summaryrefslogtreecommitdiffstats
path: root/lighting.cginc
diff options
context:
space:
mode:
Diffstat (limited to 'lighting.cginc')
-rwxr-xr-xlighting.cginc78
1 files changed, 78 insertions, 0 deletions
diff --git a/lighting.cginc b/lighting.cginc
index 835613e..b3ac3fa 100755
--- a/lighting.cginc
+++ b/lighting.cginc
@@ -36,6 +36,84 @@ float4 getDirectLightColorIntensity() {
return float4(_LightColor0.xyz, _LightColor0.w);
}
+#if defined(VERTEXLIGHT_ON) && (defined(FORWARD_BASE_PASS) || defined(OUTLINES_PASS))
+// Mirrors can disable pixel lights, which makes Unity expose up to four point
+// lights through the vertex-light uniforms instead of drawing ForwardAdd.
+// Evaluate them per fragment so they use the same normals and BRDF as pixel
+// lights. Demoted spot lights are supplied by Unity as point lights here.
+void GetVertexLighting(v2f i, Pbr pbr, uint light_index, inout LightData data) {
+ float3 light_position = float3(
+ unity_4LightPosX0[light_index],
+ unity_4LightPosY0[light_index],
+ unity_4LightPosZ0[light_index]);
+ float3 to_light = light_position - i.worldPos;
+ float distance_squared = max(dot(to_light, to_light), 1e-6f);
+ float3 light_direction = to_light * rsqrt(distance_squared);
+
+ // Match Unity/Poiyomi's vertex-light range fade rather than allowing the
+ // reciprocal attenuation tail to illuminate indefinitely.
+ float attenuation_squared = unity_4LightAtten0[light_index];
+ float attenuation = rcp(1.0f + distance_squared * attenuation_squared);
+ float range_fade = saturate(1.0f - distance_squared * attenuation_squared / 25.0f);
+ attenuation = min(attenuation, range_fade * range_fade);
+
+ data.direct.dir = light_direction;
+ data.direct.H = normalize(data.common.V + light_direction);
+#if defined(_WRAPPED_LIGHTING)
+ data.direct.NoL = max(1e-4, wrapNoL(saturate(dot(pbr.normal, light_direction)), _Wrapped_Lighting_Amount));
+#else
+ data.direct.NoL = max(1e-4, dot(pbr.normal, light_direction));
+#endif
+ data.direct.NoH = max(1e-4, dot(pbr.normal, data.direct.H));
+ data.direct.LoH = max(1e-4, dot(light_direction, data.direct.H));
+#if defined(_CLEARCOAT)
+ data.direct.NoH_cc = max(1e-4, dot(pbr.cc_normal, data.direct.H));
+ data.direct.NoL_cc = max(1e-4, dot(pbr.cc_normal, light_direction));
+#endif
+ float direct_LoV = dot(light_direction, data.common.V);
+ data.direct.LoV = max(1e-4, direct_LoV);
+ data.direct.double_LoV = max(1e-4, 2.0f * direct_LoV * direct_LoV - 1.0f);
+ data.direct.color = unity_LightColor[light_index].rgb * attenuation;
+
+#if defined(_BRIGHTNESS_CLAMP)
+ float3 direct_hsv = RGBtoHSV(data.direct.color);
+ direct_hsv[2] = clamp(direct_hsv[2], _Brightness_Clamp_Min, _Brightness_Clamp_Max);
+ data.direct.color = HSVtoRGB(direct_hsv);
+#endif
+#if defined(_BRIGHTNESS_MULTIPLIER)
+ data.direct.color *= _Brightness_Multiplier;
+#endif
+
+#if defined(_GLITTER)
+ float2 glitter_uv = UV_SCOFF(i, _Glitter_Mask_ST, _Glitter_UV_Channel);
+ float2x2 glitter_uv_J = uv_ellipsoid(transpose(float2x2(ddx(glitter_uv), ddy(glitter_uv))));
+#if defined(_GLITTER_NORMAL_OVERRIDE)
+ float2 glitter_normal_uv = UV_SCOFF(i, _Glitter_Normal_Override_ST,
+ _Glitter_UV_Channel);
+ float3 glitter_normal = _Glitter_Normal_Override.Sample(
+ bilinear_clamp_s, glitter_normal_uv).xyz * 2 - 1;
+ glitter_normal = glitter_normal.xzy * float3(-1, 1, -1);
+ glitter_normal = UnityObjectToWorldNormal(glitter_normal);
+ float3x3 glitter_tbn = tbn_from_normal_tangent(glitter_normal, i.tangent);
+#else
+ float3x3 glitter_tbn = pbr.tbn;
+#endif
+ float3 direct_H_tangent = mul(data.direct.H, transpose(glitter_tbn));
+ float3 direct_micro_normal;
+#if defined(_GLITTER_BASE_ROUGHNESS_OVERRIDE)
+ float glitter_roughness = _Glitter_Base_Roughness_Override;
+#else
+ float glitter_roughness = pbr.roughness;
+#endif
+ data.glitter.direct_D = D_Kemppinen(
+ direct_H_tangent, glitter_roughness, _Glitter_Roughness,
+ _Glitter_Angular_Cells, glitter_uv, glitter_uv_J,
+ GLITTER_REFERENCE_N * GLITTER_POPULATION_SCALE, _Glitter_Amount,
+ _Glitter_Filter_Size, direct_micro_normal);
+#endif
+}
+#endif
+
float3 getIndirectSpecular(v2f i, float perceptual_roughness, float3 view_dir, float3 reflect_dir, float3 indirect_diffuse) {
UnityGIInput data = InitialiseUnityGIInput(i.worldPos, view_dir);
float3 env_refl = UnityGI_prefilteredRadiance(data, perceptual_roughness, reflect_dir);