fixed4 frag(v2f i) : SV_Target
{
float3 normal = normalize(cross(ddx(i.worldPos), ddy(i.worldPos)));
// dot product between normal and light direction for
// standard diffuse (Lambert) lighting
half nl = max(0, dot(normal, _WorldSpaceLightPos0.xyz));
// factor in the light color
fixed4 diff = nl * _LightColor0;
// in addition to the diffuse lighting from the main light,
// add illumination from ambient or light probes
// ShadeSH9 function from UnityCG.cginc evaluates it,
// using world space normal
diff.xyz += ShadeSH9(half4(normal,1));
return i.color * diff;
}
When I change the MSAA setting on my camera, light direction ‘flips’, making the light come from the exact opposite direction.
MSAA on:
MSAA off:
Why does this happen and what alternative methods can I use?
I don’t need shadows, prefer performance, prefer MSAA (FXAA isn’t very good) and I need only a depth buffer.
First, if you don’t have the “LightMode”=“ForwardBase” tag on your shader pass, the light direction can be a little funny, but I don’t know if that’s the issue.
Second, there’s a weird thing with MSAA in Direct3D. Normally, OpenGL and Direct3D texture sampling and rendering orientation are flipped from each other. Unity handles this by flipping the projection matrix, and a few variables here and there to let shaders know the projection is flipped, or that the incoming render texture was rendered flipped. MSAA is weird because it causes the GPU to render in the same orientation as OpenGL. I wonder if that’s what’s flipping the normal since now the ddy() is going to be giving you the inverse vector, flipping the cross product.
I’d try using this line and see if it works:
float3 normal = normalize(cross(ddy(i.worldPos), ddx(i.worldPos))) * _ProjectionParams.x;
I’ve honestly never seen this problem crop up from MSAA flipping the screen since it should be using an inverted projection matrix to keep it consistent, but maybe there’s something else in your rendering setup causing it to behave differently.
Your proposed solution works!
You truly are a hero.
I have no clue why, other than a right-handed worldToCameraMatrix I do nothing seemingly weird. That said, Unity doesn’t like right-handed worldToCameraMatrices (camera gizmo goes weird)