summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2024-12-17 16:57:27 -0800
committeryum <yum.food.vr@gmail.com>2024-12-17 16:57:27 -0800
commitbc1a80b614afa8bf6f7d601f0caa3eba33320201 (patch)
tree22e7ddcc51f342e27976d2ca0929925a7dd28540
parent07a94ee97d02aa31b428cbc1f67dc7f8ae58a403 (diff)
Vertex lighting is now wrapped
This is unconditional (for now). In VRChat, anything other than fully wrapped vertex lighting usually looks bad. Also add direct lighting to clearcoat.
-rw-r--r--pbr.cginc34
-rw-r--r--tooner.shader2
-rw-r--r--tooner_lighting.cginc46
3 files changed, 73 insertions, 9 deletions
diff --git a/pbr.cginc b/pbr.cginc
index c5a6c33..d65f981 100644
--- a/pbr.cginc
+++ b/pbr.cginc
@@ -402,6 +402,8 @@ float4 getLitColor(
}
cc_mask *= cc_mask2_tmp;
#endif
+ // Diffuse specular
+ const float cc_roughness = max(1E-4, _Clearcoat_Roughness);
{
// TODO fold this into the full BRDF and apply the brightness corrections
// described in the filament whitepaper:
@@ -411,15 +413,37 @@ float4 getLitColor(
indirect_light.specular = getIndirectSpecular(i, view_dir, normal, smoothness,
metallic, worldPos, uv);
+ const float3 l = reflect(-view_dir, normal);
+ const float3 h = normalize(l + view_dir);
+ const float NoH = dot(normal, h);
+ const float LoH = dot(l, h);
+
+ float Fc;
+ float cc_term = FilamentClearcoat(
+ cc_roughness,
+ _Clearcoat_Strength,
+ NoH,
+ LoH,
+ h,
+ Fc);
+ pbr.rgb += cc_term * indirect_light.specular * cc_mask;
+ }
+ // Direct
+ {
+ const float3 l = direct_light.dir;
+ const float3 h = normalize(l + view_dir);
+ const float NoH = dot(normal, h);
+ const float LoH = dot(direct_light.dir, h);
+
float Fc;
float cc_term = FilamentClearcoat(
- _Clearcoat_Roughness,
+ cc_roughness,
_Clearcoat_Strength,
- 1,
- dot(view_dir, normal),
- normal,
+ NoH,
+ LoH,
+ h,
Fc);
- pbr.rgb += cc_term * indirect_light.specular;
+ pbr.rgb += cc_term * direct_light.color * cc_mask;
}
#endif
diff --git a/tooner.shader b/tooner.shader
index 2598770..275cce9 100644
--- a/tooner.shader
+++ b/tooner.shader
@@ -1018,7 +1018,6 @@ Shader "yum_food/tooner"
#include "tooner_lighting.cginc"
ENDCG
}
- /*
Pass {
Tags {
"RenderType"="Opaque"
@@ -1099,7 +1098,6 @@ Shader "yum_food/tooner"
#include "mochie_shadow_caster.cginc"
ENDCG
}
- */
}
CustomEditor "ToonerGUI"
}
diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc
index e976132..e5bcd13 100644
--- a/tooner_lighting.cginc
+++ b/tooner_lighting.cginc
@@ -28,6 +28,47 @@
#ifndef TOONER_LIGHTING
#define TOONER_LIGHTING
+float3 Shade4PointLightsWrapped(
+ float4 lightPosX, float4 lightPosY, float4 lightPosZ,
+ float3 lightColor0, float3 lightColor1, float3 lightColor2, float3 lightColor3,
+ float4 lightAttenSq,
+ float3 pos, float3 normal,
+ float wrapFactor)
+{
+ // Compute the difference between the vertex position and light positions
+ float4 toLightX = lightPosX - pos.x;
+ float4 toLightY = lightPosY - pos.y;
+ float4 toLightZ = lightPosZ - pos.z;
+
+ float4 lengthSq = 0;
+ lengthSq += toLightX * toLightX;
+ lengthSq += toLightY * toLightY;
+ lengthSq += toLightZ * toLightZ;
+
+ float4 ndotl = 0;
+ ndotl += toLightX * normal.x;
+ ndotl += toLightY * normal.y;
+ ndotl += toLightZ * normal.z;
+
+ // Apply wrapped lighting correction
+ // https://www.iro.umontreal.ca/~derek/files/jgt_wrap_final.pdf
+ //float4 wrapped = (ndotl + 1) * (ndotl + 1) * .25;
+ float4 wrapped = pow(max(1E-4, (ndotl + wrapFactor) / (1 + wrapFactor)), 1 + wrapFactor);
+ //float4 wrapped = pow((ndotl + 1) / (2), 2);
+ float4 corr = rsqrt(lengthSq);
+ ndotl = max(0, wrapped) * corr;
+
+ // Compute attenuation
+ float4 atten = 1.0 / (1.0 + lengthSq * lightAttenSq);
+ float4 diff = ndotl * atten;
+
+ // Compute final color
+ return diff.x * lightColor0 +
+ diff.y * lightColor1 +
+ diff.z * lightColor2 +
+ diff.w * lightColor3;
+}
+
void getVertexLightColor(inout v2f i)
{
#if defined(VERTEXLIGHT_ON)
@@ -37,13 +78,14 @@ void getVertexLightColor(inout v2f i)
float3 flat_normal = normalize(
(1.0 / _Flatten_Mesh_Normals_Str) * i.normal +
_Flatten_Mesh_Normals_Str * view_dir);
- i.vertexLightColor = Shade4PointLights(
+ i.vertexLightColor = Shade4PointLightsWrapped(
unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
unity_LightColor[0].rgb,
unity_LightColor[1].rgb,
unity_LightColor[2].rgb,
unity_LightColor[3].rgb,
- unity_4LightAtten0, i.worldPos, flat ? flat_normal : i.normal
+ unity_4LightAtten0, i.worldPos, flat ? flat_normal : i.normal,
+ 1
);
#endif
}