From dc8a6dfb9d78316b8c58c587bc606468377b0fe3 Mon Sep 17 00:00:00 2001 From: yum Date: Sat, 4 Oct 2025 19:18:47 -0700 Subject: add unlit toggle, adjust IBL --- brdf.cginc | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'brdf.cginc') diff --git a/brdf.cginc b/brdf.cginc index 5a24307..d89558c 100644 --- a/brdf.cginc +++ b/brdf.cginc @@ -1,6 +1,7 @@ #ifndef __BRDF_INC #define __BRDF_INC +#include "pema99.cginc" #include "pbr.cginc" #include "lighting.cginc" #include "lysenko.cginc" @@ -184,14 +185,14 @@ float4 brdf(Pbr pbr, LightData data) { #if defined(FORWARD_BASE_PASS) { float remainder = 1.0f; - float2 dfg_uv = float2(data.common.NoV, pbr.roughness); + float2 dfg_uv = float2(pbr.roughness, data.common.NoV); #if defined(_CLEARCOAT) float cc_f0 = 0.04f; float Fcc = F_Schlick(data.common.NoV, cc_f0, 1.0f); float3 indirect_specular_cc = Fcc * data.indirect.specular_cc * pbr.cc_strength; specular += indirect_specular_cc; - remainder *= (1.0f - Fcc * pbr.cc_strength); + remainder -= Fcc * pbr.cc_strength; #endif #if defined(_CLOTH_SHEEN) @@ -201,19 +202,27 @@ float4 brdf(Pbr pbr, LightData data) { // Energy conservation for cloth is tricky with IBL. // A simple approximation is to use the Fresnel of the sheen layer. float Fcl = F_Schlick(data.common.NoV, 0.04, 1.0); - remainder *= (1.0f - Fcl * pbr.cl_strength); + remainder -= Fcl * pbr.cl_strength; #endif // Standard PBR IBL using split-sum approximation - float2 dfg = _DFG_LUT.Sample(bilinear_clamp_s, dfg_uv).rg; - float3 f0_spec = lerp(0.04f, pbr.albedo.xyz, pbr.metallic); + // Specular lobe + float2 dfg; + [branch] + if (textureExists(_DFG_LUT)) { + dfg = _DFG_LUT.SampleLevel(bilinear_clamp_s, dfg_uv, 0).rg; + } else { + dfg = float2(0, 1); + } + float3 f0_spec = lerp(f0, pbr.albedo.xyz, pbr.metallic); float3 ibl_specular_reflectance = f0_spec * dfg.x + dfg.y; float3 indirect_specular = data.indirect.specular * ibl_specular_reflectance; - specular += indirect_specular * remainder; - - // For energy conservation with the diffuse term, we use the view-dependent Fresnel. - float3 F = F_Schlick(data.common.NoV, f0_spec, 1.0f); - remainder *= (1.0f - F); + // surface reduction term lifted from here: + // UnityStandardBRDF.cginc :: BRDF1_Unity_PBS + float surface_reduction = 1.0f / (pbr.roughness * pbr.roughness + 1.0f); + const float F = F_Schlick(data.indirect.NoL, f0_spec, f90); + specular += surface_reduction * indirect_specular * F; + remainder -= F; // Diffuse is Lambertian, which is pre-integrated into the SH diffuse probe float3 indirect_diffuse = pbr.albedo.xyz * data.indirect.diffuse * remainder * (1.0 - pbr.metallic); -- cgit v1.2.3