Skip to content

Commit

Permalink
PBR Renderer: fixed shader conversion issue in OpenGL
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Sep 15, 2023
1 parent 221792c commit 3d2b1bb
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 89 deletions.
2 changes: 1 addition & 1 deletion PBR/src/PBR_Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ void PBR_Renderer::CreatePSO(IRenderDevice* pDevice, IRenderStateCache* pStateCa
RefCntAutoPtr<IShader> pVS;
{
ShaderCI.Desc = {"PBR VS", SHADER_TYPE_VERTEX, true};
ShaderCI.EntryPoint = "main";
ShaderCI.EntryPoint = m_Settings.MaxJointCount > 0 ? "VSMainSkinned" : "VSMain";
ShaderCI.FilePath = "RenderPBR.vsh";

pVS = Device.CreateShader(ShaderCI);
Expand Down
45 changes: 25 additions & 20 deletions Shaders/PBR/private/RenderPBR.psh
Original file line number Diff line number Diff line change
Expand Up @@ -103,24 +103,29 @@ float4 SampleTexture(Texture2DArray Tex,
#endif
}

void main(in float4 ClipPos : SV_Position,
in float3 WorldPos : WORLD_POS,
in float3 Normal : NORMAL,
in float2 UV0 : UV0,
in float2 UV1 : UV1,
in bool IsFrontFace : SV_IsFrontFace,
out float4 OutColor : SV_Target)
struct PbrVsOutput
{
float4 BaseColor = SampleTexture(g_ColorMap, g_ColorMap_sampler, UV0, UV1, g_PBRAttribs.Material.BaseColorTextureUVSelector,
float4 ClipPos : SV_Position;
float3 WorldPos : WORLD_POS;
float3 Normal : NORMAL;
float2 UV0 : UV0;
float2 UV1 : UV1;
};

void main(in PbrVsOutput VSOut,
in bool IsFrontFace : SV_IsFrontFace,
out float4 OutColor : SV_Target)
{
float4 BaseColor = SampleTexture(g_ColorMap, g_ColorMap_sampler, VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.BaseColorTextureUVSelector,
g_PBRAttribs.Material.BaseColorUVScaleBias, g_PBRAttribs.Material.BaseColorSlice, float4(1.0, 1.0, 1.0, 1.0));
BaseColor = SRGBtoLINEAR(BaseColor) * g_PBRAttribs.Material.BaseColorFactor;
//BaseColor *= getVertexColor();

float2 NormalMapUV = lerp(UV0, UV1, g_PBRAttribs.Material.NormalTextureUVSelector);
float2 NormalMapUV = lerp(VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.NormalTextureUVSelector);

// We have to compute gradients in uniform flow control to avoid issues with perturbed normal
float3 dWorldPos_dx = ddx(WorldPos);
float3 dWorldPos_dy = ddy(WorldPos);
float3 dWorldPos_dx = ddx(VSOut.WorldPos);
float3 dWorldPos_dy = ddy(VSOut.WorldPos);
float2 dNormalMapUV_dx = ddx(NormalMapUV);
float2 dNormalMapUV_dy = ddy(NormalMapUV);
#if USE_TEXTURE_ATLAS
Expand All @@ -144,7 +149,7 @@ void main(in float4 ClipPos : SV_Position,
{
SampleTextureAtlasAttribs SampleAttribs;
SampleAttribs.f2UV = NormalMapUV;
SampleAttribs.f2SmoothUV = lerp(UV0, UV1, g_PBRAttribs.Material.NormalTextureUVSelector) * g_PBRAttribs.Material.NormalMapUVScaleBias.xy;
SampleAttribs.f2SmoothUV = lerp(VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.NormalTextureUVSelector) * g_PBRAttribs.Material.NormalMapUVScaleBias.xy;
SampleAttribs.f2dSmoothUV_dx = dNormalMapUV_dx;
SampleAttribs.f2dSmoothUV_dy = dNormalMapUV_dy;
SampleAttribs.fSlice = g_PBRAttribs.Material.NormalSlice;
Expand All @@ -163,30 +168,30 @@ void main(in float4 ClipPos : SV_Position,

float Occlusion = 1.0;
#if PBR_USE_AO
Occlusion = SampleTexture(g_AOMap, g_AOMap_sampler, UV0, UV1, g_PBRAttribs.Material.OcclusionTextureUVSelector,
Occlusion = SampleTexture(g_AOMap, g_AOMap_sampler, VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.OcclusionTextureUVSelector,
g_PBRAttribs.Material.OcclusionUVScaleBias, g_PBRAttribs.Material.OcclusionSlice, float4(1.0, 1.0, 1.0, 1.0)).r;
Occlusion *= g_PBRAttribs.Material.OcclusionFactor;
#endif

float3 Emissive = float3(0.0, 0.0, 0.0);
#if PBR_USE_EMISSIVE
Emissive = SampleTexture(g_EmissiveMap, g_EmissiveMap_sampler, UV0, UV1, g_PBRAttribs.Material.EmissiveTextureUVSelector,
Emissive = SampleTexture(g_EmissiveMap, g_EmissiveMap_sampler, VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.EmissiveTextureUVSelector,
g_PBRAttribs.Material.EmissiveUVScaleBias, g_PBRAttribs.Material.EmissiveSlice, float4(0.0, 0.0, 0.0, 0.0)).rgb;
#endif

float4 PhysicalDesc = float4(0.0, 0.0, 0.0, 0.0);
#if USE_SEPARATE_METALLIC_ROUGHNESS_TEXTURES
PhysicalDesc.b = SampleTexture(g_MetallicMap, g_MetallicMap_sampler,
UV0, UV1, g_PBRAttribs.Material.PhysicalDescriptorTextureUVSelector,
VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.PhysicalDescriptorTextureUVSelector,
g_PBRAttribs.Material.PhysicalDescriptorUVScaleBias, g_PBRAttribs.Material.PhysicalDescriptorSlice,
float4(0.0, 1.0, 0.0, 0.0)).r;
PhysicalDesc.g = SampleTexture(g_RoughnessMap, g_RoughnessMap_sampler,
UV0, UV1, g_PBRAttribs.Material.PhysicalDescriptorTextureUVSelector,
VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.PhysicalDescriptorTextureUVSelector,
g_PBRAttribs.Material.PhysicalDescriptorUVScaleBias, g_PBRAttribs.Material.PhysicalDescriptorSlice,
float4(0.0, 1.0, 0.0, 0.0)).r;
#else
PhysicalDesc = SampleTexture(g_PhysicalDescriptorMap, g_PhysicalDescriptorMap_sampler,
UV0, UV1, g_PBRAttribs.Material.PhysicalDescriptorTextureUVSelector,
VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.PhysicalDescriptorTextureUVSelector,
g_PBRAttribs.Material.PhysicalDescriptorUVScaleBias, g_PBRAttribs.Material.PhysicalDescriptorSlice,
float4(0.0, 1.0, 0.0, 0.0));
#endif
Expand All @@ -207,8 +212,8 @@ void main(in float4 ClipPos : SV_Position,

// LIGHTING
float3 perturbedNormal = PerturbNormal(dWorldPos_dx, dWorldPos_dy, dNormalMapUV_dx, dNormalMapUV_dy,
Normal, TSNormal, g_PBRAttribs.Material.NormalTextureUVSelector >= 0.0, IsFrontFace);
float3 view = normalize(g_CameraAttribs.f4Position.xyz - WorldPos.xyz); // Direction from surface point to camera
VSOut.Normal, TSNormal, g_PBRAttribs.Material.NormalTextureUVSelector >= 0.0, IsFrontFace);
float3 view = normalize(g_CameraAttribs.f4Position.xyz - VSOut.WorldPos.xyz); // Direction from surface point to camera

float3 color = float3(0.0, 0.0, 0.0);
color += ApplyDirectionalLight(g_LightAttribs.f4Direction.xyz, g_LightAttribs.f4Intensity.rgb, SrfInfo, perturbedNormal, view);
Expand Down Expand Up @@ -284,7 +289,7 @@ void main(in float4 ClipPos : SV_Position,
case 8: OutColor.rgb = SrfInfo.DiffuseColor; break;
case 9: OutColor.rgb = SrfInfo.Reflectance0; break;
case 10: OutColor.rgb = SrfInfo.Reflectance90; break;
case 11: OutColor.rgb = SRGBtoLINEAR(abs(Normal / max(length(Normal), 1e-3))); break;
case 11: OutColor.rgb = SRGBtoLINEAR(abs(VSOut.Normal / max(length(VSOut.Normal), 1e-3))); break;
case 12: OutColor.rgb = SRGBtoLINEAR(abs(perturbedNormal)); break;
case 13: OutColor.rgb = dot(perturbedNormal, view) * float3(1.0, 1.0, 1.0); break;
#if PBR_USE_IBL
Expand Down
83 changes: 57 additions & 26 deletions Shaders/PBR/private/RenderPBR.vsh
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@
# define MAX_JOINT_COUNT 64
#endif

struct GLTF_VS_Input
struct VertexAttribs
{
float3 Pos : ATTRIB0;
float3 Normal : ATTRIB1;
float2 UV0 : ATTRIB2;
float2 UV1 : ATTRIB3;
float3 Pos : ATTRIB0;
float3 Normal : ATTRIB1;
float2 UV0 : ATTRIB2;
float2 UV1 : ATTRIB3;
};

#if MAX_JOINT_COUNT > 0
struct SkinningAttribs
{
float4 Joint0 : ATTRIB4;
float4 Weight0 : ATTRIB5;
#endif
};
#endif

cbuffer cbCameraAttribs
cbuffer cbCameraAttribs
{
CameraAttribs g_CameraAttribs;
}
Expand All @@ -34,13 +38,21 @@ cbuffer cbJointTransforms
float4x4 g_Joints[MAX_JOINT_COUNT];
}
#endif

void main(in GLTF_VS_Input VSIn,
out float4 ClipPos : SV_Position,
out float3 WorldPos : WORLD_POS,
out float3 Normal : NORMAL,
out float2 UV0 : UV0,
out float2 UV1 : UV1)

struct PbrVsOutput
{
float4 ClipPos : SV_Position;
float3 WorldPos : WORLD_POS;
float3 Normal : NORMAL;
float2 UV0 : UV0;
float2 UV1 : UV1;
};

void VSMainInternal(in VertexAttribs Vert,
#if MAX_JOINT_COUNT > 0
in SkinningAttribs Skinning,
#endif
out PbrVsOutput VSOut)
{
// Warning: moving this block into GLTF_TransformVertex() function causes huge
// performance degradation on Vulkan because glslang/SPIRV-Tools are apparently not able
Expand All @@ -52,19 +64,38 @@ void main(in GLTF_VS_Input VSIn,
{
// Mesh is skinned
float4x4 SkinMat =
VSIn.Weight0.x * g_Joints[int(VSIn.Joint0.x)] +
VSIn.Weight0.y * g_Joints[int(VSIn.Joint0.y)] +
VSIn.Weight0.z * g_Joints[int(VSIn.Joint0.z)] +
VSIn.Weight0.w * g_Joints[int(VSIn.Joint0.w)];
Skinning.Weight0.x * g_Joints[int(Skinning.Joint0.x)] +
Skinning.Weight0.y * g_Joints[int(Skinning.Joint0.y)] +
Skinning.Weight0.z * g_Joints[int(Skinning.Joint0.z)] +
Skinning.Weight0.w * g_Joints[int(Skinning.Joint0.w)];
Transform = mul(Transform, SkinMat);
}
#endif

GLTF_TransformedVertex TransformedVert = GLTF_TransformVertex(VSIn.Pos, VSIn.Normal, Transform);

ClipPos = mul(float4(TransformedVert.WorldPos, 1.0), g_CameraAttribs.mViewProj);
WorldPos = TransformedVert.WorldPos;
Normal = TransformedVert.Normal;
UV0 = VSIn.UV0;
UV1 = VSIn.UV1;

GLTF_TransformedVertex TransformedVert = GLTF_TransformVertex(Vert.Pos, Vert.Normal, Transform);

VSOut.ClipPos = mul(float4(TransformedVert.WorldPos, 1.0), g_CameraAttribs.mViewProj);
VSOut.WorldPos = TransformedVert.WorldPos;
VSOut.Normal = TransformedVert.Normal;
VSOut.UV0 = Vert.UV0;
VSOut.UV1 = Vert.UV1;
}

#if MAX_JOINT_COUNT > 0

void VSMainSkinned(in VertexAttribs Vert,
in SkinningAttribs Skinning,
out PbrVsOutput VSOut)
{
VSMainInternal(Vert, Skinning, VSOut);
}

#else

void VSMain(in VertexAttribs Vert,
out PbrVsOutput VSOut)
{
VSMainInternal(Vert, VSOut);
}

#endif
45 changes: 25 additions & 20 deletions shaders_inc/RenderPBR.psh.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,24 +103,29 @@
"#endif\n"
"}\n"
"\n"
"void main(in float4 ClipPos : SV_Position,\n"
" in float3 WorldPos : WORLD_POS,\n"
" in float3 Normal : NORMAL,\n"
" in float2 UV0 : UV0,\n"
" in float2 UV1 : UV1,\n"
" in bool IsFrontFace : SV_IsFrontFace,\n"
" out float4 OutColor : SV_Target)\n"
"struct PbrVsOutput\n"
"{\n"
" float4 BaseColor = SampleTexture(g_ColorMap, g_ColorMap_sampler, UV0, UV1, g_PBRAttribs.Material.BaseColorTextureUVSelector,\n"
" float4 ClipPos : SV_Position;\n"
" float3 WorldPos : WORLD_POS;\n"
" float3 Normal : NORMAL;\n"
" float2 UV0 : UV0;\n"
" float2 UV1 : UV1;\n"
"};\n"
"\n"
"void main(in PbrVsOutput VSOut,\n"
" in bool IsFrontFace : SV_IsFrontFace,\n"
" out float4 OutColor : SV_Target)\n"
"{\n"
" float4 BaseColor = SampleTexture(g_ColorMap, g_ColorMap_sampler, VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.BaseColorTextureUVSelector,\n"
" g_PBRAttribs.Material.BaseColorUVScaleBias, g_PBRAttribs.Material.BaseColorSlice, float4(1.0, 1.0, 1.0, 1.0));\n"
" BaseColor = SRGBtoLINEAR(BaseColor) * g_PBRAttribs.Material.BaseColorFactor;\n"
" //BaseColor *= getVertexColor();\n"
"\n"
" float2 NormalMapUV = lerp(UV0, UV1, g_PBRAttribs.Material.NormalTextureUVSelector);\n"
" float2 NormalMapUV = lerp(VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.NormalTextureUVSelector);\n"
"\n"
" // We have to compute gradients in uniform flow control to avoid issues with perturbed normal\n"
" float3 dWorldPos_dx = ddx(WorldPos);\n"
" float3 dWorldPos_dy = ddy(WorldPos);\n"
" float3 dWorldPos_dx = ddx(VSOut.WorldPos);\n"
" float3 dWorldPos_dy = ddy(VSOut.WorldPos);\n"
" float2 dNormalMapUV_dx = ddx(NormalMapUV);\n"
" float2 dNormalMapUV_dy = ddy(NormalMapUV);\n"
"#if USE_TEXTURE_ATLAS\n"
Expand All @@ -144,7 +149,7 @@
" {\n"
" SampleTextureAtlasAttribs SampleAttribs;\n"
" SampleAttribs.f2UV = NormalMapUV;\n"
" SampleAttribs.f2SmoothUV = lerp(UV0, UV1, g_PBRAttribs.Material.NormalTextureUVSelector) * g_PBRAttribs.Material.NormalMapUVScaleBias.xy;\n"
" SampleAttribs.f2SmoothUV = lerp(VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.NormalTextureUVSelector) * g_PBRAttribs.Material.NormalMapUVScaleBias.xy;\n"
" SampleAttribs.f2dSmoothUV_dx = dNormalMapUV_dx;\n"
" SampleAttribs.f2dSmoothUV_dy = dNormalMapUV_dy;\n"
" SampleAttribs.fSlice = g_PBRAttribs.Material.NormalSlice;\n"
Expand All @@ -163,30 +168,30 @@
"\n"
" float Occlusion = 1.0;\n"
"#if PBR_USE_AO\n"
" Occlusion = SampleTexture(g_AOMap, g_AOMap_sampler, UV0, UV1, g_PBRAttribs.Material.OcclusionTextureUVSelector,\n"
" Occlusion = SampleTexture(g_AOMap, g_AOMap_sampler, VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.OcclusionTextureUVSelector,\n"
" g_PBRAttribs.Material.OcclusionUVScaleBias, g_PBRAttribs.Material.OcclusionSlice, float4(1.0, 1.0, 1.0, 1.0)).r;\n"
" Occlusion *= g_PBRAttribs.Material.OcclusionFactor;\n"
"#endif\n"
"\n"
" float3 Emissive = float3(0.0, 0.0, 0.0);\n"
"#if PBR_USE_EMISSIVE\n"
" Emissive = SampleTexture(g_EmissiveMap, g_EmissiveMap_sampler, UV0, UV1, g_PBRAttribs.Material.EmissiveTextureUVSelector,\n"
" Emissive = SampleTexture(g_EmissiveMap, g_EmissiveMap_sampler, VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.EmissiveTextureUVSelector,\n"
" g_PBRAttribs.Material.EmissiveUVScaleBias, g_PBRAttribs.Material.EmissiveSlice, float4(0.0, 0.0, 0.0, 0.0)).rgb;\n"
"#endif\n"
"\n"
" float4 PhysicalDesc = float4(0.0, 0.0, 0.0, 0.0);\n"
"#if USE_SEPARATE_METALLIC_ROUGHNESS_TEXTURES\n"
" PhysicalDesc.b = SampleTexture(g_MetallicMap, g_MetallicMap_sampler,\n"
" UV0, UV1, g_PBRAttribs.Material.PhysicalDescriptorTextureUVSelector,\n"
" VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.PhysicalDescriptorTextureUVSelector,\n"
" g_PBRAttribs.Material.PhysicalDescriptorUVScaleBias, g_PBRAttribs.Material.PhysicalDescriptorSlice,\n"
" float4(0.0, 1.0, 0.0, 0.0)).r;\n"
" PhysicalDesc.g = SampleTexture(g_RoughnessMap, g_RoughnessMap_sampler,\n"
" UV0, UV1, g_PBRAttribs.Material.PhysicalDescriptorTextureUVSelector,\n"
" VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.PhysicalDescriptorTextureUVSelector,\n"
" g_PBRAttribs.Material.PhysicalDescriptorUVScaleBias, g_PBRAttribs.Material.PhysicalDescriptorSlice,\n"
" float4(0.0, 1.0, 0.0, 0.0)).r;\n"
"#else\n"
" PhysicalDesc = SampleTexture(g_PhysicalDescriptorMap, g_PhysicalDescriptorMap_sampler,\n"
" UV0, UV1, g_PBRAttribs.Material.PhysicalDescriptorTextureUVSelector,\n"
" VSOut.UV0, VSOut.UV1, g_PBRAttribs.Material.PhysicalDescriptorTextureUVSelector,\n"
" g_PBRAttribs.Material.PhysicalDescriptorUVScaleBias, g_PBRAttribs.Material.PhysicalDescriptorSlice,\n"
" float4(0.0, 1.0, 0.0, 0.0));\n"
"#endif\n"
Expand All @@ -207,8 +212,8 @@
"\n"
" // LIGHTING\n"
" float3 perturbedNormal = PerturbNormal(dWorldPos_dx, dWorldPos_dy, dNormalMapUV_dx, dNormalMapUV_dy,\n"
" Normal, TSNormal, g_PBRAttribs.Material.NormalTextureUVSelector >= 0.0, IsFrontFace);\n"
" float3 view = normalize(g_CameraAttribs.f4Position.xyz - WorldPos.xyz); // Direction from surface point to camera\n"
" VSOut.Normal, TSNormal, g_PBRAttribs.Material.NormalTextureUVSelector >= 0.0, IsFrontFace);\n"
" float3 view = normalize(g_CameraAttribs.f4Position.xyz - VSOut.WorldPos.xyz); // Direction from surface point to camera\n"
"\n"
" float3 color = float3(0.0, 0.0, 0.0);\n"
" color += ApplyDirectionalLight(g_LightAttribs.f4Direction.xyz, g_LightAttribs.f4Intensity.rgb, SrfInfo, perturbedNormal, view);\n"
Expand Down Expand Up @@ -284,7 +289,7 @@
" case 8: OutColor.rgb = SrfInfo.DiffuseColor; break;\n"
" case 9: OutColor.rgb = SrfInfo.Reflectance0; break;\n"
" case 10: OutColor.rgb = SrfInfo.Reflectance90; break;\n"
" case 11: OutColor.rgb = SRGBtoLINEAR(abs(Normal / max(length(Normal), 1e-3))); break;\n"
" case 11: OutColor.rgb = SRGBtoLINEAR(abs(VSOut.Normal / max(length(VSOut.Normal), 1e-3))); break;\n"
" case 12: OutColor.rgb = SRGBtoLINEAR(abs(perturbedNormal)); break;\n"
" case 13: OutColor.rgb = dot(perturbedNormal, view) * float3(1.0, 1.0, 1.0); break;\n"
"#if PBR_USE_IBL\n"
Expand Down
Loading

0 comments on commit 3d2b1bb

Please sign in to comment.