diff --git a/features/Grass Collision/Shaders/GrassCollision/GrassCollision.hlsli b/features/Grass Collision/Shaders/GrassCollision/GrassCollision.hlsli index 8f8f8420d..da75ac1a1 100644 --- a/features/Grass Collision/Shaders/GrassCollision/GrassCollision.hlsli +++ b/features/Grass Collision/Shaders/GrassCollision/GrassCollision.hlsli @@ -16,9 +16,9 @@ struct StructuredCollision StructuredBuffer 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 diff --git a/features/Grass Lighting/Shaders/RunGrass.hlsl b/features/Grass Lighting/Shaders/RunGrass.hlsl index 7b8ce8377..9503b1ee6 100644 --- a/features/Grass Lighting/Shaders/RunGrass.hlsl +++ b/features/Grass Lighting/Shaders/RunGrass.hlsl @@ -1,3 +1,6 @@ +#include "Common/FrameBuffer.hlsl" +#include "Common/MotionBlur.hlsl" + struct VS_INPUT { float4 Position : POSITION0; @@ -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); @@ -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; @@ -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 @@ -169,30 +175,31 @@ 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)); @@ -200,19 +207,13 @@ clipPositionOut = clipPos 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) @@ -234,19 +235,8 @@ 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); @@ -254,16 +244,10 @@ clipPositionOut = clipPos 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 @@ -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; @@ -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); } @@ -476,14 +436,11 @@ 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; @@ -491,22 +448,9 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace 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); @@ -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 @@ -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 \ No newline at end of file diff --git a/features/Screen-Space Shadows/Shaders/ScreenSpaceShadows/ShadowsPS.hlsli b/features/Screen-Space Shadows/Shaders/ScreenSpaceShadows/ShadowsPS.hlsli index 21e2c8ea0..504dc8765 100644 --- a/features/Screen-Space Shadows/Shaders/ScreenSpaceShadows/ShadowsPS.hlsli +++ b/features/Screen-Space Shadows/Shaders/ScreenSpaceShadows/ShadowsPS.hlsli @@ -13,30 +13,19 @@ Texture2D 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; } diff --git a/package/Shaders/Common/FrameBuffer.hlsl b/package/Shaders/Common/FrameBuffer.hlsl index 356fd4393..cb2c482c7 100644 --- a/package/Shaders/Common/FrameBuffer.hlsl +++ b/package/Shaders/Common/FrameBuffer.hlsl @@ -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); @@ -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) @@ -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; +} diff --git a/package/Shaders/Common/MotionBlur.hlsl b/package/Shaders/Common/MotionBlur.hlsl index f3d79d799..abfc945ed 100644 --- a/package/Shaders/Common/MotionBlur.hlsl +++ b/package/Shaders/Common/MotionBlur.hlsl @@ -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); } diff --git a/package/Shaders/Common/VR.hlsl b/package/Shaders/Common/VR.hlsl new file mode 100644 index 000000000..3e19082ab --- /dev/null +++ b/package/Shaders/Common/VR.hlsl @@ -0,0 +1,22 @@ +/* +* Multiply for matrixes that will use an a_eyeIndex. +* This uses a standard mul if in flat +* +* @param a_matrix The matrix to multiple against +* @param a_vector The vector to multiply +* @param a_eyeIndex The a_eyeIndex, normally 0 for flat +* @return The result of a mul that works in VR with eyeindex +*/ +float4 NG_mul(float4x4 a_matrix, float4 a_vector, uint a_eyeIndex = 0) +{ +#if !defined(VR) + float4 result = mul(a_matrix, a_vector); +#else + float4 result; + result.x = dot(a_matrix[a_eyeIndex + 0].xyzw, a_vector.xyzw); + result.y = dot(a_matrix[a_eyeIndex + 1].xyzw, a_vector.xyzw); + result.z = dot(a_matrix[a_eyeIndex + 2].xyzw, a_vector.xyzw); + result.w = dot(a_matrix[a_eyeIndex + 3].xyzw, a_vector.xyzw); +#endif // VR + return result; +} \ No newline at end of file