- Home /
Incorrect lighting projecting normal map downwards in world space
Hey everyone, I'm new to writing shaders but I've been trying to create a raindrops shader for the roads and surfaces in my game. It uses a couple of textures to animate the display of a bump texture that is meant to affect the normals of the road. Because it's rain, I want to project the normal map downwards in world space so that it is always even and disregards the scale and orientation of the UVs on the object it hits.
The core of my issue: I simply want to project a normal map downwards in world space and still have it reflect light correctly. I've looked at this question but I think my situation is slightly different.
This is the current response of the pure normal map: http://puu.sh/oog7h/9228a864cf.gif The map currently disregards orientation of the object's UVs, which is good, but as you can see the light response is incorrect.
The surf function code is here (and the entire shader code here (with some recent changes)):
void surf (Input IN, inout SurfaceOutputStandard o) {
half2 uv = IN.uv_MainTex;
uv.x = clamp(uv.x,0,1);fixed4 c = tex2D (_MainTex, uv);
fixed4 m1 = tex2D (_MetallicDry, IN.uv_MainTex);
fixed4 m2 = tex2D (_MetallicWet, IN.uv_MainTex);
fixed4 n2 = tex2D (_Ripple, IN.worldPos.xz);
//using worldPos.xz to project the ripple normal map downwards
fixed4 no = tex2D (_RippleOffset, IN.worldPos.xz);
o.Albedo = c.rgb;
o.Metallic = 0;
o.Smoothness = lerp(_SmoothnessDry,_SmoothnessWet,_Wetness);
o.Normal = UnpackNormal (n);
//water stuff
float fade = 10 - distance(_WorldSpaceCameraPos, IN.worldPos)/10; //distance culling of the effect
if (_Rain > 0 && fade > 0) {
float3 ripple = UnpackNormal(n2); //normal map for the raindrops, this is animated below
//make animation value
//the +0.01 just clips away the background of the channel
float repeat = frac(-_Time.y+no.rgb)+0.01;
//this applies an offset to the second layer of the ripple
float repeat2 = frac(-_Time.y+no.rgb+0.2)+0.01;
//first step is the lower bound, second step is the upper bound. *_Rain effects the intensity.
//There are two equations ()+() because there are two ripples
fixed l = ((step(repeat,n2.b)*(1-step(repeat*1.3,n2.b))) + (step(repeat2,n2.b)*(1-step(repeat2*2,n2.b)))) * _Rain * n2.b * fade;
//so now L will be 1 where there is part of a water droplet and 0 otherwise
//"refract" on the droplets by pushing the uvs of the surface around where they are covered
c = tex2D (_MainTex, lerp(IN.uv_MainTex,IN.uv_MainTex + (IN.viewDir.xy * -.03),l)) * _Color;
o.Normal = lerp(o.Normal,worldToTangentMatrix(IN.vnormal, IN.vtangent, ripple),1);
//display road bump map where L = 0 and raindrop bumpmap where L is 1. Constant 1 here instead of L for testing purposes
}
}
I'm certain the maths behind the worldToTangent transform are correct, because I used them in another shader. However i'm not sure if that transform is appropriate here (I'm new to shaders). It looks like I'm almost there but i'm just not sure how to correct the response of the map. Thanks for any help !
Bump. I haven't been able to make any headway on this. Any help is appreciated!
Hi @dreadofmondays Have you found a solution for this issue?
Your answer
Follow this Question
Related Questions
Why is my UV'd texture displaying wrapped with the wrong scale? 0 Answers
Overlaying a Darkening Texture over Certain UVs with a Shader 0 Answers
Layering multiple Normal maps into one without blending in a Surface shader script 0 Answers
UnityObjectToClipPos is inverted? 0 Answers
How to add metallic and smoothness to a frag shader? 1 Answer