From a88b2d0c1894cbfdc26247dc8e482fd4849dad98 Mon Sep 17 00:00:00 2001 From: Christoph Wilk Date: Wed, 25 Oct 2023 22:48:33 +0900 Subject: [PATCH 1/2] Triplanar mapping for projected diffuse textures (introduced by Better Dynamic Snow / Simplicity Of Snow / Shaders Of Solstheim). Fixes texture striping when projection is parallel to object geometry, most notably for snow on Windhelm architecture. Uses screen space derivatives because geometry normals don't help. Uses UV based triplanar mapping for performance. Works for VR and flat screen, although it needs to hook into different code paths for each platform. The function "ComputeTriplanarUV" does the math. --- package/Shaders/Lighting.hlsl | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/package/Shaders/Lighting.hlsl b/package/Shaders/Lighting.hlsl index 081dbfb26..d9e5c4ac0 100644 --- a/package/Shaders/Lighting.hlsl +++ b/package/Shaders/Lighting.hlsl @@ -947,7 +947,16 @@ float GetSnowParameterY(float texProjTmp, float alpha) # endif } -# if defined(LOD) +float2 ComputeTriplanarUV(float3 InputPosition) +{ + float3 posDDX = ddx(InputPosition.xyz); + float3 posDDY = ddy(InputPosition.xyz); + return (((0.1 * (abs(posDDX.z) + abs(posDDY.z)) < abs(posDDX.x) + abs(posDDY.x)) && + (0.1 * (abs(posDDX.z) + abs(posDDY.z)) < abs(posDDX.y) + abs(posDDY.y))) ? InputPosition.xy : + ((0.5 * (abs(posDDX.x) + abs(posDDY.x)) < abs(posDDX.y) + abs(posDDY.y)) ? InputPosition.yz : InputPosition.xz)); +} + +#if defined(LOD) # undef COMPLEX_PARALLAX_MATERIALS # undef WATER_BLENDING # undef LIGHT_LIMIT_FIX @@ -1140,7 +1149,12 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace float2 diffuseUv = uv; # if defined(SPARKLE) +# if defined(VR) diffuseUv = ProjectedUVParams2.yy * input.TexCoord0.zw; +# else + float2 triplanarUv = ComputeTriplanarUV(input.InputPosition.xyz); + diffuseUv = ProjectedUVParams2.yy * triplanarUv; +# endif // VR # endif // SPARKLE # if defined(CPM_AVAILABLE) @@ -1157,7 +1171,11 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace # endif // LANDSCAPE # if defined(SPARKLE) +# if defined(VR) diffuseUv = ProjectedUVParams2.yy * (input.TexCoord0.zw + (uv - uvOriginal)); +# else + diffuseUv = ProjectedUVParams2.yy * (triplanarUv + (uv - uvOriginal)); +# endif // VR # else diffuseUv = uv; # endif // SPARKLE @@ -1431,7 +1449,11 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace # endif // SNOW # else if (ProjectedUVParams3.w > 0.5) { +# if defined(VR) + float2 projNormalUv = ProjectedUVParams3.x * ProjectedUVParams.zz * ComputeTriplanarUV(input.InputPosition.xyz); +# else float2 projNormalUv = ProjectedUVParams3.x * projNoiseUv; +# endif // VR float3 projNormal = TransformNormal(TexProjNormalSampler.Sample(SampProjNormalSampler, projNormalUv).xyz); float2 projDetailUv = ProjectedUVParams3.y * projNoiseUv; float3 projDetail = TexProjDetail.Sample(SampProjDetailSampler, projDetailUv).xyz; From 7362abceec29ee6aa87a97e099823daa84eb4fd2 Mon Sep 17 00:00:00 2001 From: CiMaWi Date: Wed, 25 Oct 2023 13:57:53 +0000 Subject: [PATCH 2/2] =?UTF-8?q?style:=20=F0=9F=8E=A8=20apply=20clang-forma?= =?UTF-8?q?t=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package/Shaders/Lighting.hlsl | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/package/Shaders/Lighting.hlsl b/package/Shaders/Lighting.hlsl index d9e5c4ac0..e6fca176b 100644 --- a/package/Shaders/Lighting.hlsl +++ b/package/Shaders/Lighting.hlsl @@ -952,11 +952,12 @@ float2 ComputeTriplanarUV(float3 InputPosition) float3 posDDX = ddx(InputPosition.xyz); float3 posDDY = ddy(InputPosition.xyz); return (((0.1 * (abs(posDDX.z) + abs(posDDY.z)) < abs(posDDX.x) + abs(posDDY.x)) && - (0.1 * (abs(posDDX.z) + abs(posDDY.z)) < abs(posDDX.y) + abs(posDDY.y))) ? InputPosition.xy : - ((0.5 * (abs(posDDX.x) + abs(posDDY.x)) < abs(posDDX.y) + abs(posDDY.y)) ? InputPosition.yz : InputPosition.xz)); + (0.1 * (abs(posDDX.z) + abs(posDDY.z)) < abs(posDDX.y) + abs(posDDY.y))) ? + InputPosition.xy : + ((0.5 * (abs(posDDX.x) + abs(posDDY.x)) < abs(posDDX.y) + abs(posDDY.y)) ? InputPosition.yz : InputPosition.xz)); } -#if defined(LOD) +# if defined(LOD) # undef COMPLEX_PARALLAX_MATERIALS # undef WATER_BLENDING # undef LIGHT_LIMIT_FIX @@ -1154,8 +1155,8 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace # else float2 triplanarUv = ComputeTriplanarUV(input.InputPosition.xyz); diffuseUv = ProjectedUVParams2.yy * triplanarUv; -# endif // VR -# endif // SPARKLE +# endif // VR +# endif // SPARKLE # if defined(CPM_AVAILABLE) @@ -1175,7 +1176,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace diffuseUv = ProjectedUVParams2.yy * (input.TexCoord0.zw + (uv - uvOriginal)); # else diffuseUv = ProjectedUVParams2.yy * (triplanarUv + (uv - uvOriginal)); -# endif // VR +# endif // VR # else diffuseUv = uv; # endif // SPARKLE @@ -1453,7 +1454,7 @@ PS_OUTPUT main(PS_INPUT input, bool frontFace float2 projNormalUv = ProjectedUVParams3.x * ProjectedUVParams.zz * ComputeTriplanarUV(input.InputPosition.xyz); # else float2 projNormalUv = ProjectedUVParams3.x * projNoiseUv; -# endif // VR +# endif // VR float3 projNormal = TransformNormal(TexProjNormalSampler.Sample(SampProjNormalSampler, projNormalUv).xyz); float2 projDetailUv = ProjectedUVParams3.y * projNoiseUv; float3 projDetail = TexProjDetail.Sample(SampProjDetailSampler, projDetailUv).xyz;