Skip to content

Commit c298be6

Browse files
Merge pull request #328 from EvgeniiG/master
Fix diffuse transmission
2 parents c098be2 + 9c4db26 commit c298be6

2 files changed

Lines changed: 27 additions & 9 deletions

File tree

Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -781,14 +781,18 @@ void EvaluateBSDF_Directional( LightLoopContext lightLoopContext,
781781

782782
[branch] if (bsdfData.enableTransmission)
783783
{
784-
// Use the reversed normal from the front for the back of the object.
785-
illuminance = F_Transm_Schlick(bsdfData.fresnel0.x, saturate(-NdotL)); // Transmission is only valid for dielectric
784+
// Currently, we only model diffuse transmission. Specular transmission is not yet supported.
785+
// We assume that the back side of the object is a uniformly illuminated infinite plane
786+
// (we reuse the illumination) with the reversed normal of the current sample.
787+
// We apply wrapped lighting instead of the regular Lambertian diffuse
788+
// to compensate for these approximations.
789+
illuminance = ComputeWrappedDiffuseLighting(NdotL, SSS_WRAP_LIGHT);
786790

787791
// For low thickness, we can reuse the shadowing status for the back of the object.
788792
shadow = bsdfData.useThinObjectMode ? shadow : 1;
789793
illuminance *= shadow * cookie.a;
790794

791-
float3 backLight = (cookie.rgb * lightData.color) * (illuminance * lightData.diffuseScale);
795+
float3 backLight = (cookie.rgb * lightData.color) * (Lambert() * illuminance * lightData.diffuseScale);
792796
// TODO: multiplication by 'diffuseColor' and 'transmittance' is the same for each light.
793797
float3 transmittedLight = backLight * (bsdfData.diffuseColor * bsdfData.transmittance);
794798

@@ -885,14 +889,18 @@ void EvaluateBSDF_Punctual( LightLoopContext lightLoopContext,
885889

886890
[branch] if (bsdfData.enableTransmission)
887891
{
888-
// Use the reversed normal from the front for the back of the object.
889-
illuminance = F_Transm_Schlick(bsdfData.fresnel0.x , saturate(-NdotL)) * attenuation; // Transmission is only valid for dielectric
892+
// Currently, we only model diffuse transmission. Specular transmission is not yet supported.
893+
// We assume that the back side of the object is a uniformly illuminated infinite plane
894+
// (we reuse the illumination) with the reversed normal of the current sample.
895+
// We apply wrapped lighting instead of the regular Lambertian diffuse
896+
// to compensate for these approximations.
897+
illuminance = ComputeWrappedDiffuseLighting(NdotL, SSS_WRAP_LIGHT) * attenuation;
890898

891899
// For low thickness, we can reuse the shadowing status for the back of the object.
892900
shadow = bsdfData.useThinObjectMode ? shadow : 1;
893901
illuminance *= shadow * cookie.a;
894902

895-
float3 backLight = (cookie.rgb * lightData.color) * (illuminance * lightData.diffuseScale);
903+
float3 backLight = (cookie.rgb * lightData.color) * (Lambert() * illuminance * lightData.diffuseScale);
896904
// TODO: multiplication by 'diffuseColor' and 'transmittance' is the same for each light.
897905
float3 transmittedLight = backLight * (bsdfData.diffuseColor * bsdfData.transmittance);
898906

@@ -968,14 +976,18 @@ void EvaluateBSDF_Projector(LightLoopContext lightLoopContext,
968976

969977
[branch] if (bsdfData.enableTransmission)
970978
{
971-
// Use the reversed normal from the front for the back of the object.
972-
illuminance = F_Transm_Schlick(bsdfData.fresnel0.x, saturate(-NdotL)) * clipFactor; // Transmission is only valid for dielectric
979+
// Currently, we only model diffuse transmission. Specular transmission is not yet supported.
980+
// We assume that the back side of the object is a uniformly illuminated infinite plane
981+
// (we reuse the illumination) with the reversed normal of the current sample.
982+
// We apply wrapped lighting instead of the regular Lambertian diffuse
983+
// to compensate for these approximations.
984+
illuminance = ComputeWrappedDiffuseLighting(NdotL, SSS_WRAP_LIGHT) * clipFactor;
973985

974986
// For low thickness, we can reuse the shadowing status for the back of the object.
975987
shadow = bsdfData.useThinObjectMode ? shadow : 1;
976988
illuminance *= shadow * cookie.a;
977989

978-
float3 backLight = (cookie.rgb * lightData.color) * (illuminance * lightData.diffuseScale);
990+
float3 backLight = (cookie.rgb * lightData.color) * (Lambert() * illuminance * lightData.diffuseScale);
979991
// TODO: multiplication by 'diffuseColor' and 'transmittance' is the same for each light.
980992
float3 transmittedLight = backLight * (bsdfData.diffuseColor * bsdfData.transmittance);
981993

Assets/ScriptableRenderPipeline/ShaderLibrary/CommonMaterial.hlsl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ float3 ComputeTransmittance(float3 S, float3 volumeAlbedo, float thickness, floa
151151
return 0.25 * (expOneThird + 3 * expOneThird * expOneThird * expOneThird) * volumeAlbedo;
152152
}
153153

154+
// Ref: Steve McAuley - Energy-Conserving Wrapped Diffuse
155+
float ComputeWrappedDiffuseLighting(float NdotL, float w)
156+
{
157+
return saturate((-NdotL + w) / ((1 + w) * (1 + w)));
158+
}
159+
154160
// MACRO from Legacy Untiy
155161
// Transforms 2D UV by scale/bias property
156162
#define TRANSFORM_TEX(tex, name) ((tex.xy) * name##_ST.xy + name##_ST.zw)

0 commit comments

Comments
 (0)