Skip to content

Commit 93e0690

Browse files
refactor: restructure lighting (#1633)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent d221945 commit 93e0690

File tree

5 files changed

+733
-728
lines changed

5 files changed

+733
-728
lines changed

features/Hair Specular/Shaders/Hair/Hair.hlsli

Lines changed: 24 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,15 @@ namespace Hair
6767
const float NdotV = saturate(dot(N, V));
6868
const float VNdotV = dot(VN, V);
6969
const float VNdotL = dot(VN, L);
70+
const float satVNdotL = saturate(VNdotL);
7071
const float HdotV = saturate(dot(H, V));
7172
const float HdotL = saturate(dot(H, L));
7273
const float wrapped = 0.5;
7374

7475
// [Yibing Jiang 2016, "The Process of Creating Volumetric-based Materials in Uncharted 4"]
7576
// https://advances.realtimerendering.com/s2016
7677
dirDiffuse = saturate(oNdotL + wrapped) / (1 + wrapped);
77-
float3 scatterColor = lerp(float3(0.992, 0.808, 0.518), baseColor, 0.5);
78+
float3 scatterColor = pow(baseColor, 0.5);
7879
dirDiffuse = saturate(scatterColor + NdotL) * dirDiffuse * lightColor * SharedData::hairSpecularSettings.DiffuseMult;
7980

8081
float3 TshiftPrimary;
@@ -205,74 +206,51 @@ namespace Hair
205206
T = ShiftTangent(T, N, shift);
206207
}
207208

208-
const float cosThetaV = dot(VN, V);
209-
210209
float backlit = SharedData::hairSpecularSettings.Transmission;
211210

212211
dirTransmission += D_Marschner(L, V, T, roughness, baseColor, 0, backlit) * lightColor * SharedData::hairSpecularSettings.SpecularMult;
213212
dirTransmission += GetHairDiffuseAttenuationKajiyaKay(T, V, L, selfShadow, baseColor) * lightColor * SharedData::hairSpecularSettings.DiffuseMult;
214213
}
215214

216-
void GetHairDirectLight(out float3 dirDiffuse, out float3 dirSpecular, out float3 dirTransmission, float3 T, float3 L, float3 V, float3 N, float3 VN, float3 lightColor, float shininess, float selfShadow, float2 uv, float3 baseColor)
215+
void GetHairDirectLight(out DirectLightingOutput lightingOutput, DirectContext context, MaterialProperties material, float3x3 tbnTr, float2 uv)
217216
{
217+
const float3 T = normalize(context.worldNormal);
218+
const float3 V = normalize(context.viewDir);
219+
const float3 N = normalize(context.vertexNormal);
220+
const float3 VN = normalize(tbnTr[2]);
221+
const float3 L = normalize(context.lightDir);
222+
218223
if (SharedData::hairSpecularSettings.HairMode == 0) {
219-
GetHairDirectLightScheuermann(dirDiffuse, dirSpecular, dirTransmission, T, L, V, N, VN, lightColor, shininess, selfShadow, uv, baseColor);
224+
GetHairDirectLightScheuermann(lightingOutput.diffuse, lightingOutput.specular, lightingOutput.transmission, T, L, V, N, VN, context.lightColor, material.Shininess, context.hairShadow, uv, material.BaseColor);
220225
} else {
221-
GetHairDirectLightMarschner(dirDiffuse, dirSpecular, dirTransmission, T, L, V, N, VN, lightColor, shininess, selfShadow, uv, baseColor);
226+
GetHairDirectLightMarschner(lightingOutput.diffuse, lightingOutput.specular, lightingOutput.transmission, T, L, V, N, VN, context.lightColor, material.Shininess, context.hairShadow, uv, material.BaseColor);
222227
}
223228
}
224229

225-
void GetHairIndirectSpecularLobeWeights(out float3 diffuseLobeWeight, out float3 specularLobeWeightPrimary, out float3 specularLobeWeightSecondary, float3 T, float3 N, float3 V, float3 VN, float shininess, float2 uv, float3 baseColor)
230+
void GetHairIndirectLobeWeights(out IndirectLobeWeights lobeWeights, IndirectContext context, MaterialProperties material, float2 uv)
226231
{
227-
const float roughnessPrimary = pow(abs(2.0 / (shininess + 2.0)), 0.25);
228-
const float roughnessSecondary = pow(abs(2.0 / (shininess * 0.5 + 2.0)), 0.25);
229-
const float NdotV = saturate(dot(N, V));
232+
lobeWeights = (IndirectLobeWeights)0;
230233

231-
if (SharedData::hairSpecularSettings.HairMode == 1) {
232-
specularLobeWeightPrimary = 0;
233-
specularLobeWeightSecondary = 0;
234+
float3 T = normalize(context.worldNormal);
235+
const float3 V = normalize(context.viewDir);
236+
const float3 N = normalize(context.vertexNormal);
234237

238+
if (SharedData::hairSpecularSettings.HairMode == 1) {
235239
if (SharedData::hairSpecularSettings.EnableTangentShift) {
236240
const float shift = TexTangentShift.SampleLevel(SampColorSampler, uv, 0).x - 0.5;
237241
T = ShiftTangent(T, N, shift);
238242
}
239243
float3 L = normalize(V - T * dot(V, T));
240244

241-
diffuseLobeWeight = D_Marschner(L, V, T, roughnessPrimary, baseColor, 0.2, 0) * Math::PI;
242-
diffuseLobeWeight += GetHairDiffuseAttenuationKajiyaKay(T, V, L, 1, baseColor) * Math::PI;
245+
lobeWeights.diffuse = D_Marschner(L, V, T, 1 - saturate(material.Shininess * 0.01), material.BaseColor, 0.2, 0) * Math::PI * SharedData::hairSpecularSettings.SpecularIndirectMult;
246+
lobeWeights.diffuse += GetHairDiffuseAttenuationKajiyaKay(T, V, L, 1, material.BaseColor) * Math::PI * SharedData::hairSpecularSettings.DiffuseIndirectMult;
243247
return;
244248
} else {
245-
float NdotVshifted = NdotV;
246-
float NdotVshifted2 = NdotV;
247-
248-
if (SharedData::hairSpecularSettings.EnableTangentShift) {
249-
const float shift = TexTangentShift.SampleLevel(SampColorSampler, uv, 0).x - 0.5;
250-
NdotVshifted = saturate(dot(ShiftNormal(T, N, shift + SharedData::hairSpecularSettings.PrimaryTangentShift), V));
251-
NdotVshifted2 = saturate(dot(ShiftNormal(T, N, shift + SharedData::hairSpecularSettings.SecondaryTangentShift), V));
252-
}
253-
254-
diffuseLobeWeight = baseColor;
255-
specularLobeWeightPrimary = 0;
256-
specularLobeWeightSecondary = 0;
257-
258-
const float2 specularBRDFPrimary = BRDF::EnvBRDF(roughnessPrimary, NdotVshifted);
259-
const float2 specularBRDFSecondary = BRDF::EnvBRDF(roughnessSecondary, NdotVshifted2);
260-
261-
const float3 F0 = HairF0();
262-
specularLobeWeightPrimary = F0 * specularBRDFPrimary.x + specularBRDFPrimary.y;
263-
diffuseLobeWeight *= (1 - specularLobeWeightPrimary);
264-
diffuseLobeWeight = saturate(diffuseLobeWeight);
265-
specularLobeWeightPrimary *= 1 + F0 * (1 / (specularBRDFPrimary.x + specularBRDFPrimary.y) - 1);
266-
267-
specularLobeWeightSecondary = F0 * specularBRDFSecondary.x + specularBRDFSecondary.y;
268-
specularLobeWeightSecondary *= 1 + F0 * (1 / (specularBRDFSecondary.x + specularBRDFSecondary.y) - 1);
269-
specularLobeWeightSecondary *= baseColor;
270-
271-
float3 R = reflect(-V, N);
272-
float horizon = min(1.0 + dot(R, VN), 1.0);
273-
horizon = horizon * horizon;
274-
specularLobeWeightPrimary *= horizon;
275-
specularLobeWeightSecondary *= horizon;
249+
lobeWeights.diffuse = saturate(material.BaseColor * SharedData::hairSpecularSettings.DiffuseIndirectMult);
250+
float2 hairBRDF = BRDF::EnvBRDF(material.Roughness, saturate(dot(N, V)));
251+
float3 hairSpecularLobe = material.F0 * hairBRDF.x + hairBRDF.y;
252+
lobeWeights.diffuse *= (1 - hairSpecularLobe);
253+
lobeWeights.specular = saturate(hairSpecularLobe * SharedData::hairSpecularSettings.SpecularIndirectMult);
276254
}
277255
}
278256

@@ -318,39 +296,5 @@ namespace Hair
318296
}
319297
return lerp(1.0, shadow, SharedData::hairSpecularSettings.SelfShadowStrength);
320298
}
321-
322-
#if defined(DYNAMIC_CUBEMAPS)
323-
# if defined(SKYLIGHTING)
324-
float3 GetHairDynamicCubemapSpecularIrradiance(float2 uv, float2 ScreenUV, float3 T, float3 N, float3 VN, float3 V, float glossiness, float3 specLobePrim, float3 specLobeSec, sh2 skylighting)
325-
# else
326-
float3 GetHairDynamicCubemapSpecularIrradiance(float2 uv, float2 ScreenUV, float3 T, float3 N, float3 VN, float3 V, float glossiness, float3 specLobePrim, float3 specLobeSec)
327-
# endif
328-
{
329-
if (SharedData::hairSpecularSettings.HairMode == 1) {
330-
return 0;
331-
}
332-
float3 SpecularIrradiance = 0;
333-
float3 N1 = N;
334-
float3 N2 = N;
335-
336-
const float roughnessPrimary = SharedData::hairSpecularSettings.HairMode == 1 ? 1.0 : pow(abs(2.0 / (glossiness + 2.0)), 0.25);
337-
const float roughnessSecondary = pow(abs(2.0 / (glossiness * 0.5 + 2.0)), 0.25);
338-
339-
if (SharedData::hairSpecularSettings.EnableTangentShift) {
340-
const float shift = TexTangentShift.SampleLevel(SampColorSampler, uv, 0).x - 0.5;
341-
N1 = ShiftNormal(T, N, shift + (SharedData::hairSpecularSettings.HairMode == 1 ? 0.0 : SharedData::hairSpecularSettings.PrimaryTangentShift));
342-
N2 = ShiftNormal(T, N, shift + SharedData::hairSpecularSettings.SecondaryTangentShift);
343-
}
344-
345-
# if defined(SKYLIGHTING)
346-
SpecularIrradiance += DynamicCubemaps::GetDynamicCubemapSpecularIrradiance(ScreenUV, N1, VN, V, roughnessPrimary, skylighting) * specLobePrim;
347-
SpecularIrradiance += DynamicCubemaps::GetDynamicCubemapSpecularIrradiance(ScreenUV, N2, VN, V, roughnessSecondary, skylighting) * specLobeSec;
348-
# else
349-
SpecularIrradiance += DynamicCubemaps::GetDynamicCubemapSpecularIrradiance(ScreenUV, N1, VN, V, roughnessPrimary) * specLobePrim;
350-
SpecularIrradiance += DynamicCubemaps::GetDynamicCubemapSpecularIrradiance(ScreenUV, N2, VN, V, roughnessSecondary) * specLobeSec;
351-
# endif
352-
return SpecularIrradiance;
353-
}
354-
#endif
355299
}
356300
#endif //__HAIR_DEPENDENCY_HLSL__
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#ifndef LIGHTING_COMMON_HLSLI
2+
#define LIGHTING_COMMON_HLSLI
3+
4+
struct DirectContext
5+
{
6+
float3 worldNormal;
7+
float3 vertexNormal;
8+
float3 viewDir;
9+
float3 lightDir;
10+
float3 halfVector;
11+
float3 lightColor;
12+
#if defined(TRUE_PBR)
13+
float3 coatWorldNormal;
14+
float3 coatViewDir;
15+
float3 coatLightDir;
16+
float3 coatHalfVector;
17+
float3 coatLightColor;
18+
#elif defined(HAIR) && defined(CS_HAIR)
19+
float hairShadow;
20+
#endif
21+
};
22+
23+
struct IndirectContext
24+
{
25+
float3 worldNormal;
26+
float3 vertexNormal;
27+
float3 viewDir;
28+
};
29+
30+
struct DirectLightingOutput
31+
{
32+
float3 diffuse;
33+
float3 specular;
34+
float3 transmission;
35+
#if defined(TRUE_PBR)
36+
float3 coatDiffuse;
37+
#endif
38+
};
39+
40+
struct IndirectLobeWeights
41+
{
42+
float3 diffuse;
43+
float3 specular;
44+
};
45+
46+
#if defined(TRUE_PBR)
47+
# if defined(GLINT)
48+
# include "Common/Glints/Glints2023.hlsli"
49+
# else
50+
namespace Glints
51+
{
52+
typedef float GlintCachedVars;
53+
}
54+
# endif
55+
#endif
56+
57+
struct MaterialProperties
58+
{
59+
float3 BaseColor;
60+
#if !defined(TRUE_PBR)
61+
float Shininess;
62+
float Glossiness;
63+
float3 SpecularColor;
64+
# if (defined(RIM_LIGHTING) || defined(SOFT_LIGHTING) || defined(LOAD_SOFT_LIGHTING))
65+
float3 rimSoftLightColor;
66+
# endif
67+
# if defined(BACK_LIGHTING)
68+
float3 backLightColor;
69+
# endif
70+
float Roughness;
71+
float3 F0;
72+
#else
73+
float Roughness;
74+
float Metallic;
75+
float AO;
76+
float3 F0;
77+
float3 SubsurfaceColor;
78+
float Thickness;
79+
float3 CoatColor;
80+
float CoatStrength;
81+
float CoatRoughness;
82+
float3 CoatF0;
83+
float3 FuzzColor;
84+
float FuzzWeight;
85+
float GlintScreenSpaceScale;
86+
float GlintLogMicrofacetDensity;
87+
float GlintMicrofacetRoughness;
88+
float GlintDensityRandomization;
89+
Glints::GlintCachedVars GlintCache;
90+
float Noise;
91+
#endif
92+
};
93+
94+
float ShininessToRoughness(float shininess)
95+
{
96+
return pow(abs(2.0 / (shininess + 2.0)), 0.25);
97+
}
98+
99+
float3x3 ReconstructTBN(float3 worldPos, float3 worldNormal, float2 uv)
100+
{
101+
float3 dFdx = ddx(worldPos);
102+
float3 dFdy = ddy(worldPos);
103+
float2 dUVdx = ddx(uv);
104+
float2 dUVdy = ddy(uv);
105+
float3 tangent = normalize(dFdx * dUVdy.y - dFdy * dUVdx.y);
106+
float3 bitangent = normalize(dFdy * dUVdx.x - dFdx * dUVdy.x);
107+
tangent = normalize(tangent - worldNormal * dot(worldNormal, tangent));
108+
bitangent = normalize(bitangent - worldNormal * dot(worldNormal, bitangent));
109+
110+
return float3x3(tangent, bitangent, normalize(worldNormal));
111+
}
112+
#endif

0 commit comments

Comments
 (0)