summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-02-28 15:17:43 -0800
committeryum <yum.food.vr@gmail.com>2025-02-28 15:17:43 -0800
commiteb1529d4401cc4d385ef8bc806a186890999fed6 (patch)
treef73f77b9f6b2b676f80d3071c591b53985655018
parent646482b01a552fddfff33e31aeb9275644d08336 (diff)
add basic clearcoat lobe
-rw-r--r--2ner.shader8
-rw-r--r--features.cginc4
-rw-r--r--filamented.cginc3
-rw-r--r--globals.cginc5
-rw-r--r--yum_brdf.cginc59
5 files changed, 77 insertions, 2 deletions
diff --git a/2ner.shader b/2ner.shader
index e02cef6..8bf7934 100644
--- a/2ner.shader
+++ b/2ner.shader
@@ -81,6 +81,14 @@ Shader "yum_food/2ner"
[HideInInspector] m_end_Metallic("Metallics", Float) = 0
//endex
+ //ifex _Clearcoat_Enabled==0
+ [HideInInspector] m_start_Clearcoat("Clearcoat", Float) = 0
+ [ThryToggle(_CLEARCOAT)]_Clearcoat_Enabled("Enable", Float) = 0
+ _Clearcoat_Strength("Strength", Range(0, 1)) = 1
+ _Clearcoat_Roughness("Roughness", Range(0.089, 1)) = 0.089
+ [HideInInspector] m_end_Clearcoat("Clearcoat", Float) = 0
+ //endex
+
[HideInInspector] m_gimmicks("Gimmicks", Float) = 0
//ifex _Outlines_Enabled==0
[HideInInspector] m_start_Outlines("Outlines", Float) = 0
diff --git a/features.cginc b/features.cginc
index 3a18b8b..64c0480 100644
--- a/features.cginc
+++ b/features.cginc
@@ -37,6 +37,10 @@
#pragma shader_feature_local _QUANTIZE_SPECULAR
//endex
+//ifex _Clearcoat_Enabled==0
+#pragma shader_feature_local _CLEARCOAT
+//endex
+
//ifex _Metallics_Enabled==0
#pragma shader_feature_local _METALLICS
//endex
diff --git a/filamented.cginc b/filamented.cginc
index 9edfca5..fac3fef 100644
--- a/filamented.cginc
+++ b/filamented.cginc
@@ -241,7 +241,7 @@ float3 PrefilteredDFG_LUT(float lod, float NoV) {
return UNITY_SAMPLE_TEX2D(_DFG, float2(NoV, lod));
}
-float3 specularDFG(const float3 dfg, const float f0) {
+float3 specularDFG(const float3 dfg, const float3 f0) {
return lerp(dfg.xxx, dfg.yyy, f0);
}
@@ -355,7 +355,6 @@ inline half3 UnityGI_prefilteredRadiance(const UnityGIInput data,
glossIn.reflUVW = r;
#ifdef UNITY_SPECCUBE_BOX_PROJECTION
- // we will tweak reflUVW in glossIn directly (as we pass it to Unity_GlossyEnvironment twice for probe0 and pr obe1), so keep original to pass into BoxProjectedCubemapDirection
half3 originalReflUVW = glossIn.reflUVW;
glossIn.reflUVW = BoxProjectedCubemapDirection(originalReflUVW,
data.worldPos, data.probePosition[0], data.boxMin[0], data.boxMax[0]);
diff --git a/globals.cginc b/globals.cginc
index 043c1a9..cfde8a1 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -81,6 +81,11 @@ sampler2D _MetallicGlossMap;
float4 _MetallicGlossMap_ST;
#endif
+#if defined(_CLEARCOAT)
+float _Clearcoat_Strength;
+float _Clearcoat_Roughness;
+#endif
+
#if defined(OUTLINE_PASS)
float _Outlines_Enabled_Dynamic;
float4 _Outline_Color;
diff --git a/yum_brdf.cginc b/yum_brdf.cginc
index 52bc495..ab1730b 100644
--- a/yum_brdf.cginc
+++ b/yum_brdf.cginc
@@ -44,6 +44,22 @@ float3 specularLobe(YumPbr pbr, float f0,
return (D * V) * F * PI;
}
+#if defined(_CLEARCOAT)
+// Add a clearcoat specular lobe function
+float3 clearcoatLobe(float roughness, float f0,
+ float3 h, float LoH, float NoH_mesh, float NoV_mesh, float NoL_mesh)
+{
+ const float F = F_Schlick(f0, LoH);
+
+ // Normal distribution function with clearcoat roughness
+ float D = D_GGX(roughness, NoH_mesh, h);
+ // Geometric shadowing
+ float V = V_SmithGGXCorrelated_Fast(roughness, NoV_mesh, NoL_mesh);
+
+ return (D * V) * F * PI;
+}
+#endif // _CLEARCOAT
+
float4 YumBRDF(v2f i, const YumLighting light, YumPbr pbr) {
const float3 h = normalize(light.view_dir + light.dir);
const float LoH = saturate(dot(light.dir, h));
@@ -73,13 +89,49 @@ float4 YumBRDF(v2f i, const YumLighting light, YumPbr pbr) {
const float3 E = specularDFG(dfg, f0);
const float3 energy_compensation = energyCompensation(dfg, f0);
+#if defined(_CLEARCOAT)
+ // Clearcoat parameters
+ const float clearcoat_strength = _Clearcoat_Strength;
+ const float clearcoat_roughness = max(0.089, _Clearcoat_Roughness);
+ const float clearcoat_perceptual_roughness = sqrt(clearcoat_roughness);
+
+ // IoR of 1.5 -> reflectance of 0.04
+ const float clearcoat_f0 = 0.04;
+
+ // Use cc normal for clearcoat instead of detail normal
+ const float3 cc_normal = i.normal;
+ const float NoV_cc = max(1E-4, dot(cc_normal, light.view_dir));
+ const float NoH_cc = saturate(dot(cc_normal, h));
+ const float NoL_cc = saturate(dot(cc_normal, light.dir));
+#if defined(_WRAPPED_LIGHTING)
+ const float NoL_cc_wrapped = saturate((NoL_cc + light.wrapped) / (1.0 + light.wrapped));
+#else
+ const float NoL_cc_wrapped = NoL_cc;
+#endif
+
+ // Calculate clearcoat DFG terms with cc normal
+ const float3 clearcoat_dfg = PrefilteredDFG_LUT(clearcoat_perceptual_roughness, NoV_cc);
+ const float clearcoat_E = specularDFG(clearcoat_dfg, clearcoat_f0);
+ const float clearcoat_energy_compensation = energyCompensation(clearcoat_dfg, clearcoat_f0);
+#endif // _CLEARCOAT
+
float3 direct;
{
+ // Base layer
float3 Fd = diffuseLobe(pbr.albedo, pbr.roughness_perceptual, LoH, NoL,
NoV, f90);
Fd *= (1.0 - pbr.metallic) * light.attenuation;
float3 Fr = specularLobe(pbr, f0, h, LoH, NoH, NoV, NoL_wrapped_s);
+
+#if defined(_CLEARCOAT)
+ float Fcr = clearcoatLobe(clearcoat_roughness, clearcoat_f0, h, LoH, NoH_cc, NoV_cc, NoL_cc_wrapped);
+ Fcr *= clearcoat_strength * clearcoat_energy_compensation;
+ float clearcoat_factor = 1.0 - clearcoat_strength * F_Schlick(clearcoat_f0, NoV_cc);
+ float3 color = (Fd * NoL_wrapped_d + Fr * energy_compensation * NoL_wrapped_s) * clearcoat_factor +
+ Fcr * NoL_cc_wrapped;
+#else
float3 color = Fd * NoL_wrapped_d + Fr * energy_compensation * NoL_wrapped_s;
+#endif // _CLEARCOAT
direct = color * light.direct;
}
@@ -88,7 +140,14 @@ float4 YumBRDF(v2f i, const YumLighting light, YumPbr pbr) {
{
float3 Fr = E * light.specular * energy_compensation;
float3 Fd = pbr.albedo * light.diffuse * (1.0 - E) * (1.0 - pbr.metallic) * pbr.ao;
+
+#if defined(_CLEARCOAT)
+ float Fcr = clearcoat_E * light.specular * clearcoat_energy_compensation * clearcoat_strength;
+ float clearcoat_factor = 1.0 - clearcoat_strength * F_Schlick(clearcoat_f0, NoV_cc);
+ indirect = (Fr + Fd) * clearcoat_factor + Fcr;
+#else
indirect = Fr + Fd;
+#endif // _CLEARCOAT
}
return float4(direct + indirect, pbr.albedo.a);