summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x3ner.cginc13
-rwxr-xr-x3ner.shader2
-rwxr-xr-xbrdf.cginc12
-rwxr-xr-xlighting.cginc78
4 files changed, 103 insertions, 2 deletions
diff --git a/3ner.cginc b/3ner.cginc
index d7184a4..375aa87 100755
--- a/3ner.cginc
+++ b/3ner.cginc
@@ -324,6 +324,19 @@ float4 frag(v2f i, uint facing : SV_IsFrontFace
BrdfData bd;
float4 lit = brdf(i, pbr, light_data, bd);
+#if defined(VERTEXLIGHT_ON) && (defined(FORWARD_BASE_PASS) || defined(OUTLINES_PASS))
+ [loop]
+ for (uint light_index = 0; light_index < 4; ++light_index) {
+ [branch]
+ if (any(unity_LightColor[light_index].rgb > 0)) {
+ LightData vertex_light_data = light_data;
+ GetVertexLighting(i, pbr, light_index, vertex_light_data);
+ BrdfData vertex_bd;
+ lit.rgb += brdf(i, pbr, vertex_light_data, true, vertex_bd).rgb;
+ }
+ }
+#endif
+
return apply_debug_view(i, pbr, light_data, bd, lit);
}
diff --git a/3ner.shader b/3ner.shader
index 213eb72..dd63f1d 100755
--- a/3ner.shader
+++ b/3ner.shader
@@ -1439,6 +1439,7 @@ Shader "yum_food/3ner"
#pragma multi_compile_fullshadows
#pragma multi_compile_instancing
#pragma multi_compile_fog
+ #pragma multi_compile_fragment _ VERTEXLIGHT_ON
#pragma vertex vert
//ifex _Geometry_Enabled==0
#pragma geometry geom
@@ -1470,6 +1471,7 @@ Shader "yum_food/3ner"
#pragma multi_compile_fullshadows
#pragma multi_compile_instancing
#pragma multi_compile_fog
+ #pragma multi_compile_fragment _ VERTEXLIGHT_ON
#pragma vertex vert
//ifex _Geometry_Enabled==0
#pragma geometry geom
diff --git a/brdf.cginc b/brdf.cginc
index 22e0de9..93157e8 100755
--- a/brdf.cginc
+++ b/brdf.cginc
@@ -107,7 +107,7 @@ float G_Estevez(float roughness, float NoL, float NoV) {
return 1.0 / ((1.0 + lambda_l + lambda_v) * 4.0 * NoL * NoV);
}
-float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) {
+float4 brdf(v2f i, Pbr pbr, LightData data, bool direct_only, out BrdfData bd) {
bd = (BrdfData)0;
float3 specular = 0;
float3 diffuse = 0;
@@ -235,6 +235,8 @@ float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) {
// Indirect
#if !defined(FURNACE_TEST_DIRECT) && (defined(FORWARD_BASE_PASS) || defined(OUTLINES_PASS))
+ [branch]
+ if (!direct_only)
{
float3 remainder = 1.0f;
#if defined(_CLEARCOAT)
@@ -282,6 +284,8 @@ float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) {
#endif
#if defined(FORWARD_BASE_PASS)
+ [branch]
+ if (!direct_only)
{
[branch]
if (_UdonLightVolumeEnabled) {
@@ -306,7 +310,7 @@ float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) {
diffuse *= data.common.ao;
#if (defined(_EMISSIONS) || defined(_LETTER_GRID)) && defined(FORWARD_BASE_PASS)
- float3 emission = pbr.emission;
+ float3 emission = direct_only ? 0 : pbr.emission;
#else
float3 emission = 0;
#endif
@@ -315,4 +319,8 @@ float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) {
return float4(lit.rgb * lit.a, lit.a);
}
+float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) {
+ return brdf(i, pbr, data, false, bd);
+}
+
#endif // __BRDF_INC
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);