Skip to content

Commit

Permalink
fix: fix VR water
Browse files Browse the repository at this point in the history
  • Loading branch information
alandtse committed Apr 1, 2024
1 parent 24b1078 commit c600bd0
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 15 deletions.
37 changes: 32 additions & 5 deletions package/Shaders/Common/VR.hlsl
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
/**
Converts to the eye specific uv [0,1].
In VR, texture buffers include the left and right eye in the same buffer. Flat only has a single camera for the entire width.
This means the x value [0, .5] represents the left eye, and the x value (.5, 1] are the right eye.
This returns the adjusted value
In VR, texture buffers include the left and right eye in the same buffer. Flat
only has a single camera for the entire width. This means the x value [0, .5]
represents the left eye, and the x value (.5, 1] are the right eye. This returns
the adjusted value
@param uv - uv coords [0,1] to be encoded for VR
@param a_eyeIndex The eyeIndex; 0 is left, 1 is right
@param a_invertY Whether to invert the Y direction
@returns uv with x coords adjusted for the VR texture buffer
*/
float2 ConvertToStereoUV(float2 uv, uint a_eyeIndex)
float2 ConvertToStereoUV(float2 uv, uint a_eyeIndex, uint a_invertY = 0)
{
#ifdef VR
// convert [0,1] to eye specific [0,.5] and [.5, 1] dependent on a_eyeIndex
uv.x = (uv.x + (float)a_eyeIndex) / 2;
if (a_invertY)
uv.y = 1 - uv.y;
#endif
return uv;
}
Expand All @@ -23,13 +27,16 @@ This means the x value [0, .5] represents the left eye, and the x value (.5, 1]
This returns the adjusted value
@param uv - eye specific uv coords [0,1]; if uv.x < 0.5, it's a left eye; otherwise right
@param a_eyeIndex The eyeIndex; 0 is left, 1 is right
@param a_invertY Whether to invert the Y direction
@returns uv with x coords adjusted to full range for either left or right eye
*/
float2 ConvertFromStereoUV(float2 uv, uint a_eyeIndex)
float2 ConvertFromStereoUV(float2 uv, uint a_eyeIndex, uint a_invertY = 0)
{
#ifdef VR
// convert [0,.5] to [0, 1] and [.5, 1] to [0,1]
uv.x = 2 * uv.x - (float)a_eyeIndex;
if (a_invertY)
uv.y = 1 - uv.y;
#endif
return uv;
}
Expand All @@ -49,3 +56,23 @@ float2 ConvertToStereoSP(float2 screenPosition, uint a_eyeIndex, float2 a_resolu
screenPosition.x /= a_resolution.x;
return ConvertToStereoUV(screenPosition, a_eyeIndex) * a_resolution;
}

/**
Calculates the depthMultiplier as used in water.hlsl
VR appears to require use of CameraProjInverse and does not use projData
@param a_uv uv coords to convert
@param a_depth The calculated depth
@param a_eyeIndex The eyeIndex; 0 is left, 1 is right
@returns depthMultiplier
*/
float calculateDepthMultfromUV(float2 a_uv, float a_depth, uint a_eyeIndex = 0)
{
float4 temp;
temp.xy = (a_uv * 2 - 1);
temp.z = a_depth;
temp.w = 1;
temp = mul(CameraProjInverse[a_eyeIndex], temp.xyzw);
temp.xyz /= temp.w;
return length(temp);
}
23 changes: 13 additions & 10 deletions package/Shaders/Water.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,11 @@ float3 GetWaterSpecularColor(PS_INPUT input, float3 normal, float3 viewDirection
float GetScreenDepthWater(float2 screenPosition)
{
float depth = DepthTex.Load(float3(screenPosition, 0)).x;
# if !defined(VR)
return (CameraData.w / (-depth * CameraData.z + CameraData.x));
# else // VR appears to use hard coded values
return depth * 1.01 + -0.01;
# endif // VR
}
# endif

Expand Down Expand Up @@ -635,10 +639,11 @@ float3 GetWaterDiffuseColor(PS_INPUT input, float3 normal, float3 viewDirection,
float depth = GetScreenDepthWater(screenPosition);
float2 refractionScreenPosition = DynamicResolutionParams1.xy * (refractionUvRaw / VPOSOffset.xy);
float refractionDepth = GetScreenDepthWater(refractionScreenPosition);
float refractionDepthMul = length(
float3((refractionDepth * ((VPOSOffset.zw + refractionUvRaw) * 2 - 1)) /
ProjData.xy,
refractionDepth));
# if !defined(VR)
float refractionDepthMul = length(float3((((VPOSOffset.zw + refractionUvRaw) * 2 - 1)) * refractionDepth / ProjData.xy, refractionDepth));
# else
float refractionDepthMul = calculateDepthMultfromUV(ConvertFromStereoUV(VPOSOffset.zw + refractionUvRaw, a_eyeIndex, 1), refractionDepth, a_eyeIndex);
# endif //VR

float3 refractionDepthAdjustedViewDirection = -viewDirection * refractionDepthMul;
float refractionViewSurfaceAngle = dot(refractionDepthAdjustedViewDirection, ReflectPlane[a_eyeIndex].xyz);
Expand Down Expand Up @@ -737,8 +742,11 @@ PS_OUTPUT main(PS_INPUT input)
depth = GetScreenDepthWater(screenPosition);
float2 depthOffset =
DynamicResolutionParams2.xy * input.HPosition.xy * VPOSOffset.xy + VPOSOffset.zw;
# if !defined(VR)
float depthMul = length(float3((depthOffset * 2 - 1) * depth / ProjData.xy, depth));

# else
float depthMul = calculateDepthMultfromUV(ConvertFromStereoUV(depthOffset, eyeIndex, 1), depth, eyeIndex);
# endif //VR
float3 depthAdjustedViewDirection = -viewDirection * depthMul;
float viewSurfaceAngle = dot(depthAdjustedViewDirection, ReflectPlane[eyeIndex].xyz);

Expand All @@ -756,12 +764,7 @@ PS_OUTPUT main(PS_INPUT input)
# elif defined(SPECULAR) && (NUM_SPECULAR_LIGHTS != 0)
float4 depthControl = float4(0, 0, 1, 0);
# else
// # if !defined(VR)
float4 depthControl = DepthControl * (distanceMul - 1) + 1;
// # else
// float4 VRDepthControl = DepthControl.zwxw; // VR appears to move values around
// float4 depthControl = VRDepthControl * (distanceMul - 1) + 1;
// # endif // VR
# endif

# if defined(WATER_CAUSTICS)
Expand Down

0 comments on commit c600bd0

Please sign in to comment.