diff options
| author | yum <yum.food.vr@gmail.com> | 2024-12-17 16:57:27 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2024-12-17 16:57:27 -0800 |
| commit | bc1a80b614afa8bf6f7d601f0caa3eba33320201 (patch) | |
| tree | 22e7ddcc51f342e27976d2ca0929925a7dd28540 | |
| parent | 07a94ee97d02aa31b428cbc1f67dc7f8ae58a403 (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.cginc | 34 | ||||
| -rw-r--r-- | tooner.shader | 2 | ||||
| -rw-r--r-- | tooner_lighting.cginc | 46 |
3 files changed, 73 insertions, 9 deletions
@@ -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 } |
