SSR Water For Orthographic Camera

Posted by Bad Fat Dog on February 25, 2020

SSR Water For Orthographic Camera

Fantastic SSR Water LWRP/URP SSR Water

One review:

A good asset if you use perspective camera. Unfortunately it doesn’t work correctly with orthographic one which I use in my project.

Oh,I forgot orthographic camera, I should support it.

How To

For orthographic camera, the calculation of WorldViewDirection and Depth is quite different.

WorldViewDirection

For perspective camera:

1
lightingData.worldViewDir = normalize(_WorldSpaceCameraPos.xyz - lightingData.worldPos);

For orthographic camera:

1
lightingData.worldViewDir = normalize(UNITY_MATRIX_V[2].xyz);

For both:

1
lightingData.worldViewDir = unity_OrthoParams.w * UNITY_MATRIX_V[2].xyz + (1- unity_OrthoParams.w) * (_WorldSpaceCameraPos.xyz - lightingData.worldPos);

Depth

For perspective camera, I get scene depth like this:

1
float sceneDepth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, screenMatchUVZ.xy), _ZBufferParams);

Above code does not work for orthographic camera, I should write like this:

1
2
3
4
5
6
7
8
9
10
inline float GetOrthoDepthFromZBuffer (float rawDepth) 
{
    #if defined(UNITY_REVERSED_Z)
        #if UNITY_REVERSED_Z == 1
            rawDepth = 1.0f - rawDepth;
        #endif
    #endif

    return lerp(_ProjectionParams.y, _ProjectionParams.z, rawDepth);
}
1
2
3
4
float rawDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, screenMatchUVZ.xy);
float perspectiveSceneDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
float orthoSceneDepth = GetOrthoDepthFromZBuffer(rawDepth);
return lerp(perspectiveSceneDepth, orthoSceneDepth, unity_OrthoParams.w);

When computing depth from the result of TransformWorldToHClip, the situation is similar.

OK, my local shader works well for orthographic camera now:

I’ll commit the new version soon.

Reference

I’ve learned a lot from Lux URP/LWRP Essentials, it’s really a great asset.