Skip to content

Commit

Permalink
feat: add VR water shader (#193)
Browse files Browse the repository at this point in the history
  • Loading branch information
alandtse authored Apr 7, 2024
1 parent f773793 commit 3c2d04c
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 103 deletions.
31 changes: 2 additions & 29 deletions features/Water Caustics/Shaders/WaterCaustics/WaterCaustics.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ struct PerPassWaterCaustics
float pad[3];
};

StructuredBuffer<PerPassWaterCaustics> perPassWaterCaustics : register(t71);

#if defined(WATER)

Texture2D<float4> WaterCaustics : register(t70);
StructuredBuffer<PerPassWaterCaustics> perPassWaterCaustics : register(t71);

float2 PanCausticsUV(float2 uv, float speed, float tiling)
{
Expand Down Expand Up @@ -43,29 +40,7 @@ float3 ComputeWaterCaustics(float2 uv)
return caustics;
}

#else

Texture2D<float4> WaterCaustics : register(t70);

float2 PanCausticsUV(float2 uv, float speed, float tiling)
{
return (float2(1, 0) * lightingData[0].Timer * speed) + (uv * tiling);
}

float3 SampleCaustics(float2 uv, float split)
{
float2 uv1 = uv + float2(split, split);
float2 uv2 = uv + float2(split, -split);
float2 uv3 = uv + float2(-split, -split);

float r = WaterCaustics.Sample(SampColorSampler, uv1).r;
float g = WaterCaustics.Sample(SampColorSampler, uv2).r;
float b = WaterCaustics.Sample(SampColorSampler, uv3).r;

return float3(r, g, b);
}

float3 ComputeWaterCaustics(float3 waterHeight, float3 worldPosition, float3 worldSpaceNormal)
float3 ComputeWaterCaustics(float waterHeight, float3 worldPosition, float3 worldSpaceNormal)
{
float causticsDistToWater = waterHeight - worldPosition.z;
float shoreFactorCaustics = saturate(causticsDistToWater / 64.0);
Expand Down Expand Up @@ -99,5 +74,3 @@ float3 ComputeWaterCaustics(float3 waterHeight, float3 worldPosition, float3 wor
caustics = lerp(causticsLow, caustics, upAmount);
return lerp(1.0, caustics, shoreFactorCaustics * upAmount);
}

#endif
39 changes: 31 additions & 8 deletions package/Shaders/Common/VR.hlsl
Original file line number Diff line number Diff line change
@@ -1,35 +1,58 @@
/**
Converts to the eye specific uv.
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 y value (.5, 1] are the right eye.
This returns the adjusted value
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
@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;
}

/**
Converts from eye specific uv to general uv.
Converts from eye specific uv to general uv [0,1].
In VR, texture buffers include the left and right eye in the same buffer.
This means the x value [0, .5] represents the left eye, and the y value (.5, 1] are the right eye.
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 - 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;
}

/**
Converts to the eye specific screenposition [0,Resolution].
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, resx/2] represents the left eye, and the x value (resx/2, x] are the right eye.
This returns the adjusted value
@param screenPosition - Screenposition coords ([0,resx], [0,resy]) to be encoded for VR
@param a_eyeIndex The eyeIndex; 0 is left, 1 is right
@param a_resolution The resolution of the screen
@returns screenPosition with x coords adjusted for the VR texture buffer
*/
float2 ConvertToStereoSP(float2 screenPosition, uint a_eyeIndex, float2 a_resolution)
{
screenPosition.x /= a_resolution.x;
return ConvertToStereoUV(screenPosition, a_eyeIndex) * a_resolution;
}
Loading

0 comments on commit 3c2d04c

Please sign in to comment.