Skip to content

Commit fe7955c

Browse files
HDRenderPipeline: Fix issue with SurfaceGradient + update flip/mirror normal
1 parent c508d83 commit fe7955c

2 files changed

Lines changed: 11 additions & 27 deletions

File tree

Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ void GenerateLayerTexCoordBasisTB(FragInputs input, inout LayerTexCoord layerTex
8686
{
8787
float3 vertexNormalWS = input.worldToTangent[2];
8888

89-
layerTexCoord.vertexTangentWS0 = input.worldToTangent[1];
90-
layerTexCoord.vertexBitangentWS0 = input.worldToTangent[2];
89+
layerTexCoord.vertexTangentWS0 = input.worldToTangent[0];
90+
layerTexCoord.vertexBitangentWS0 = input.worldToTangent[1];
9191

9292
// TODO: We should use relative camera position here - This will be automatic when we will move to camera relative space.
9393
float3 dPdx = ddx_fine(input.positionWS);
@@ -292,7 +292,7 @@ float ComputePerVertexDisplacement(LayerTexCoord layerTexCoord, float4 vertexCol
292292

293293
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
294294
{
295-
ApplyDoubleSidedFlip(input); // Apply double sided flip on the vertex normal
295+
ApplyDoubleSidedFlipOrMirror(input); // Apply double sided flip on the vertex normal
296296

297297
LayerTexCoord layerTexCoord;
298298
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
@@ -310,7 +310,6 @@ void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs p
310310
// so it allow us to correctly deal with detail normal map and optimize the code for the layered shaders
311311
float3 normalTS;
312312
float alpha = GetSurfaceData(input, layerTexCoord, surfaceData, normalTS);
313-
ApplyDoubleSidedMirror(input, normalTS); // Apply double sided mirror on the final normalTS
314313
GetNormalAndTangentWS(input, V, normalTS, surfaceData.normalWS, surfaceData.tangentWS);
315314
// Done one time for all layered - cumulate with spec occ alpha for now
316315
surfaceData.specularOcclusion *= GetHorizonOcclusion(V, surfaceData.normalWS, input.worldToTangent[2].xyz, _HorizonFade);
@@ -1101,7 +1100,7 @@ float3 ComputeMainBaseColorInfluence(float3 baseColor0, float3 baseColor1, float
11011100

11021101
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
11031102
{
1104-
ApplyDoubleSidedFlip(input); // Apply double sided flip on the vertex normal
1103+
ApplyDoubleSidedFlipOrMirror(input); // Apply double sided flip on the vertex normal
11051104

11061105
LayerTexCoord layerTexCoord;
11071106
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
@@ -1159,7 +1158,6 @@ void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs p
11591158
surfaceData.coatPerceptualSmoothness = 1.0;
11601159
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
11611160

1162-
ApplyDoubleSidedMirror(input, normalTS); // Apply double sided mirror on the final normalTS
11631161
GetNormalAndTangentWS(input, V, normalTS, surfaceData.normalWS, surfaceData.tangentWS);
11641162
// Done one time for all layered - cumulate with spec occ alpha for now
11651163
surfaceData.specularOcclusion = SURFACEDATA_BLEND_SCALAR(surfaceData, specularOcclusion, weights);

Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -84,38 +84,24 @@ float2 CalculateVelocity(float4 positionCS, float4 previousPositionCS)
8484
#endif
8585
}
8686

87-
// To flip in case of double sided, we must flip the vertex normal and this will apply to the whole process either in surface gradient or not.
88-
// As here we are in the function call GetSurfaceAndBuiltinData(), the tangent space is already built, so we need to flip both normal and bitangent.
87+
// Flipping or mirroring a normal can be done directly on the tangent space. This has the benefit to apply to the whole process either in surface gradient or not.
8988
// This function will modify FragInputs and this is not propagate outside of GetSurfaceAndBuiltinData(). This is ok as tangent space is not use outside of GetSurfaceAndBuiltinData().
90-
void ApplyDoubleSidedFlip(inout FragInputs input)
89+
void ApplyDoubleSidedFlipOrMirror(inout FragInputs input)
9190
{
9291
#ifdef _DOUBLESIDED_ON
9392
// _DoubleSidedConstants is float3(-1, -1, -1) in flip mode and float3(1, 1, -1) in mirror mode
94-
float flipSign = input.isFrontFace ? 1.0 : _DoubleSidedConstants.x; // TOCHECK : GetOddNegativeScale() is not necessary here as it is apply for tangent space creation.
95-
input.worldToTangent[1] = flipSign * input.worldToTangent[1]; // bitangent
96-
input.worldToTangent[2] = flipSign * input.worldToTangent[2]; // normal
93+
// To get a flipped normal with the tangent space, we must flip bitangent (because it is construct from the normal) and normal
94+
// To get a mirror normal with the tangent space, we only need to flip the normal and not the tangent
95+
float2 flipSign = input.isFrontFace ? float2(1.0, 1.0) : _DoubleSidedConstants.yz; // TOCHECK : GetOddNegativeScale() is not necessary here as it is apply for tangent space creation.
96+
input.worldToTangent[1] = flipSign.x * input.worldToTangent[1]; // bitangent
97+
input.worldToTangent[2] = flipSign.y * input.worldToTangent[2]; // normal
9798

9899
#ifdef SURFACE_GRADIENT
99100
// TOCHECK: seems that we don't need to invert any genBasisTB(), sign cancel. Which is expected as we deal with surface gradient.
100101
#endif
101102
#endif
102103
}
103104

104-
// To mirror a normal: in ws reflect around the vertex normal / in tangent space apply minus on the z component.
105-
// For surface gradient it is sufficient to take the opposite of the surface gradient.
106-
void ApplyDoubleSidedMirror(FragInputs input, inout float3 normalTS)
107-
{
108-
#ifdef _DOUBLESIDED_ON
109-
// _DoubleSidedConstants is float3(-1, -1, -1) in flip mode and float3(1, 1, -1) in mirror mode
110-
float flipSign = input.isFrontFace ? 1.0 : -_DoubleSidedConstants.x; // TOCHECK : GetOddNegativeScale() is not necessary here as it is apply for tangent space creation.
111-
#ifdef SURFACE_GRADIENT
112-
normalTS = flipSign * normalTS;
113-
#else
114-
normalTS.z *= flipSign;
115-
#endif
116-
#endif
117-
}
118-
119105
// This function convert the tangent space normal/tangent to world space and orthonormalize it + apply a correction of the normal if it is not pointing towards the near plane
120106
void GetNormalAndTangentWS(FragInputs input, float3 V, float3 normalTS, inout float3 normalWS, inout float3 tangentWS, bool wantNegativeNormal = false)
121107
{

0 commit comments

Comments
 (0)