diff options
| author | yum <yum.food.vr@gmail.com> | 2025-06-30 20:37:47 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-06-30 20:37:47 -0700 |
| commit | 33a4a6d93f5f6c98cfc1bda95f9d3903310bc511 (patch) | |
| tree | 5c99afc2344ff09c9c68b20dac18a74e332d0a0f | |
| parent | 586f15513edd509f6ea7258eca52c1038024ac07 (diff) | |
add wrapped spherical harmonics
| -rw-r--r-- | yum_brdf.cginc | 9 | ||||
| -rw-r--r-- | yum_lighting.cginc | 50 |
2 files changed, 42 insertions, 17 deletions
diff --git a/yum_brdf.cginc b/yum_brdf.cginc index 364a183..daa6793 100644 --- a/yum_brdf.cginc +++ b/yum_brdf.cginc @@ -99,10 +99,9 @@ float4 YumBRDF(v2f i, const YumLighting light, YumPbr pbr) { #if defined(_MATERIAL_TYPE_CLOTH_SUBSURFACE) // Energy conservative wrap diffuse for subsurface scattering - float wrap_diffuse = saturate((NoL + 0.5) / 2.25); - Fd *= wrap_diffuse; + Fd *= NoL_wrapped_d; // Apply subsurface color - Fd *= saturate(_Cloth_Subsurface_Color + NoL); + Fd *= saturate(_Cloth_Subsurface_Color + NoL_wrapped_d); #endif // Cloth specular BRDF - multiply by PI to match Unity intensities @@ -110,9 +109,9 @@ float4 YumBRDF(v2f i, const YumLighting light, YumPbr pbr) { #if defined(_MATERIAL_TYPE_CLOTH_SUBSURFACE) // No need to multiply by NoL when using subsurface scattering - direct_cloth = (Fd + Fr * NoL) * light.direct * _Cloth_Direct_Multiplier; + direct_cloth = (Fd + Fr * NoL_wrapped_s) * light.direct * _Cloth_Direct_Multiplier; #else - direct_cloth = (Fd + Fr) * NoL * light.direct * _Cloth_Direct_Multiplier; + direct_cloth = (Fd + Fr) * NoL_wrapped_d * light.direct * _Cloth_Direct_Multiplier; #endif } #endif diff --git a/yum_lighting.cginc b/yum_lighting.cginc index 56fca90..88e8da7 100644 --- a/yum_lighting.cginc +++ b/yum_lighting.cginc @@ -208,24 +208,50 @@ float3 yumSH9(float4 n, float3 worldPos, inout YumLighting light) { L21 * n.x * n.z + L22 * (n.x * n.x - n.y * n.y); +#if defined(_WRAPPED_LIGHTING) + float wrap_term = _Wrap_NoL_Diffuse_Strength; + // Original coefficients: 1, 2/3, 1/4. + // Wrapped coefficients: 1, (2-w)/3, ((1-w)^2)/4. + + // Setting w=0, the l1 band is: + // (2-w)/3 = 2/3 + // 2-w = 2 + // 1-w/2 = 1 + float l1_wrap = 1.0f - wrap_term * 0.75f; + L1 *= l1_wrap; + + // The l2 band is: + // ((1-w)^2)/4 = 1/4 + // (1-w)^2 = 1 + float l2_wrap = (1.0f-wrap_term); + l2_wrap *= l2_wrap; + L2 *= l2_wrap; +#else + float l1_wrap = 1.0f; +#endif + light.L00 = L00; - light.L01r = unity_SHAr.xyz; - light.L01g = unity_SHAg.xyz; - light.L01b = unity_SHAb.xyz; + light.L01r = unity_SHAr.xyz * l1_wrap; + light.L01g = unity_SHAg.xyz * l1_wrap; + light.L01b = unity_SHAb.xyz * l1_wrap; return L0 + L1 + L2; #else LightVolumeSH(worldPos, light.L00, light.L01r, light.L01g, light.L01b); -#if defined(_SPHERICAL_HARMONICS_L1) - return LightVolumeEvaluate(n.xyz, light.L00, light.L01r, light.L01g, light.L01b); -#else - [branch] - if (_UdonLightVolumeEnabled) { - return LightVolumeEvaluate(n.xyz, light.L00, light.L01r, light.L01g, light.L01b); - } else { - return LightVolumeEvaluate(n.xyz, light.L00, 0, 0, 0); - } + +#if defined(_WRAPPED_LIGHTING) + float wrap_term = _Wrap_NoL_Diffuse_Strength; + // Hack. Not energy preserving but sorta close. I think this looks better at fully flat mode. + float l1_wrap = 1.0f - wrap_term * 0.75f; + light.L01r *= l1_wrap; + light.L01g *= l1_wrap; + light.L01b *= l1_wrap; #endif + + return light.L00 + float3( + dot(light.L01r, n.xyz), + dot(light.L01g, n.xyz), + dot(light.L01b, n.xyz)); #endif } |
