diff options
| author | yum <yum.food.vr@gmail.com> | 2025-06-13 17:59:00 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-06-13 17:59:00 -0700 |
| commit | a9dbbfa1488a9ec3bd772fc9847888502f49a65e (patch) | |
| tree | 2930432ee795faff97b81c6261c2160a37125048 /yum_lighting.cginc | |
| parent | f639117b1f743ab2941667b32b190dd1e715d4a5 (diff) | |
Fix some filamented inconsistencies
Diffstat (limited to 'yum_lighting.cginc')
| -rw-r--r-- | yum_lighting.cginc | 626 |
1 files changed, 330 insertions, 296 deletions
diff --git a/yum_lighting.cginc b/yum_lighting.cginc index dabc148..d1cf779 100644 --- a/yum_lighting.cginc +++ b/yum_lighting.cginc @@ -1,296 +1,330 @@ -#ifndef __YUM_LIGHTING_INC
-#define __YUM_LIGHTING_INC
-
-#include "UnityCG.cginc"
-#include "AutoLight.cginc"
-#include "UnityPBSLighting.cginc"
-#include "UnityLightingCommon.cginc"
-
-#include "features.cginc"
-#include "LightVolumes.cginc"
-#include "poi.cginc"
-#include "yum_pbr.cginc"
-
-// fucking kill me
-#ifndef __LTCGI_INC
-#define __LTCGI_INC
-
-#include "features.cginc"
-
-#if defined(_LTCGI)
-struct ltcgi_acc {
- float3 diffuse;
- float3 specular;
-};
-
-#include "Third_Party/at.pimaker.ltcgi/Shaders/LTCGI_structs.cginc"
-
-void ltcgi_cb_diffuse(inout ltcgi_acc acc, in ltcgi_output output);
-void ltcgi_cb_specular(inout ltcgi_acc acc, in ltcgi_output output);
-
-#define LTCGI_V2_CUSTOM_INPUT ltcgi_acc
-#define LTCGI_V2_DIFFUSE_CALLBACK ltcgi_cb_diffuse
-#define LTCGI_V2_SPECULAR_CALLBACK ltcgi_cb_specular
-
-#include "Third_Party/at.pimaker.ltcgi/Shaders/LTCGI.cginc"
-void ltcgi_cb_diffuse(inout ltcgi_acc acc, in ltcgi_output output) {
- acc.diffuse += output.intensity * output.color * _LTCGI_DiffuseColor;
-}
-void ltcgi_cb_specular(inout ltcgi_acc acc, in ltcgi_output output) {
- acc.specular += output.intensity * output.color * _LTCGI_SpecularColor;
-}
-#endif // _LTCGI
-
-#endif // __LTCGI_INC
-
-struct YumLighting {
- float3 view_dir;
- float3 dir;
- float3 direct;
- float3 diffuse;
- float diffuse_luminance;
- float3 specular;
- float NoL;
-#if defined(_WRAPPED_LIGHTING)
- float NoL_wrapped_s; // specular
- float NoL_wrapped_d; // diffuse
-#endif
- float attenuation;
- float3 L00;
- float3 L01r;
- float3 L01g;
- float3 L01b;
-};
-
-float getShadowAttenuation(v2f i)
-{
- float attenuation;
- // This whole block is yoinked from AutoLight.cginc. I needed a way to
- // control shadow strength so I had to duplicate the code.
-#if defined(DIRECTIONAL_COOKIE)
- DECLARE_LIGHT_COORD(i, i.worldPos);
- float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos);
- attenuation = tex2D(_LightTexture0, lightCoord).w;
-#elif defined(POINT_COOKIE)
- DECLARE_LIGHT_COORD(i, i.worldPos);
- float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos);
- attenuation = tex2D(_LightTextureB0, dot(lightCoord, lightCoord).rr).r *
- texCUBE(_LightTexture0, lightCoord).w;
-#elif defined(DIRECTIONAL)
- float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos);
- attenuation = 1;
-#elif defined(SPOT)
- DECLARE_LIGHT_COORD(i, i.worldPos);
- float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos);
- attenuation = (lightCoord.z > 0) * UnitySpotCookie(lightCoord) *
- UnitySpotAttenuate(lightCoord.xyz);
-#elif defined(POINT)
- unityShadowCoord3 lightCoord =
- mul(unity_WorldToLight, unityShadowCoord4(i.worldPos, 1)).xyz;
- float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos);
- attenuation = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).r;
-#else
- float shadow = 1;
- attenuation = 1;
-#endif
- attenuation *= lerp(1, shadow, _Shadow_Strength);
- return attenuation;
-}
-
-float3 getDirectLightDirection(v2f i) {
-#if defined(POINT) || defined(POINT_COOKIE) || defined(SPOT)
- return normalize((_WorldSpaceLightPos0 - i.worldPos).xyz);
-#else
- return _WorldSpaceLightPos0;
-#endif
-}
-
-float GetLodRoughness(float roughness) {
- return roughness * (1.7 - 0.7 * roughness);
-}
-
-float3 getIndirectSpecular(v2f i, YumPbr pbr, float3 view_dir, float diffuse_luminance) {
- float roughness = GetLodRoughness(pbr.roughness_perceptual);
- float3 reflect_dir = reflect(-view_dir, pbr.normal);
-
- UnityGIInput data;
- data.worldPos = i.worldPos;
- data.worldViewDir = view_dir;
- data.probeHDR[0] = unity_SpecCube0_HDR;
- data.probeHDR[1] = unity_SpecCube1_HDR;
-#if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION)
- data.boxMin[0] = unity_SpecCube0_BoxMin; // .w holds lerp value for blending
-#endif
-#ifdef UNITY_SPECCUBE_BOX_PROJECTION
- data.boxMax[0] = unity_SpecCube0_BoxMax;
- data.probePosition[0] = unity_SpecCube0_ProbePosition;
- data.boxMax[1] = unity_SpecCube1_BoxMax;
- data.boxMin[1] = unity_SpecCube1_BoxMin;
- data.probePosition[1] = unity_SpecCube1_ProbePosition;
-#endif
-
- const float3 env_refl = UnityGI_prefilteredRadiance(data, roughness, reflect_dir);
-
-#if defined(_FALLBACK_CUBEMAP)
- // Check if there's no valid scene cubemap
- float3 canned_refl = env_refl;
- if (!SceneHasReflections() || _Fallback_Cubemap_Force) {
- // Set up data for fallback sampling similar to Unity's system
- half3 reflectVector = reflect(-view_dir, pbr.normal);
-
- #ifdef UNITY_SPECCUBE_BOX_PROJECTION
- reflectVector = BoxProjectedCubemapDirection(reflectVector, data.worldPos, /*probe_position=*/0, /*box_min=*/-1, /*box_max=*/1);
- #endif
-
- half mip = roughness * UNITY_SPECCUBE_LOD_STEPS;
- float4 envSample = UNITY_SAMPLE_TEXCUBE_LOD(_Fallback_Cubemap, reflectVector, mip);
- canned_refl = DecodeHDR(envSample, _Fallback_Cubemap_HDR) * _Fallback_Cubemap_Brightness * diffuse_luminance;
- }
-#endif
-
-#if defined(_FALLBACK_CUBEMAP_LIMIT_METALLIC)
- return lerp(env_refl, canned_refl, pbr.metallic);
-#elif defined(_FALLBACK_CUBEMAP)
- return canned_refl;
-#else
- return env_refl;
-#endif
-}
-
-float3 yumSH9(float4 n, float3 worldPos, inout YumLighting light) {
-#if defined(YUM_SH9_STANDARD)
- // Unity gives us the first three bands (L0-L2) of SH coefficients as follows:
- // unity_SHA*.w: L0 coefficients
- // unity_SHA*.xyz: L1 coefficients
- // unity_SHB*: first four of the L2 coefficients
- // unity_SHC: last L2 coefficient
-
- // Parse out coefficients into a simpler but less efficient format.
- float3 L00 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
- float3 L1_1 = float3(unity_SHAr.x, unity_SHAg.x, unity_SHAb.x);
- float3 L10 = float3(unity_SHAr.y, unity_SHAg.y, unity_SHAb.y);
- float3 L11 = float3(unity_SHAr.z, unity_SHAg.z, unity_SHAb.z);
- float3 L2_2 = float3(unity_SHBr.x, unity_SHBg.x, unity_SHBb.x);
- float3 L2_1 = float3(unity_SHBr.y, unity_SHBg.y, unity_SHBb.y);
- float3 L20 = float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z);
- float3 L21 = float3(unity_SHBr.w, unity_SHBg.w, unity_SHBb.w);
- float3 L22 = unity_SHC;
-
- // Equation 13 from "An Efficient Representation for Irradiance Environment
- // Maps" by Ramamoorthi and Hanrahan. Note that the order of some
- // coefficients is different, and normalization constants have been
- // premultiplied by Unity.
- float3 L0 = L00;
- float3 L1 = L1_1 * n.x + L10 * n.y + L11 * n.z;
- float3 L2 =
- L2_2 * n.x * n.y +
- L2_1 * n.y * n.z +
- L20 * n.z * n.z +
- L21 * n.x * n.z +
- L22 * (n.x * n.x - n.y * n.y);
-
- light.L00 = L00;
- light.L01r = unity_SHAr.xyz;
- light.L01g = unity_SHAg.xyz;
- light.L01b = unity_SHAb.xyz;
-
- return L0 + L1 + L2;
-#elif 1
- // Light volumes. We omit the L01 contribution since flat shading looks
- // better on avatars.
- LightVolumeSH(worldPos, light.L00, light.L01r, light.L01g, light.L01b);
- return LightVolumeEvaluate(n.xyz, light.L00,
- _UdonLightVolumeEnabled ? light.L01r : 0,
- _UdonLightVolumeEnabled ? light.L01g : 0,
- _UdonLightVolumeEnabled ? light.L01b : 0);
-#else
- // On non-photorealistic avatars, simply using the diffuse component looks
- // better. *shruge*
- float3 L00 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
-
- light.L00 = L00;
- light.L01r = unity_SHAr.xyz;
- light.L01g = unity_SHAg.xyz;
- light.L01b = unity_SHAb.xyz;
-
- return L00;
-#endif
-}
-
-float4 getIndirectDiffuse(v2f i, float4 vertexLightColor,
- inout YumLighting light) {
- float4 diffuse = vertexLightColor;
-#if defined(FORWARD_BASE_PASS)
-#if defined(LIGHTMAP_ON)
- diffuse.xyz = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uv01.zw));
-#else
- diffuse.xyz += max(0, yumSH9(float4(i.normal, 0), i.worldPos, light));
-#endif
-#endif
- return diffuse;
-}
-
-YumLighting GetYumLighting(v2f i, YumPbr pbr) {
- YumLighting light = (YumLighting) 0;
-
- // normalize has no visibile impact in test scene
- light.view_dir = -normalize(i.eyeVec.xyz);
-
- light.dir = getDirectLightDirection(i);
-
- light.direct = _LightColor0.rgb;
- // TODO filament's spherical harmonics look nicer than this.
- // See FilamentLightIndirect.cginc::UnityGI_Irradiance in filamented.
- light.diffuse = getIndirectDiffuse(i, /*vertexLightColor=*/0, light);
-#if defined(_MIN_BRIGHTNESS)
- light.diffuse = max(_Min_Brightness, light.diffuse);
-#endif
-
- light.diffuse_luminance = luminance(light.diffuse);
- light.specular = getIndirectSpecular(i, pbr, light.view_dir, light.diffuse_luminance);
-
-#if defined(_LTCGI)
- ltcgi_acc acc = (ltcgi_acc) 0;
- LTCGI_Contribution(
- acc,
- i.worldPos,
- pbr.normal,
- light.view_dir,
- pbr.roughness_perceptual,
- 0);
- light.diffuse += acc.diffuse * _LTCGI_Strength;
- light.specular += acc.specular * _LTCGI_Strength;
-#endif
-
-#if defined(_QUANTIZE_SPECULAR)
- float specular_luminance = luminance(light.specular);
- light.specular = light.specular * floor(specular_luminance * _Quantize_Specular_Steps) / _Quantize_Specular_Steps;
-#endif
-#if defined(_QUANTIZE_DIFFUSE)
- light.diffuse = light.diffuse * floor(light.diffuse_luminance * _Quantize_Diffuse_Steps) / _Quantize_Diffuse_Steps;
- light.diffuse_luminance = luminance(light.diffuse);
-#endif
-
-#if defined(_BRIGHTNESS_CONTROL)
- light.direct *= _Brightness_Multiplier;
- light.diffuse *= _Brightness_Multiplier;
- light.specular *= _Brightness_Multiplier;
-#endif
-
- light.NoL = dot(pbr.normal, light.dir);
-#if defined(_QUANTIZE_NOL)
- light.NoL = floor(light.NoL * _Quantize_NoL_Steps) / _Quantize_NoL_Steps;
-#endif
-#if defined(_WRAPPED_LIGHTING)
- light.NoL_wrapped_s = saturate(wrapNoL(light.NoL, _Wrap_NoL_Specular_Strength));
- light.NoL_wrapped_d = saturate(wrapNoL(light.NoL, _Wrap_NoL_Diffuse_Strength));
-#endif
- light.NoL = saturate(light.NoL);
-
- light.attenuation = getShadowAttenuation(i);
-
- return light;
-}
-
-#endif // __YUM_LIGHTING_INC
-
+#ifndef __YUM_LIGHTING_INC +#define __YUM_LIGHTING_INC + +#include "UnityCG.cginc" +#include "AutoLight.cginc" +#include "UnityPBSLighting.cginc" +#include "UnityLightingCommon.cginc" + +#include "features.cginc" +#include "LightVolumes.cginc" +#include "poi.cginc" +#include "yum_pbr.cginc" + +// fucking kill me +#ifndef __LTCGI_INC +#define __LTCGI_INC + +#include "features.cginc" + +#if defined(_LTCGI) +struct ltcgi_acc { + float3 diffuse; + float3 specular; +}; + +#include "Third_Party/at.pimaker.ltcgi/Shaders/LTCGI_structs.cginc" + +void ltcgi_cb_diffuse(inout ltcgi_acc acc, in ltcgi_output output); +void ltcgi_cb_specular(inout ltcgi_acc acc, in ltcgi_output output); + +#define LTCGI_V2_CUSTOM_INPUT ltcgi_acc +#define LTCGI_V2_DIFFUSE_CALLBACK ltcgi_cb_diffuse +#define LTCGI_V2_SPECULAR_CALLBACK ltcgi_cb_specular + +#include "Third_Party/at.pimaker.ltcgi/Shaders/LTCGI.cginc" +void ltcgi_cb_diffuse(inout ltcgi_acc acc, in ltcgi_output output) { + acc.diffuse += output.intensity * output.color * _LTCGI_DiffuseColor; +} +void ltcgi_cb_specular(inout ltcgi_acc acc, in ltcgi_output output) { + acc.specular += output.intensity * output.color * _LTCGI_SpecularColor; +} +#endif // _LTCGI + +#endif // __LTCGI_INC + +struct YumLighting { + float3 view_dir; + float3 dir; + float3 direct; + float3 diffuse; + float diffuse_luminance; + float3 specular; + float NoL; +#if defined(_WRAPPED_LIGHTING) + float NoL_wrapped_s; // specular + float NoL_wrapped_d; // diffuse +#endif + float attenuation; + float3 L00; + float3 L01r; + float3 L01g; + float3 L01b; + float occlusion; + Light derivedLight; +}; + +float getShadowAttenuation(v2f i) +{ + float attenuation; + // This whole block is yoinked from AutoLight.cginc. I needed a way to + // control shadow strength so I had to duplicate the code. +#if defined(DIRECTIONAL_COOKIE) + DECLARE_LIGHT_COORD(i, i.worldPos); + float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos); + attenuation = tex2D(_LightTexture0, lightCoord).w; +#elif defined(POINT_COOKIE) + DECLARE_LIGHT_COORD(i, i.worldPos); + float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos); + attenuation = tex2D(_LightTextureB0, dot(lightCoord, lightCoord).rr).r * + texCUBE(_LightTexture0, lightCoord).w; +#elif defined(DIRECTIONAL) + float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos); + attenuation = 1; +#elif defined(SPOT) + DECLARE_LIGHT_COORD(i, i.worldPos); + float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos); + attenuation = (lightCoord.z > 0) * UnitySpotCookie(lightCoord) * + UnitySpotAttenuate(lightCoord.xyz); +#elif defined(POINT) + unityShadowCoord3 lightCoord = + mul(unity_WorldToLight, unityShadowCoord4(i.worldPos, 1)).xyz; + float shadow = UNITY_SHADOW_ATTENUATION(i, i.worldPos); + attenuation = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).r; +#else + float shadow = 1; + attenuation = 1; +#endif + attenuation *= lerp(1, shadow, _Shadow_Strength); + return attenuation; +} + +float3 getDirectLightDirection(v2f i) { +#if defined(POINT) || defined(POINT_COOKIE) || defined(SPOT) + return normalize((_WorldSpaceLightPos0 - i.worldPos).xyz); +#else + return _WorldSpaceLightPos0; +#endif +} + +float GetLodRoughness(float roughness) { + return roughness * (1.7 - 0.7 * roughness); +} + +float3 getIndirectSpecular(v2f i, YumPbr pbr, float3 view_dir, float diffuse_luminance) { + float roughness = GetLodRoughness(pbr.roughness_perceptual); + float3 reflect_dir = reflect(-view_dir, pbr.normal); + + UnityGIInput data; + data.worldPos = i.worldPos; + data.worldViewDir = view_dir; + data.probeHDR[0] = unity_SpecCube0_HDR; + data.probeHDR[1] = unity_SpecCube1_HDR; +#if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION) + data.boxMin[0] = unity_SpecCube0_BoxMin; // .w holds lerp value for blending +#endif +#ifdef UNITY_SPECCUBE_BOX_PROJECTION + data.boxMax[0] = unity_SpecCube0_BoxMax; + data.probePosition[0] = unity_SpecCube0_ProbePosition; + data.boxMax[1] = unity_SpecCube1_BoxMax; + data.boxMin[1] = unity_SpecCube1_BoxMin; + data.probePosition[1] = unity_SpecCube1_ProbePosition; +#endif + + const float3 env_refl = UnityGI_prefilteredRadiance(data, roughness, reflect_dir); + +#if defined(_FALLBACK_CUBEMAP) + // Check if there's no valid scene cubemap + float3 canned_refl = env_refl; + if (!SceneHasReflections() || _Fallback_Cubemap_Force) { + // Set up data for fallback sampling similar to Unity's system + half3 reflectVector = reflect(-view_dir, pbr.normal); + + #ifdef UNITY_SPECCUBE_BOX_PROJECTION + reflectVector = BoxProjectedCubemapDirection(reflectVector, data.worldPos, /*probe_position=*/0, /*box_min=*/-1, /*box_max=*/1); + #endif + + half mip = roughness * UNITY_SPECCUBE_LOD_STEPS; + float4 envSample = UNITY_SAMPLE_TEXCUBE_LOD(_Fallback_Cubemap, reflectVector, mip); + canned_refl = DecodeHDR(envSample, _Fallback_Cubemap_HDR) * _Fallback_Cubemap_Brightness * diffuse_luminance; + } +#endif + +#if defined(_FALLBACK_CUBEMAP_LIMIT_METALLIC) + return lerp(env_refl, canned_refl, pbr.metallic); +#elif defined(_FALLBACK_CUBEMAP) + return canned_refl; +#else + return env_refl; +#endif +} + +float3 yumSH9(float4 n, float3 worldPos, inout YumLighting light) { +#if defined(YUM_SH9_STANDARD) + // Unity gives us the first three bands (L0-L2) of SH coefficients as follows: + // unity_SHA*.w: L0 coefficients + // unity_SHA*.xyz: L1 coefficients + // unity_SHB*: first four of the L2 coefficients + // unity_SHC: last L2 coefficient + + // Parse out coefficients into a simpler but less efficient format. + float3 L00 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w); + float3 L1_1 = float3(unity_SHAr.x, unity_SHAg.x, unity_SHAb.x); + float3 L10 = float3(unity_SHAr.y, unity_SHAg.y, unity_SHAb.y); + float3 L11 = float3(unity_SHAr.z, unity_SHAg.z, unity_SHAb.z); + float3 L2_2 = float3(unity_SHBr.x, unity_SHBg.x, unity_SHBb.x); + float3 L2_1 = float3(unity_SHBr.y, unity_SHBg.y, unity_SHBb.y); + float3 L20 = float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z); + float3 L21 = float3(unity_SHBr.w, unity_SHBg.w, unity_SHBb.w); + float3 L22 = unity_SHC; + + // Equation 13 from "An Efficient Representation for Irradiance Environment + // Maps" by Ramamoorthi and Hanrahan. Note that the order of some + // coefficients is different, and normalization constants have been + // premultiplied by Unity. + float3 L0 = L00; + float3 L1 = L1_1 * n.x + L10 * n.y + L11 * n.z; + float3 L2 = + L2_2 * n.x * n.y + + L2_1 * n.y * n.z + + L20 * n.z * n.z + + L21 * n.x * n.z + + L22 * (n.x * n.x - n.y * n.y); + + light.L00 = L00; + light.L01r = unity_SHAr.xyz; + light.L01g = unity_SHAg.xyz; + light.L01b = unity_SHAb.xyz; + + return L0 + L1 + L2; +#elif 1 + // Light volumes. We omit the L01 contribution since flat shading looks + // better on avatars. + LightVolumeSH(worldPos, light.L00, light.L01r, light.L01g, light.L01b); + return LightVolumeEvaluate(n.xyz, light.L00, + _UdonLightVolumeEnabled ? light.L01r : 0, + _UdonLightVolumeEnabled ? light.L01g : 0, + _UdonLightVolumeEnabled ? light.L01b : 0); +#else + // On non-photorealistic avatars, simply using the diffuse component looks + // better. *shruge* + float3 L00 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w); + + light.L00 = L00; + light.L01r = unity_SHAr.xyz; + light.L01g = unity_SHAg.xyz; + light.L01b = unity_SHAb.xyz; + + return L00; +#endif +} + +float3 SubtractMainLightWithRealtimeAttenuationFromLightmap(float3 lightmap, float attenuation, float4 bakedColorTex, float3 normalWorld) { + float3 shadowColor = unity_ShadowColor.rgb; + float shadowStrength = _LightShadowData.x; + + // Calculate estimated light contribution that should be shadowed + float ndotl = saturate(dot(normalWorld, _WorldSpaceLightPos0.xyz)); + float3 estimatedLightContributionMaskedByInverseOfShadow = ndotl * (1.0 - attenuation) * _LightColor0.rgb; + float3 subtractedLightmap = lightmap - estimatedLightContributionMaskedByInverseOfShadow; + + // Apply shadow color and strength + float3 realtimeShadow = max(subtractedLightmap, shadowColor); + realtimeShadow = lerp(realtimeShadow, lightmap, shadowStrength); + + // Pick darkest color + return min(lightmap, realtimeShadow); +} + +YumLighting GetYumLighting(v2f i, YumPbr pbr) { + YumLighting light = (YumLighting) 0; + + // normalize has no visibile impact in test scene + light.view_dir = -normalize(i.eyeVec.xyz); + + light.dir = getDirectLightDirection(i); + + light.direct = _LightColor0.rgb; + + // Calculate attenuation first, before diffuse lighting +#if defined(LIGHTMAP_ON) + light.attenuation = 1; +#else + light.attenuation = getShadowAttenuation(i); +#endif + + // Use filamented's comprehensive irradiance calculation + float occlusion; + Light derivedLight; + float3 tangentNormal = mul(pbr.normal, transpose(float3x3(i.tangent, i.binormal, i.normal))); + float3x3 tangentToWorld = float3x3(i.tangent, i.binormal, i.normal); + + light.diffuse = UnityGI_Irradiance( + pbr.normal, // worldNormal + i.worldPos, // worldPos + float4(i.uv01.zw, 0, 0), // lightmapUV (xy = uv0, zw = uv1) + float3(0,0,0), // ambient (will be calculated internally) + light.attenuation, // attenuation + tangentNormal, // tangentNormal + tangentToWorld, // tangentToWorld + #if defined(USING_BAKERY_VERTEXLMSH) + // You'll need to add these to your v2f if using Bakery vertex SH + i.bakeryVertexSH, + #elif defined(USING_BAKERY_VERTEXLMDIR) + // You'll need to add this to your v2f if using Bakery vertex directional + i.bakeryVertexDir, + #endif + occlusion, // out occlusion + derivedLight // out Light + ); + +#if defined(_MIN_BRIGHTNESS) + light.diffuse = max(_Min_Brightness, light.diffuse); +#endif + + light.diffuse_luminance = luminance(light.diffuse); + light.specular = getIndirectSpecular(i, pbr, light.view_dir, light.diffuse_luminance); + +#if defined(_LTCGI) + ltcgi_acc acc = (ltcgi_acc) 0; + LTCGI_Contribution( + acc, + i.worldPos, + pbr.normal, + light.view_dir, + pbr.roughness_perceptual, + 0); + light.diffuse += acc.diffuse * _LTCGI_Strength; + light.specular += acc.specular * _LTCGI_Strength; +#endif + +#if defined(_QUANTIZE_SPECULAR) + float specular_luminance = luminance(light.specular); + light.specular = light.specular * floor(specular_luminance * _Quantize_Specular_Steps) / _Quantize_Specular_Steps; +#endif +#if defined(_QUANTIZE_DIFFUSE) + light.diffuse = light.diffuse * floor(light.diffuse_luminance * _Quantize_Diffuse_Steps) / _Quantize_Diffuse_Steps; + light.diffuse_luminance = luminance(light.diffuse); +#endif + +#if defined(_BRIGHTNESS_CONTROL) + light.direct *= _Brightness_Multiplier; + light.diffuse *= _Brightness_Multiplier; + light.specular *= _Brightness_Multiplier; +#endif + + light.NoL = dot(pbr.normal, light.dir); +#if defined(_QUANTIZE_NOL) + light.NoL = floor(light.NoL * _Quantize_NoL_Steps) / _Quantize_NoL_Steps; +#endif +#if defined(_WRAPPED_LIGHTING) + light.NoL_wrapped_s = saturate(wrapNoL(light.NoL, _Wrap_NoL_Specular_Strength)); + light.NoL_wrapped_d = saturate(wrapNoL(light.NoL, _Wrap_NoL_Diffuse_Strength)); +#endif + light.NoL = saturate(light.NoL); + + return light; +} + +#endif // __YUM_LIGHTING_INC + |
