I have a radial fog shader that works like this:
- a variable which determines max fog distance (beyond this distance, everything is 100% fogged) (max_fog_dist), hard-coded to 10.0 for now
- a variable (0.0 to 1.0) which represents when the fog should begin to fade in, starting from the eye/camera (fog_start), hard-coded to 0.5 for now
I’m still a little hazy on all things matrices and I generally follow tutorials for things relating to them, and I’d done so here. The fog shader WORKS, but it uses SQRT in the frag shader. Not a huge deal, but I gather it’s something to be avoided if possible. Mostly, this is for learning, and is not of any urgency.
Vertex shader:
in vec3 vPosition;
in vec4 vColor;
in vec2 vUV;
out vec4 fColor;
out vec2 fUV;
out vec4 fViewSpace;
out float fAlpha;
uniform mat4 uMatrixWorld;
uniform mat4 uMatrixView;
uniform mat4 uMatrixProjection;
void main()
{
fColor = vColor;
// save the alpha, we're about to overwrite this
fAlpha = fColor.a;
// store vertex z-pos in the alpha
fColor.a = vPosition.a;
fUV = vUV;
fViewSpace = uMatrixView * uMatrixWorld * vec4(vPosition, 1.0);
gl_Position = uMatrixProjection * fViewSpace;
}
Frag shader:
in vec4 fColor;
in vec2 fUV;
in vec4 fViewSpace;
in float fAlpha;
out vec4 final;
uniform sampler2D uTexture0;
uniform vec3 uFogColor;
void main()
{
// unrelated fragment shader stuff relating to textures/uvs
// fog stuff
float max_fog_dist = 10.0;
float fog_start = 0.5;
// fragment distance
float dist = (fViewSpace.x * fViewSpace.x) + (fViewSpace.y * fViewSpace.y) + (fViewSpace.z * fViewSpace.z);
float fog_amount = (max_fog_dist - sqrt(dist)) / (max_fog_dist * fog_start);
fog_amount = clamp(fog_amount, 0.0, 1.0);
// then, use fog_amount as a multiplier for how much to blend uFogColor
// and return "final" frag color
}
Really I think this is a logic problem and not a GLSL question.
The problem is that my frag distance I’m working with is squared to begin with (the "dist = " line), and I don’t think I can retrieve that distance without having it be squared in the first place. The guide recommends to “work with all squared numbers” and you can avoid using SQRT that way, but it doesn’t stay correct if you do that. For example, if I square the other number:
// "dist" is already a squared value
float fog_amount = ((max_fog_dist * max_fog_dist) - dist) / (max_fog_dist * max_fog_dist) * fog_start);
This doesn’t stay accurate (linear) because of the subtraction on the left side of the “/”. Using my values of 10 for max_fog_dist and 0.5 for fog_start, the non-squared way, if our fragment distance is at 7.5, which should be half-way fogged (between 5 and 10), results in:
(10 - 7.5) / (10 * 0.5)
2.5 / 5.0
50%
Great, that’s what I want.
Squared version, however, if frag is again at 7.5, (without using sqrt) goes like this:
// “frag” is already squared, so distance of “7.5” in reality is 7.5*7.5=56.25
(100 - 56.25) / (100 * 0.5)
43.75 / 50
87.5%
Gradient is wrong this way, (well, duh, because the distance value is squared). Is there any way to structure or math this problem in a way such that I can still achieve the linear fade without squarerooting in the frag shader, or is it simply unavoidable in my case? Again not a high-priority question but just trying to learn a bit.