diff options
| author | yum <yum.food.vr@gmail.com> | 2025-08-07 19:33:02 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-08-07 19:33:02 -0700 |
| commit | 9393f117a139976b19adf9f5201dfc7023fb3c04 (patch) | |
| tree | ead7a6a29507ccca4b456a5123742dcc05ccb715 | |
| parent | 8c6e9be61b2a7b1c5b9e5b61252090a4e2432ce2 (diff) | |
add clearcoat
| -rw-r--r-- | 3ner.shader | 30 | ||||
| -rw-r--r-- | brdf.cginc | 32 | ||||
| -rw-r--r-- | features.cginc | 4 | ||||
| -rw-r--r-- | globals.cginc | 4 | ||||
| -rw-r--r-- | lighting.cginc | 36 | ||||
| -rw-r--r-- | pbr.cginc | 13 |
6 files changed, 98 insertions, 21 deletions
diff --git a/3ner.shader b/3ner.shader index 7b6fbac..1058d59 100644 --- a/3ner.shader +++ b/3ner.shader @@ -67,14 +67,22 @@ Shader "yum_food/3ner" [HideInInspector] m_end_Tessellation("Tessellation", Float) = 0 //endex - [HideInInspector] m_start_Rendering_Options("Rendering Options", Float) = 0 - [Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull", Float) = 2 - [Enum(UnityEngine.Rendering.CompareFunction)] _ZTest("ZTest", Float) = 4 - [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Source Blend", Float) = 1 - [Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Destination Blend", Float) = 0 - [Enum(Off, 0, On, 1)] _ZWrite("ZWrite", Int) = 1 + [HideInInspector] m_start_BRDF("BRDF", Float) = 0 + _BRDF_Specular_Min_Denom("Specular minimum denominator", Float) = 0.000001 + _Specular_AA_Variance("Specular AA Variance", Float) = 0.15 + _Specular_AA_Threshold("Specular AA Threshold", Float) = 0.25 + + //ifex _Clearcoat_Enabled==0 + [HideInInspector] m_start_Clearcoat("Clearcoat", Float) = 0 + [ThryToggle(_CLEARCOAT)] _Clearcoat_Enabled("Enable", Float) = 0 + _Clearcoat_Strength("Strength", Range(0, 1)) = 0 + _Clearcoat_Roughness("Roughness", Range(0, 1)) = 0 + [HideInInspector] m_end_Clearcoat("Clearcoat", Float) = 0 + //endex + + [HideInInspector] m_end_BRDF("BRDF", Float) = 0 [HideInInspector] m_start_blending ("Blending--{button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/rendering/blending},hover:Documentation}}", Float) = 0 [DoNotAnimate][Enum(Thry.BlendOp)]_BlendOp ("RGB Blend Op", Int) = 0 @@ -95,11 +103,11 @@ Shader "yum_food/3ner" [DoNotAnimate][HideInInspector] m_end_alphaBlending ("Advanced Alpha Blending", Float) = 0 [HideInInspector] m_end_blending ("Blending", Float) = 0 - [HideInInspector] m_start_BRDF("BRDF", Float) = 0 - _BRDF_Specular_Min_Denom("Specular minimum denominator", Float) = 0.000001 - _Specular_AA_Variance("Specular AA Variance", Float) = 0.15 - _Specular_AA_Threshold("Specular AA Threshold", Float) = 0.25 - [HideInInspector] m_end_BRDF("BRDF", Float) = 0 + [Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull", Float) = 2 + [Enum(UnityEngine.Rendering.CompareFunction)] _ZTest("ZTest", Float) = 4 + [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Source Blend", Float) = 1 + [Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Destination Blend", Float) = 0 + [Enum(Off, 0, On, 1)] _ZWrite("ZWrite", Int) = 1 [HideInInspector] m_end_Rendering_Options("Rendering Options", Float) = 0 } @@ -76,17 +76,31 @@ float4 brdf(Pbr pbr, LightData data) { // Direct if (true) { + float remainder = 1.0f; + +#if defined(_CLEARCOAT) + float cc_f0 = 0.04f; + float Fc = F_Schlick(data.direct.LoH, cc_f0, f90); + float Dc = D_GGX(pbr.cc_roughness, data.direct.NoH_cc); + float Gc = V_GGXSmith(pbr.cc_roughness, data.direct.NoL_cc, data.common.NoV_cc); + float FDGc = Fc * Dc * Gc; + float3 direct_specular_cc = FDGc * data.direct.color * data.direct.NoL_cc * pbr.cc_strength; + direct_specular_cc = max(0, direct_specular_cc); + specular += direct_specular_cc; + remainder -= Fc; +#endif + float F = F_Schlick(data.direct.LoH, f0, f90); float D = D_GGX(pbr.roughness, data.direct.NoH); float G = V_GGXSmith(pbr.roughness, data.direct.NoL, data.common.NoV); float FDG = F * D * G; - float3 direct_specular = FDG * data.direct.color * data.direct.NoL * lerp(1.0f, pbr.albedo.xyz, pbr.metallic); + float3 direct_specular = FDG * remainder * data.direct.color * data.direct.NoL * lerp(1.0f, pbr.albedo.xyz, pbr.metallic); direct_specular = max(0, direct_specular); specular += direct_specular; + remainder -= F; - float3 remainder = (1.0f - direct_specular); float Fd = Fd_OrenNayar(pbr.roughness, data.common.NoV, data.direct.NoL, data.direct.LoV) / PI; float3 direct_diffuse = Fd * remainder * (1.0f - pbr.metallic) * pbr.albedo.xyz * data.direct.color; direct_diffuse = max(0, direct_diffuse); @@ -95,14 +109,22 @@ float4 brdf(Pbr pbr, LightData data) { // Indirect if (true) { - float F = F_Schlick(data.indirect.LoH, f0, f90); - float G = V_GGXSmith(pbr.roughness, data.indirect.NoL, data.common.NoV); + float remainder = 1.0f; +#if defined(_CLEARCOAT) + float cc_f0 = 0.04f; + float Fc = F_Schlick(data.indirect.LoH, cc_f0, f90); + float3 indirect_specular_cc = Fc * data.indirect.specular_cc * pbr.cc_strength; + specular += indirect_specular_cc; + remainder -= Fc; +#endif + float F = F_Schlick(data.indirect.LoH, f0, f90); float3 indirect_specular = F * data.indirect.specular; specular += indirect_specular; + remainder -= F; float Fd = 1.0f; // Lambertian divide is baked into SH - float3 remainder = (1.0f - indirect_specular); + remainder -= indirect_specular; float3 indirect_diffuse = Fd * remainder * pbr.albedo.xyz * data.indirect.diffuse; diffuse += indirect_diffuse; } diff --git a/features.cginc b/features.cginc index 4958d77..e6de1c1 100644 --- a/features.cginc +++ b/features.cginc @@ -15,4 +15,8 @@ #pragma shader_feature_local _TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL //endex +//ifex _Clearcoat_Enabled==0 +#pragma shader_feature_local _CLEARCOAT +//endex + #endif // __FEATURES_INC diff --git a/globals.cginc b/globals.cginc index b1db690..12e86c8 100644 --- a/globals.cginc +++ b/globals.cginc @@ -44,5 +44,9 @@ float _Tessellation_Frustum_Culling_Bias; float _Tessellation_Falloff_Factor; #endif // _TESSELLATION +#if defined(_CLEARCOAT) +float _Clearcoat_Strength; +float _Clearcoat_Roughness; +#endif // _CLEARCOAT #endif // __GLOBALS_INC diff --git a/lighting.cginc b/lighting.cginc index db3c4ff..66b7220 100644 --- a/lighting.cginc +++ b/lighting.cginc @@ -16,7 +16,10 @@ struct LightCommon { float3 V; float3 N; - float NoV; + float NoV; +#if defined(_CLEARCOAT) + float NoV_cc; +#endif }; struct LightDirect { @@ -25,6 +28,10 @@ struct LightDirect { float3 H; float NoH; float NoL; +#if defined(_CLEARCOAT) + float NoH_cc; + float NoL_cc; +#endif float LoH; float LoV; float double_LoV; @@ -38,11 +45,17 @@ struct LightIndirect { float3 H; float NoH; float NoL; +#if defined(_CLEARCOAT) + float LoH_cc; +#endif float LoH; float LoV; float double_LoV; float3 specular; +#if defined(_CLEARCOAT) + float3 specular_cc; +#endif float3 diffuse; float3 L00; @@ -78,9 +91,9 @@ float4 getDirectLightColorIntensity() { return float4(_LightColor0.xyz / _LightColor0.w, _LightColor0.w); } -float3 getIndirectSpecular(v2f i, Pbr pbr, float3 view_dir, float3 reflect_dir) { +float3 getIndirectSpecular(v2f i, float roughness, float3 view_dir, float3 reflect_dir) { UnityGIInput data = InitialiseUnityGIInput(i.worldPos, view_dir); - float3 env_refl = UnityGI_prefilteredRadiance(data, pbr.roughness_perceptual, reflect_dir); + float3 env_refl = UnityGI_prefilteredRadiance(data, roughness, reflect_dir); return env_refl; } @@ -108,6 +121,9 @@ void GetLighting(v2f i, Pbr pbr, out LightData data) { data.common.V = -view_dir; data.common.N = pbr.normal; data.common.NoV = saturate(dot(pbr.normal, data.common.V)); +#if defined(_CLEARCOAT) + data.common.NoV_cc = saturate(dot(i.normal, data.common.V)); +#endif // Direct lighting data.direct.dir = getDirectLightDirection(i); @@ -115,6 +131,10 @@ void GetLighting(v2f i, Pbr pbr, out LightData data) { data.direct.NoL = saturate(dot(pbr.normal, data.direct.dir)); data.direct.NoH = saturate(dot(pbr.normal, data.direct.H)); data.direct.LoH = saturate(dot(data.direct.dir, data.direct.H)); +#if defined(_CLEARCOAT) + data.direct.NoH_cc = saturate(dot(i.normal, data.direct.H)); + data.direct.NoL_cc = saturate(dot(i.normal, data.direct.dir)); +#endif float direct_LoV = dot(data.direct.dir, data.common.V); data.direct.LoV = saturate(direct_LoV); data.direct.double_LoV = saturate(2.0f * direct_LoV * direct_LoV - 1.0f); @@ -127,13 +147,21 @@ void GetLighting(v2f i, Pbr pbr, out LightData data) { data.indirect.H = normalize(data.common.V + data.indirect.dir); data.indirect.NoL = saturate(dot(pbr.normal, data.indirect.dir)); data.indirect.NoH = saturate(dot(pbr.normal, data.indirect.H)); +#if defined(_CLEARCOAT) + float3 dir_cc = -reflect(data.common.V, i.normal); + float3 H_cc = normalize(data.common.V + dir_cc); + data.indirect.LoH_cc = saturate(dot(dir_cc, H_cc)); +#endif data.indirect.LoH = saturate(dot(data.indirect.dir, data.indirect.H)); float indirect_LoV = dot(data.direct.dir, data.common.V); data.indirect.LoV = saturate(indirect_LoV); data.indirect.double_LoV = saturate(2.0f * indirect_LoV * indirect_LoV - 1.0f); data.indirect.diffuse = getIndirectDiffuse(i, pbr, data.indirect); - data.indirect.specular = getIndirectSpecular(i, pbr, view_dir, data.indirect.dir); + data.indirect.specular = getIndirectSpecular(i, pbr.roughness_perceptual, view_dir, data.indirect.dir); +#if defined(_CLEARCOAT) + data.indirect.specular_cc = getIndirectSpecular(i, pbr.cc_roughness, view_dir, dir_cc); +#endif } #endif // __LIGHTING_INC @@ -13,6 +13,10 @@ struct Pbr { float roughness_perceptual; float roughness; float metallic; +#if defined(_CLEARCOAT) + float cc_roughness; + float cc_strength; +#endif }; #define MIN_PERCEPTUAL_ROUGHNESS 5e-2f @@ -22,6 +26,9 @@ struct Pbr { void propagateSmoothness(inout Pbr pbr) { pbr.roughness_perceptual = max(MIN_PERCEPTUAL_ROUGHNESS, 1.0f - pbr.smoothness); pbr.roughness = max(MIN_ROUGHNESS, pbr.roughness_perceptual * pbr.roughness_perceptual); +#if defined(_CLEARCOAT) + pbr.cc_roughness = max(MIN_ROUGHNESS, pbr.cc_roughness * pbr.cc_roughness); +#endif } void apply_marble(float3 world_pos, inout float3 albedo) { @@ -56,8 +63,12 @@ Pbr getPbr(v2f i) { float4 metallic_gloss = _MetallicGlossMap.Sample(trilinear_repeat_s, i.uv0 * _MetallicGlossMap_ST.xy); pbr.smoothness = metallic_gloss.a * _Glossiness; pbr.metallic = metallic_gloss.r * _Metallic; - +#if defined(_CLEARCOAT) + pbr.cc_roughness = _Clearcoat_Roughness; + pbr.cc_strength = _Clearcoat_Strength; +#endif propagateSmoothness(pbr); + return pbr; } |
