@@ -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__
0 commit comments