- Home /
Fog shader
Hi,
I have some difficulties with my fog shader. I have a good visual result but the problem is that the gradient is based on the camera's position, it moves as the camera moves. I don't know how to fix it.
Here is the shader code.
struct v2f {
float4 pos : SV_POSITION;
float4 grabUV : TEXCOORD0;
float2 uv_depth : TEXCOORD1;
float4 interpolatedRay : TEXCOORD2;
float4 screenPos : TEXCOORD3;
};
v2f vert(appdata_base v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv_depth = v.texcoord.xy;
o.grabUV = ComputeGrabScreenPos(o.pos);
half index = v.vertex.z;
o.screenPos = ComputeScreenPos(o.pos);
o.interpolatedRay = mul(UNITY_MATRIX_MV, v.vertex);
return o;
}
sampler2D _GrabTexture;
float4 frag(v2f IN) : COLOR {
float3 uv = UNITY_PROJ_COORD(IN.grabUV);
float dpth = UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, uv));
dpth = LinearEyeDepth(dpth);
float4 wsPos = (IN.screenPos + dpth * IN.interpolatedRay); // Here is the problem but how to fix it
float fogVert = max(0.0, (wsPos.y - _Depth) * (_DepthScale * 0.1f));
fogVert *= fogVert;
fogVert = (exp (-fogVert));
return fogVert;
}
Thanks a lot !
Answer by MaT227 · Jun 14, 2013 at 07:31 PM
It seems that it's a Matrix problem
o.interpolatedRay = mul(UNITY_MATRIX_MV, v.vertex);
That would compute "interpolatedRay" in local camera coords. In other words, it should give the coords if the model was a child of the camera. It's pretty much the same as ScreenPos, except everything is in meters.
I would imagine that fog only really wants that Z from the camera (the built-in fog just fakes it from the 0 to 1 depth bit after $$anonymous$$VP.)
Ok, then I should use _Object2World to have the object matrix and using the _WorldSpaceCameraPos.z ?
I think I just got the point of the shader. It runs post, on the screen texture. So it wants to take into account the distance from the camera, and the world Y. It back-computes world Y using a ray from the known world-coords on the camera-plane.
The math looks roughly correct. to me. But shaders are shaders. There's got to be a better non-Unity source for height-based fog.
Yes you're right, this shader was a camera shader which I tried to convert into a mesh shader. If you have some good resources concerning fog I will be glad to look at them. I created another post with a simple depth shader and there a strange behaviour if you have some time to look at it.
Anyways thanks for your help !
Answer by Owen-Reynolds · Jun 14, 2013 at 02:02 PM
The fog (gradient?) is supposed to change based on the camera's position, at least as far as near/far. But do you mean that there's an up/down gradient, which moves with the camera and shouldn't? If so, I'd think adjusting o.screenPos
to use world y instead of local camera-y might do something.
Sorry, yes by gradient I mean fog... Yes the fog follows the camera up/down then, I can't have a plunge view of the scene.
Your answer
Follow this Question
Related Questions
Vertex and Fragment Shader worldNormal 1 Answer
Can a CG shader fail to work on hardware? 1 Answer
Why doesn't this vertex+fragment shader work? 0 Answers
Access to svPosition in fragment shader 1 Answer
Grabpass refraction masking 0 Answers