|
4 | 4 |
|
5 | 5 | // SurfaceData is define in Lit.cs which generate Lit.cs.hlsl |
6 | 6 | #include "Lit.cs.hlsl" |
| 7 | +#include "SubsurfaceScatteringProfile.cs.hlsl" |
7 | 8 |
|
8 | 9 | // In case we pack data uint16 buffer we need to change the output render target format to uint16 |
9 | 10 | // TODO: Is there a way to automate these output type based on the format declare in lit.cs ? |
@@ -52,16 +53,15 @@ TEXTURE2D_ARRAY(_LtcData); // We pack the 3 Ltc data inside a texture array |
52 | 53 | #define MIN_N_DOT_V 0.0001 // The minimum value of 'NdotV' |
53 | 54 |
|
54 | 55 | // SSS parameters |
55 | | -#define SSS_N_PROFILES 8 |
56 | | -#define SSS_LOW_THICKNESS 0.005 // 0.5 cm |
57 | 56 | #define CENTIMETERS_TO_METERS 0.01 |
58 | 57 |
|
59 | | -uint _EnableSSS; // Globally toggles subsurface scattering on/off |
60 | | -uint _TransmissionFlags; // 1 bit/profile; 0 = inf. thick, 1 = supports transmission |
61 | | -uint _TexturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter |
62 | | -float4 _TintColors[SSS_N_PROFILES]; // For transmission; alpha is unused |
63 | | -float _ThicknessRemaps[SSS_N_PROFILES][2]; // Remap: 0 = start, 1 = end - start |
64 | | -float4 _HalfRcpVariancesAndLerpWeights[SSS_N_PROFILES][2]; // 2x Gaussians per color channel, A is the the associated interpolation weight |
| 58 | +uint _EnableSSS; // Globally toggles subsurface scattering on/off |
| 59 | +uint _TransmissionFlags; // 1 bit/profile; 0 = inf. thick, 1 = supports transmission |
| 60 | +uint _TexturingModeFlags; // 1 bit/profile; 0 = PreAndPostScatter, 1 = PostScatter |
| 61 | +uint _ThinMaterialFlags; // 1 bit/profile; 1 = is thin material (allow specific optimization) |
| 62 | +float4 _TintColors[SSS_PROFILES_MAX]; // For transmission; alpha is unused |
| 63 | +float _ThicknessRemaps[SSS_PROFILES_MAX][2]; // Remap: 0 = start, 1 = end - start |
| 64 | +float4 _HalfRcpVariancesAndLerpWeights[SSS_PROFILES_MAX][2]; // 2x Gaussians per color channel, A is the the associated interpolation weight |
65 | 65 |
|
66 | 66 | //----------------------------------------------------------------------------- |
67 | 67 | // Helper functions/variable specific to this material |
@@ -167,6 +167,8 @@ void FillMaterialIdSSSData(float3 baseColor, int subsurfaceProfile, float subsur |
167 | 167 | _ThicknessRemaps[subsurfaceProfile][1] * thickness); |
168 | 168 |
|
169 | 169 | bsdfData.enableTransmission = IsBitSet(_TransmissionFlags, subsurfaceProfile); |
| 170 | + bsdfData.enableThinMaterial = IsBitSet(_ThinMaterialFlags, subsurfaceProfile); |
| 171 | + |
170 | 172 | if (bsdfData.enableTransmission) |
171 | 173 | { |
172 | 174 | bsdfData.transmittance = ComputeTransmittance( _HalfRcpVariancesAndLerpWeights[subsurfaceProfile][0].xyz, |
@@ -277,7 +279,7 @@ void EncodeIntoGBuffer( SurfaceData surfaceData, |
277 | 279 | } |
278 | 280 | else if (surfaceData.materialId == MATERIALID_LIT_SSS) |
279 | 281 | { |
280 | | - outGBuffer2 = float4(surfaceData.subsurfaceRadius, surfaceData.thickness, 0.0, surfaceData.subsurfaceProfile * rcp(SSS_N_PROFILES - 1)); |
| 282 | + outGBuffer2 = float4(surfaceData.subsurfaceRadius, surfaceData.thickness, 0.0, surfaceData.subsurfaceProfile * rcp(SSS_PROFILES_MAX - 1)); |
281 | 283 | } |
282 | 284 | else if (surfaceData.materialId == MATERIALID_LIT_SPECULAR) |
283 | 285 | { |
@@ -408,7 +410,7 @@ void DecodeFromGBuffer( |
408 | 410 | } |
409 | 411 | else if (supportsSSS && bsdfData.materialId == MATERIALID_LIT_SSS) |
410 | 412 | { |
411 | | - int subsurfaceProfile = (SSS_N_PROFILES - 0.9) * inGBuffer2.a; |
| 413 | + int subsurfaceProfile = (SSS_PROFILES_MAX - 0.9) * inGBuffer2.a; |
412 | 414 | float subsurfaceRadius = inGBuffer2.r; |
413 | 415 | float thickness = inGBuffer2.g; |
414 | 416 | FillMaterialIdSSSData(baseColor, subsurfaceProfile, subsurfaceRadius, thickness, bsdfData); |
@@ -721,7 +723,7 @@ void EvaluateBSDF_Directional( LightLoopContext lightLoopContext, |
721 | 723 |
|
722 | 724 | [branch] if (lightData.shadowIndex >= 0) |
723 | 725 | { |
724 | | - float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS); |
| 726 | + shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS); |
725 | 727 | illuminance *= shadow; |
726 | 728 | } |
727 | 729 |
|
@@ -769,8 +771,8 @@ void EvaluateBSDF_Directional( LightLoopContext lightLoopContext, |
769 | 771 | const float w = 0.15; |
770 | 772 | float illuminance = saturate((dot(-bsdfData.normalWS, L) + w) / ((1.0 + w) * (1.0 + w))); |
771 | 773 |
|
772 | | - // For low thickness, we can reuse the shadowing status for the back of the object. |
773 | | - shadow = (bsdfData.thickness <= SSS_LOW_THICKNESS) ? shadow : 1; |
| 774 | + // For thin material we can reuse the shadowing status for the back of the object. |
| 775 | + shadow = bsdfData.enableThinMaterial ? shadow : 1; |
774 | 776 | illuminance *= shadow * cookie.a; |
775 | 777 |
|
776 | 778 | // The difference between the Disney Diffuse and the Lambertian BRDF for transmission is negligible. |
@@ -824,7 +826,7 @@ void EvaluateBSDF_Punctual( LightLoopContext lightLoopContext, |
824 | 826 | [branch] if (lightData.shadowIndex >= 0) |
825 | 827 | { |
826 | 828 | float3 offset = float3(0.0, 0.0, 0.0); // GetShadowPosOffset(nDotL, normal); |
827 | | - float shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS); |
| 829 | + shadow = GetPunctualShadowAttenuation(lightLoopContext.shadowContext, positionWS + offset, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS); |
828 | 830 | shadow = lerp(1.0, shadow, lightData.shadowDimmer); |
829 | 831 |
|
830 | 832 | illuminance *= shadow; |
@@ -876,8 +878,8 @@ void EvaluateBSDF_Punctual( LightLoopContext lightLoopContext, |
876 | 878 | float illuminance = saturate((dot(-bsdfData.normalWS, L) + w) / ((1.0 + w) * (1.0 + w))); |
877 | 879 | illuminance *= attenuation; |
878 | 880 |
|
879 | | - // For low thickness, we can reuse the shadowing status for the back of the object. |
880 | | - shadow = (bsdfData.thickness <= SSS_LOW_THICKNESS) ? shadow : 1; |
| 881 | + // For thin material we can reuse the shadowing status for the back of the object. |
| 882 | + shadow = bsdfData.enableThinMaterial ? shadow : 1; |
881 | 883 | illuminance *= shadow * cookie.a; |
882 | 884 |
|
883 | 885 | // The difference between the Disney Diffuse and the Lambertian BRDF for transmission is negligible. |
@@ -932,7 +934,7 @@ void EvaluateBSDF_Projector(LightLoopContext lightLoopContext, |
932 | 934 |
|
933 | 935 | [branch] if (lightData.shadowIndex >= 0) |
934 | 936 | { |
935 | | - float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS); |
| 937 | + shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, bsdfData.normalWS, lightData.shadowIndex, L, posInput.unPositionSS); |
936 | 938 | illuminance *= shadow; |
937 | 939 | } |
938 | 940 |
|
@@ -962,8 +964,8 @@ void EvaluateBSDF_Projector(LightLoopContext lightLoopContext, |
962 | 964 | float illuminance = saturate((dot(-bsdfData.normalWS, L) + w) / ((1.0 + w) * (1.0 + w))); |
963 | 965 | illuminance *= clipFactor; |
964 | 966 |
|
965 | | - // For low thickness, we can reuse the shadowing status for the back of the object. |
966 | | - shadow = (bsdfData.thickness <= SSS_LOW_THICKNESS) ? shadow : 1; |
| 967 | + // For thin material we can reuse the shadowing status for the back of the object. |
| 968 | + shadow = bsdfData.enableThinMaterial ? shadow : 1; |
967 | 969 | illuminance *= shadow * cookie.a; |
968 | 970 |
|
969 | 971 | // The difference between the Disney Diffuse and the Lambertian BRDF for transmission is negligible. |
|
0 commit comments