Skip to content

Commit

Permalink
Refactor hlsi into common functions
Browse files Browse the repository at this point in the history
Simplify Flat and VR code with helper functions. NG_mul has been added
to replace mul when accessing FrameBuffer content. Additionally code
from ShadowPS.hlsl was moved to Framebuffer.hlsl.
  • Loading branch information
alandtse committed Jul 18, 2023
1 parent 171a0b6 commit fe548ca
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ struct StructuredCollision

StructuredBuffer<StructuredCollision> collisions : register(t0);

float3 GetDisplacedPosition(float3 position, float alpha)
float3 GetDisplacedPosition(float3 position, float alpha, uint eyeIndex = 0)
{
float3 worldPosition = mul(World, float4(position, 1)).xyz;
float3 worldPosition = NG_mul(World, float4(position, 1), eyeIndex).xyz;
float3 displacement = 0;

// Player bound culling
Expand Down
148 changes: 46 additions & 102 deletions features/Grass Lighting/Shaders/RunGrass.hlsl
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#include "Common/FrameBuffer.hlsl"
#include "Common/MotionBlur.hlsl"

struct VS_INPUT
{
float4 Position : POSITION0;
Expand Down Expand Up @@ -70,7 +73,10 @@ cbuffer PerGeometry : register(
float3 ScaleMask : packoffset(c21);
float ShadowClampValue : packoffset(c21.w);
#else
float4 cb2[32] : packoffset(c0);
row_major float4x4 WorldViewProj : packoffset(c0);
row_major float4x4 WorldView : packoffset(c8);
row_major float4x4 World : packoffset(c16);
row_major float4x4 PreviousWorld : packoffset(c24);
float4 FogNearColor : packoffset(c32);
float3 WindVector : packoffset(c33);
float WindTimer : packoffset(c33.w);
Expand All @@ -97,7 +103,7 @@ cbuffer PerFrame : register(
float4 EyePosition;
#else
float4 EyePosition[2];
#endif //!VR
#endif //! VR
row_major float3x4 DirectionalAmbient;
float SunlightScale;
float Glossiness;
Expand Down Expand Up @@ -129,7 +135,7 @@ cbuffer cb13 : register(b13)
{
float4 cb13[3];
}
# endif // VR
# endif // VR

# define M_PI 3.1415925 // PI
# define M_2PI 6.283185 // PI * 2
Expand Down Expand Up @@ -169,50 +175,45 @@ VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT vsout;

# ifdef VR
# if !defined(VR)
uint eyeIndex = 0;
uint eyeIndexX3 = 0;
uint eyeIndexX4 = 0;
# else
/*
https://docs.google.com/presentation/d/19x9XDjUvkW_9gsfsMQzt3hZbRNziVsoCEHOn4AercAc/htmlpresent
This section looks like this code
Matrix WorldToEyeClipMatrix[2] // computed from SDK
Vector4 EyeClipEdge[2]={(-1,0,0,1), (1,0,0,1)}
float EyeOffsetScale[2]={0.5,-0.5}
uint eyeIndex = instanceID & 1 // use low bit as eye index.
Vector4 clipPos = worldPos * WorldToEyeClipMatrix[eyeIndex]
cullDistanceOut.x = clipDistanceOut.x = clipPos · EyeClipEdge[eyeIndex]
clipPos.x *= 0.5; // shrink to half of the screen
clipPos.x += EyeOffsetScale[eyeIndex] * clipPos.w; // scoot left or right.
clipPositionOut = clipPos
*/
https://docs.google.com/presentation/d/19x9XDjUvkW_9gsfsMQzt3hZbRNziVsoCEHOn4AercAc/htmlpresent
This section looks like this code
Matrix WorldToEyeClipMatrix[2] // computed from SDK
Vector4 EyeClipEdge[2]={(-1,0,0,1), (1,0,0,1)}
float EyeOffsetScale[2]={0.5,-0.5}
uint eyeIndex = instanceID & 1 // use low bit as eye index.
Vector4 clipPos = worldPos * WorldToEyeClipMatrix[eyeIndex]
cullDistanceOut.x = clipDistanceOut.x = clipPos · EyeClipEdge[eyeIndex]
clipPos.x *= 0.5; // shrink to half of the screen
clipPos.x += EyeOffsetScale[eyeIndex] * clipPos.w; // scoot left or right.
clipPositionOut = clipPos
*/
float4 r0, r1, r2, r3, r4, r5, r6;
uint4 bitmask, uiDest;
float4 fDest;

r0.x = (int)input.InstanceID & 1;
r0.x = (uint)r0.x;
r0.x = cb13[0].y * r0.x;
r0.x = (uint)r0.x;
r0.z = (uint)r0.x << 2;
r0.y = (uint)r0.x << 2;
uint eyeIndex = cb13[0].y * (input.InstanceID.x & 1);
uint eyeIndexX3 = eyeIndex * 3;
uint eyeIndexX4 = eyeIndex << 2;
# endif // VR

float3x3 world3x3 = float3x3(input.InstanceData2.xyz, input.InstanceData3.xyz, float3(input.InstanceData4.x, input.InstanceData2.w, input.InstanceData3.w));

float4 msPosition = GetMSPosition(input, WindTimer, world3x3);

# ifdef GRASS_COLLISION
float3 displacement = GetDisplacedPosition(msPosition.xyz, input.Color.w);
float3 displacement = GetDisplacedPosition(msPosition.xyz, input.Color.w, eyeIndexX4);
msPosition.xyz += displacement;
# endif

float4 projSpacePosition = NG_mul(WorldViewProj, msPosition, eyeIndexX4);
# if !defined(VR)
float4 projSpacePosition = mul(WorldViewProj, msPosition);
vsout.HPosition = projSpacePosition;
# else
float4 projSpacePosition;
projSpacePosition.x = dot(cb2[r0.z + 0].xyzw, msPosition.xyzw);
projSpacePosition.y = dot(cb2[r0.z + 1].xyzw, msPosition.xyzw);
projSpacePosition.z = dot(cb2[r0.z + 2].xyzw, msPosition.xyzw);
projSpacePosition.w = dot(cb2[r0.z + 3].xyzw, msPosition.xyzw);
# endif // !VR

# if defined(RENDER_DEPTH)
Expand All @@ -234,36 +235,19 @@ clipPositionOut = clipPos
vsout.TexCoord.xy = input.TexCoord.xy;
vsout.TexCoord.z = FogNearColor.w;

# if !defined(VR)
vsout.ViewSpacePosition = mul(WorldView, msPosition).xyz;
vsout.WorldPosition = mul(World, msPosition);
# else
vsout.ViewSpacePosition.x = dot(cb2[r0.z + 8].xyzw, msPosition.xyzw);
vsout.ViewSpacePosition.y = dot(cb2[r0.z + 9].xyzw, msPosition.xyzw);
vsout.ViewSpacePosition.z = dot(cb2[r0.z + 10].xyzw, msPosition.xyzw);

vsout.WorldPosition.x = dot(cb2[r0.z + 16].xyzw, msPosition.xyzw);
vsout.WorldPosition.y = dot(cb2[r0.z + 17].xyzw, msPosition.xyzw);
vsout.WorldPosition.z = dot(cb2[r0.z + 18].xyzw, msPosition.xyzw);
vsout.WorldPosition.w = dot(cb2[r0.z + 19].xyzw, msPosition.xyzw);
# endif // !VR
vsout.ViewSpacePosition = NG_mul(WorldView, msPosition, eyeIndexX4).xyz;
vsout.WorldPosition = NG_mul(World, msPosition, eyeIndexX4);

float4 previousMsPosition = GetMSPosition(input, PreviousWindTimer, world3x3);

# ifdef GRASS_COLLISION
previousMsPosition.xyz += displacement;
# endif // GRASS_COLLISION

vsout.PreviousWorldPosition = NG_mul(PreviousWorld, previousMsPosition, eyeIndexX4);
# if !defined(VR)
vsout.PreviousWorldPosition = mul(PreviousWorld, previousMsPosition);

vsout.ViewDirectionVec.xyz = EyePosition.xyz - vsout.WorldPosition.xyz;
# else
vsout.PreviousWorldPosition.x = dot(cb2[r0.z + 24].xyzw, previousMsPosition.xyzw);
vsout.PreviousWorldPosition.y = dot(cb2[r0.z + 25].xyzw, previousMsPosition.xyzw);
vsout.PreviousWorldPosition.z = dot(cb2[r0.z + 26].xyzw, previousMsPosition.xyzw);
vsout.PreviousWorldPosition.w = dot(cb2[r0.z + 27].xyzw, previousMsPosition.xyzw);

/*
https://docs.google.com/presentation/d/19x9XDjUvkW_9gsfsMQzt3hZbRNziVsoCEHOn4AercAc/htmlpresent
This section looks like this code
Expand All @@ -278,13 +262,13 @@ clipPos.x += EyeOffsetScale[eyeIndex] * clipPos.w; // scoot left or right.
clipPositionOut = clipPos
*/
if (0 < cb13[0].y) {
r0.yz = dot(projSpacePosition, cb13[r0.x + 1].xyzw);
r0.yz = dot(projSpacePosition, cb13[eyeIndex + 1].xyzw);
} else {
r0.yz = float2(1, 1);
}

r0.w = 2 + -cb13[0].y;
r0.x = dot(cb13[0].zw, M_IdentityMatrix[r0.x + 0].xy);
r0.x = dot(cb13[0].zw, M_IdentityMatrix[eyeIndex + 0].xy);
r0.xw = r0.xw * projSpacePosition.wx;
r0.x = cb13[0].y * r0.x;

Expand Down Expand Up @@ -338,38 +322,14 @@ cbuffer cb0 : register(b0)

# endif // VR

cbuffer PS_cb12 : register(b12)
{
# if !defined(VR)
row_major float4x4 ViewMatrix : packoffset(c0);
row_major float4x4 ProjMatrix : packoffset(c4);
row_major float4x4 ViewProjMatrix : packoffset(c8);
row_major float4x4 ViewProjMatrixUnjittered : packoffset(c12);
row_major float4x4 PreviousViewProjMatrixUnjittered : packoffset(c16);
row_major float4x4 InvProjMatrixUnjittered : packoffset(c20);
row_major float4x4 ProjMatrixUnjittered : packoffset(c24);
row_major float4x4 InvViewMatrix : packoffset(c28);
row_major float4x4 InvViewProjMatrix : packoffset(c32);
row_major float4x4 InvProjMatrix : packoffset(c36);
float4 CurrentPosAdjust : packoffset(c40);
float4 PreviousPosAdjust : packoffset(c41);
// notes: FirstPersonY seems 1.0 regardless of third/first person, could be LE legacy stuff
float4 GammaInvX_FirstPersonY_AlphaPassZ_CreationKitW : packoffset(c42);
float4 DynamicRes_WidthX_HeightY_PreviousWidthZ_PreviousHeightW : packoffset(c43);
float4 DynamicRes_InvWidthX_InvHeightY_WidthClampZ_HeightClampW : packoffset(c44);
# else
//VR is float4 PerFrame[87]; VR original used for eye position in PerFrame[86].x
float4 cb12[87];
# endif // !VR
}

cbuffer AlphaTestRefCB : register(
cbuffer AlphaTestRefCB :
register(
# if !defined(VR)
b11
b11
# else
b13
b13
# endif // !VR
)
)
{
float AlphaTestRefRS : packoffset(c0);
}
Expand Down Expand Up @@ -476,37 +436,21 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
// psout.Albedo.w = 1;

# if !defined(VR)
float4 screenPosition = mul(ViewProjMatrixUnjittered, input.WorldPosition);
screenPosition.xy = screenPosition.xy / screenPosition.ww;
float4 previousScreenPosition = mul(PreviousViewProjMatrixUnjittered, input.PreviousWorldPosition);
previousScreenPosition.xy = previousScreenPosition.xy / previousScreenPosition.ww;
uint eyeIndex = 0;
uint eyeOffset = 0;
# else
float stereoUV = input.HPosition.x * cb0[2].xy + cb0[2].zw;
stereoUV = stereoUV * cb12[86].x;
stereoUV = stereoUV * DynamicResolutionParams2.x;

uint eyeIndex = (stereoUV >= 0.5) ? 1 : 0;
uint eyeOffset = eyeIndex;
uint bitmask;
bitmask = ((~(-1 << 1)) << 2) & 0xffffffff;
eyeOffset = (((uint)eyeOffset << 2) & bitmask) | ((uint)0 & ~bitmask);

float3 screenPosition;
screenPosition.x = dot(cb12[eyeOffset + 24].xyzw, input.WorldPosition);
screenPosition.y = dot(cb12[eyeOffset + 25].xyzw, input.WorldPosition);
screenPosition.z = dot(cb12[eyeOffset + 27].xyzw, input.WorldPosition);
screenPosition.xy = screenPosition.xy / screenPosition.zz;

float3 previousScreenPosition;
previousScreenPosition.x = dot(cb12[eyeOffset + 32].xyzw, input.PreviousWorldPosition);
previousScreenPosition.y = dot(cb12[eyeOffset + 33].xyzw, input.PreviousWorldPosition);
previousScreenPosition.z = dot(cb12[eyeOffset + 35].xyzw, input.PreviousWorldPosition);
previousScreenPosition.xy = previousScreenPosition.xy / previousScreenPosition.zz;
# endif // !VR

float2 screenMotionVector = float2(-0.5, 0.5) * (screenPosition.xy - previousScreenPosition.xy);

psout.MotionVectors = screenMotionVector;
psout.MotionVectors = GetSSMotionVector(input.WorldPosition, input.PreviousWorldPosition, eyeOffset);

float3 ddx = ddx_coarse(input.ViewSpacePosition);
float3 ddy = ddy_coarse(input.ViewSpacePosition);
Expand Down Expand Up @@ -547,7 +491,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
dirLightColor *= shadowColor.x;

# if defined(SCREEN_SPACE_SHADOWS)
float dirLightSShadow = PrepassScreenSpaceShadows(input.WorldPosition);
float dirLightSShadow = PrepassScreenSpaceShadows(input.WorldPosition, eyeOffset);
dirLightColor *= dirLightSShadow;
# endif // !SCREEN_SPACE_SHADOWS

Expand Down Expand Up @@ -629,7 +573,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace
psout.Albedo.xyz = color;
psout.Albedo.w = 1;

# endif // RENDER_DEPTH
# endif // RENDER_DEPTH
return psout;
}
#endif // PSHADER
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,19 @@ Texture2D<float> TexOcclusionSampler : register(t21);
SamplerState LinearSampler : register(s14);
#endif

float3 WorldToView(float3 x, bool is_position = true)
float2 SSGetDynamicResolutionAdjustedScreenPosition(float2 uv)
{
return mul(ViewMatrix, float4(x, (float)is_position)).xyz;
return uv * DynamicResolutionParams1.xy;
}

float2 ViewToUV(float3 x, bool is_position = true)
{
float4 uv = mul(ProjMatrix, float4(x, (float)is_position));
return (uv.xy / uv.w) * float2(0.5f, -0.5f) + 0.5f;
}

float2 GetDynamicResolutionAdjustedScreenPosition(float2 uv)
{
return uv * DynamicRes_WidthX_HeightY_PreviousWidthZ_PreviousHeightW.xy;
}

float PrepassScreenSpaceShadows(float3 positionWS)
float PrepassScreenSpaceShadows(float3 positionWS, uint eyeIndex = 0)
{
#if defined(EYE)
return 1;
#else
if (EnableSSS) {
float2 texCoord = ViewToUV(WorldToView(positionWS));
float2 coords = GetDynamicResolutionAdjustedScreenPosition(texCoord) / 2;
float2 texCoord = ViewToUV(WorldToView(positionWS, true, eyeIndex), true, eyeIndex);
float2 coords = SSGetDynamicResolutionAdjustedScreenPosition(texCoord) / 2;
float shadow = TexOcclusionSampler.SampleLevel(LinearSampler, coords, 0);
return shadow;
}
Expand Down
32 changes: 32 additions & 0 deletions package/Shaders/Common/FrameBuffer.hlsl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "Common/VR.hlsl"
cbuffer PerFrame : register(b12)
{
#if !defined(VR)
row_major float4x4 CameraView : packoffset(c0);
row_major float4x4 CameraProj : packoffset(c4);
row_major float4x4 CameraViewProj : packoffset(c8);
Expand All @@ -15,6 +17,23 @@ cbuffer PerFrame : register(b12)
float4 FrameParams : packoffset(c42); // inverse fGamma in x, some flags in yzw
float4 DynamicResolutionParams1 : packoffset(c43); // fDynamicResolutionWidthRatio in x, fDynamicResolutionHeightRatio in y, fDynamicResolutionPreviousWidthRatio in z, fDynamicResolutionPreviousHeightRatio in w
float4 DynamicResolutionParams2 : packoffset(c44); // inverse fDynamicResolutionWidthRatio in x, inverse fDynamicResolutionHeightRatio in y, fDynamicResolutionWidthRatio - fDRClampOffset in z, fDynamicResolutionPreviousWidthRatio - fDRClampOffset in w
#else
row_major float4x4 CameraView : packoffset(c0);
row_major float4x4 CameraProj : packoffset(c8);
row_major float4x4 CameraViewProj : packoffset(c16);
row_major float4x4 CameraViewProjUnjittered : packoffset(c24);
row_major float4x4 CameraPreviousViewProjUnjittered : packoffset(c32);
row_major float4x4 CameraProjUnjittered : packoffset(c40);
row_major float4x4 CameraProjUnjitteredInverse : packoffset(c44);
row_major float4x4 CameraViewInverse : packoffset(c56);
row_major float4x4 CameraViewProjInverse : packoffset(c64);
row_major float4x4 CameraProjInverse : packoffset(c72);
float4 CameraPosAdjust : packoffset(c80);
float4 CameraPreviousPosAdjust : packoffset(c82); // fDRClampOffset in w
float4 FrameParams : packoffset(c84); // inverse fGamma in x, some flags in yzw
float4 DynamicResolutionParams1 : packoffset(c85); // fDynamicResolutionWidthRatio in x, fDynamicResolutionHeightRatio in y, fDynamicResolutionPreviousWidthRatio in z, fDynamicResolutionPreviousHeightRatio in w
float4 DynamicResolutionParams2 : packoffset(c86); // inverse fDynamicResolutionWidthRatio in x, inverse fDynamicResolutionHeightRatio in y, fDynamicResolutionWidthRatio - fDRClampOffset in z, fDynamicResolutionPreviousWidthRatio - fDRClampOffset in w
#endif // !VR
}

float2 GetDynamicResolutionAdjustedScreenPosition(float2 screenPosition)
Expand All @@ -34,3 +53,16 @@ float3 ToSRGBColor(float3 linearColor)
{
return pow(linearColor, FrameParams.x);
}

float3 WorldToView(float3 x, bool is_position = true, uint a_eyeIndex = 0)
{
float4 newPosition = float4(x, (float)is_position);
return NG_mul(CameraView, newPosition, a_eyeIndex).xyz;
}

float2 ViewToUV(float3 x, bool is_position = true, uint a_eyeIndex = 0)
{
float4 newPosition = float4(x, (float)is_position);
float4 uv = NG_mul(CameraProj, newPosition, a_eyeIndex);
return (uv.xy / uv.w) * float2(0.5f, -0.5f) + 0.5f;
}
11 changes: 8 additions & 3 deletions package/Shaders/Common/MotionBlur.hlsl
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
float2 GetSSMotionVector(float4 wsPosition, float4 previousWSPosition)
float2 GetSSMotionVector(float4 wsPosition, float4 previousWSPosition, uint eyeOffset = 0)
{
float4 screenPosition = mul(CameraViewProjUnjittered, wsPosition);
float4 screenPosition = NG_mul(CameraViewProjUnjittered, wsPosition, eyeOffset);
float4 previousScreenPosition = NG_mul(CameraPreviousViewProjUnjittered, previousWSPosition, eyeOffset);
#if !defined(VR)
screenPosition.xy = screenPosition.xy / screenPosition.ww;
float4 previousScreenPosition = mul(CameraPreviousViewProjUnjittered, previousWSPosition);
previousScreenPosition.xy = previousScreenPosition.xy / previousScreenPosition.ww;
#else
screenPosition.xy = screenPosition.xy / screenPosition.zz;
previousScreenPosition.xy = previousScreenPosition.xy / previousScreenPosition.zz;
#endif // !VR
return float2(-0.5, 0.5) * (screenPosition.xy - previousScreenPosition.xy);
}
Loading

0 comments on commit fe548ca

Please sign in to comment.