Skip to content

Commit

Permalink
PBR Shading: fixed normal computation from gradients for left-handed …
Browse files Browse the repository at this point in the history
…coordinate systems
  • Loading branch information
TheMostDiligent committed Jan 19, 2024
1 parent da3c592 commit 13f8321
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 16 deletions.
1 change: 1 addition & 0 deletions Hydrogent/src/Tasks/HnBeginFrameTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ void HnBeginFrameTask::UpdateFrameConstants(IDeviceContext* pCtx, IBuffer* pFram
1.f / static_cast<float>(m_FrameBufferWidth),
1.f / static_cast<float>(m_FrameBufferHeight),
};
CamAttribs.fHandness = ViewMatrix.Determinant() > 0 ? 1.f : -1.f;

CamAttribs.mViewT = ViewMatrix.Transpose();
CamAttribs.mProjT = ProjMatrix.Transpose();
Expand Down
7 changes: 4 additions & 3 deletions Shaders/Common/public/BasicStructures.fxh
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,11 @@ struct CameraAttribs
float4 f4Position; // Camera world position
float4 f4ViewportSize; // (width, height, 1/width, 1/height)

float2 f2ViewportOrigin; // (min x, min y)
float fNearPlaneZ;
float fFarPlaneZ; // fNearPlaneZ < fFarPlaneZ

float fFarPlaneZ; // fNearPlaneZ < fFarPlaneZ
float fHandness; // +1.0 for right-handed coordinate system, -1.0 for left-handed
float Padding;

#ifdef __cplusplus
float4x4 mViewT;
float4x4 mProjT;
Expand Down
2 changes: 1 addition & 1 deletion Shaders/PBR/private/RenderPBR.psh
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ PSOutput main(in VSOutput VSOut,
float3 MeshNormal = float3(0.0, 0.0, 0.0);
#endif
// We have to compute gradients in uniform flow control to avoid issues with perturbed normal
PerturbNormalInfo NormalInfo = GetPerturbNormalInfo(VSOut.WorldPos, MeshNormal, IsFrontFace);
PerturbNormalInfo NormalInfo = GetPerturbNormalInfo(VSOut.WorldPos, MeshNormal, IsFrontFace, g_Frame.Camera.fHandness);

PBRMaterialTextureAttribs NormalTexAttribs;
# if USE_NORMAL_MAP
Expand Down
26 changes: 14 additions & 12 deletions Shaders/PBR/public/PBR_Shading.fxh
Original file line number Diff line number Diff line change
Expand Up @@ -119,26 +119,28 @@ struct PerturbNormalInfo
float3 dPos_dx;
float3 dPos_dy;
float3 Normal;
bool IsFrontFace;
float Face; // +1.0 if front face, -1.0 if back face
};

PerturbNormalInfo GetPerturbNormalInfo(in float3 Pos, in float3 Normal, in bool IsFrontFace)
PerturbNormalInfo GetPerturbNormalInfo(in float3 Pos, // World position
in float3 Normal, // Mesh normal
in bool IsFrontFace, // True if front face
in float CameraHandness // 1.0 if right-handed, -1.0 if left-handed
)
{
PerturbNormalInfo Info;
Info.dPos_dx = ddx(Pos);
Info.dPos_dy = ddy(Pos);

Info.IsFrontFace = IsFrontFace;
Info.Face = IsFrontFace ? +1.0 : -1.0;

float NormalLen = length(Normal);
if (NormalLen > 1e-5)
{
NormalLen *= IsFrontFace ? +1.0 : -1.0;
Info.Normal = Normal / NormalLen;
Info.Normal = Normal / (NormalLen * Info.Face);
}
else
{
Info.Normal = normalize(cross(Info.dPos_dx, Info.dPos_dy));
Info.Normal = normalize(cross(Info.dPos_dx, Info.dPos_dy)) * CameraHandness;
#if (defined(GLSL) || defined(GL_ES)) && !defined(VULKAN)
// In OpenGL, the screen is upside-down, so we have to invert the vector
Info.Normal *= -1.0;
Expand All @@ -153,14 +155,14 @@ PerturbNormalInfo GetPerturbNormalInfo(in float3 Pos, in float3 Normal, in bool
// Find the normal for this fragment, pulling either from a predefined normal map
// or from the interpolated mesh normal and tangent attributes.
float3 PerturbNormal(PerturbNormalInfo NormalInfo,
in float2 dUV_dx,
in float2 dUV_dy,
in float3 TSNormal,
bool HasUV)
in float2 dUV_dx,
in float2 dUV_dy,
in float3 TSNormal,
bool HasUV)
{
if (HasUV)
{
TSNormal.xy *= NormalInfo.IsFrontFace ? +1.0 : -1.0;
TSNormal.xy *= NormalInfo.Face;
return TransformTangentSpaceNormalGrad(NormalInfo.dPos_dx, NormalInfo.dPos_dy, dUV_dx, dUV_dy, NormalInfo.Normal, TSNormal);
}
else
Expand Down

0 comments on commit 13f8321

Please sign in to comment.