Cost: 1 VGPR.
We clamp NdotV between 0.0001 and 1 as we fill the PreLightData.
However, for direct lighting, this changes neither N nor V. Therefore, when we try to use this clamped NdotV value in other geometric calculations, results occasionally make no sense.
Caveat: if (NdotV < 0) and (NdotL -> 0), H may point in the opposite hemisphere from N. Clamped XdotH products appear to take care of this issue.
// A way to reduce artifact is to limit NdotV value to not be negative and calculate reflection vector for cubemap with a shifted normal (i.e what depends on the view)
// This is what provide this function
// Note: NdotV return by this function is always positive, no need for saturate
float GetShiftedNdotV(inout float3 N, float3 V)
float GetShiftedNdotV(inout float3 N, float3 V, float NdotV)
float NdotV = dot(N, V);
const float limit = 0.0001; // Epsilon value that avoid divide by 0 (several BSDF divide by NdotV)