diff options
| author | yum <yum.food.vr@gmail.com> | 2026-03-29 22:43:01 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-03-29 22:43:01 -0700 |
| commit | b5197bed4cad2a8452bcbfa8e116497760edf1ba (patch) | |
| tree | 25144eed48099554aa4da829580a812e421fd191 /brdf.cginc | |
| parent | a7547f351228b1d0ab380096438b6664d925e07d (diff) | |
Refactor & credit glitter
Diffstat (limited to 'brdf.cginc')
| -rwxr-xr-x | brdf.cginc | 119 |
1 files changed, 88 insertions, 31 deletions
@@ -101,6 +101,43 @@ float G_Estevez(float roughness, float NoL, float NoV) { return 1.0 / ((1.0 + lambda_l + lambda_v) * 4.0 * NoL * NoV); } +#if defined(_GLITTER) +struct GlitterData { + float2 uv; + float2x2 uv_J; + float N; +}; + +struct GlitterDFG { + float d; + float3 f; + float g; +}; + +GlitterData GetGlitterData(v2f i) { + GlitterData data; + data.uv = i.uv01.xy; + data.uv_J = uv_ellipsoid(transpose(float2x2(ddx(data.uv), ddy(data.uv)))); + data.N = 8.0e5f * pow(10.0f, _Glitter_Amount * 6.0f - 2.0f); + return data; +} + +GlitterDFG GetGlitterDFG(GlitterData data, + float3x3 world_to_tangent, float roughness, float3 H, float LoH, + float NoL, float NoV) { + GlitterDFG dfg; + const float glitter_filter_size = 0.7f; + float3 H_tangent = mul(H, world_to_tangent); + float f0 = 0.15f; + float f90 = 1.0f; + dfg.f = F_Schlick(LoH, f0, f90); + dfg.d = D_Kemppinen(H_tangent, roughness, _Glitter_Roughness, + data.uv, data.uv_J, data.N, glitter_filter_size); + dfg.g = G_GGXSmith(roughness, NoL, NoV); + return dfg; +} +#endif + float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) { bd = (BrdfData)0; float3 specular = 0; @@ -144,6 +181,11 @@ float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) { float3 cc_energy_comp = 1.0f + cc_f0_color * (1.0f / (bd.ibl_dfg_cc.xxx + bd.ibl_dfg_cc.yyy) - 1.0f); #endif +#if defined(_GLITTER) + GlitterData glitter_data = GetGlitterData(i); + float3x3 glitter_world_to_tangent = transpose(pbr.tbn); +#endif + // Direct { float3 remainder = 1.0f; @@ -161,51 +203,56 @@ float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) { remainder *= saturate(1.0f - bd.direct_f_cc * pbr.cc_strength); #endif -#if defined(_GLITTER) - float2 glitter_uv = i.uv01.xy; - float2x2 glitter_uv_J = uv_ellipsoid(mat2_from_cols(ddx(glitter_uv), ddy(glitter_uv))); - float3 H_tangent = mul(data.direct.H, transpose(pbr.tbn)); - const float glitter_filter_size = 0.7f; - float glitter_N = 8.0e5f * pow(10.0f, _Glitter_Amount * 6.0f - 2.0f); - bd.direct_f = F_Schlick(data.direct.LoH, 0.96f, 1.0f); - bd.direct_d = D_Kemppinen(H_tangent, pbr.roughness, _Glitter_Roughness, - glitter_uv, glitter_uv_J, glitter_N, glitter_filter_size); - bd.direct_g = G_GGXSmith(pbr.roughness, data.direct.NoL, data.common.NoV); - float3 direct_specular_glitter = (bd.direct_d * bd.direct_g) * bd.direct_f; - direct_specular_glitter *= data.direct.color * data.direct.NoL; - direct_specular_glitter *= remainder; - specular += direct_specular_glitter; - remainder *= saturate(1.0f - direct_specular_glitter); -#else - #if defined(_CLOTH) float3 cloth_f0 = _Cloth_Sheen.rgb; bd.direct_f = F_Schlick(data.direct.LoH, cloth_f0, f90); bd.direct_d = D_Estevez(pbr.roughness, data.direct.NoH); bd.direct_g = G_Estevez(pbr.roughness, data.direct.NoL, data.common.NoV); - float3 direct_specular = (bd.direct_d * bd.direct_g) * bd.direct_f; - direct_specular *= data.direct.color * data.direct.NoL; - direct_specular *= remainder; - specular += direct_specular; - + float3 direct_specular_cloth = (bd.direct_d * bd.direct_g) * bd.direct_f; + direct_specular_cloth *= data.direct.color * data.direct.NoL; + direct_specular_cloth *= remainder; + specular += direct_specular_cloth; + /* float Fd = Fd_Lambertian(data.direct.NoL) / PI; float3 direct_diffuse = Fd * pbr.albedo.xyz * data.direct.color; direct_diffuse *= remainder; direct_diffuse = max(0, direct_diffuse); diffuse += direct_diffuse; + */ +#endif // _CLOTH + +#if defined(_GLITTER) + GlitterDFG direct_glitter = GetGlitterDFG(glitter_data, + glitter_world_to_tangent, pbr.roughness, data.direct.H, + data.direct.LoH, data.direct.NoL, data.common.NoV); + bd.direct_f = direct_glitter.f; + bd.direct_d = direct_glitter.d; + bd.direct_g = direct_glitter.g; + float3 direct_specular_glitter = (direct_glitter.d * direct_glitter.g) + * direct_glitter.f * data.direct.color * data.direct.NoL + * _Glitter_Tint; + // No spec ao for glitter, please. + direct_specular_glitter *= remainder; + specular += direct_specular_glitter; + + float direct_g = G_GGXSmith(pbr.roughness, data.direct.NoL, data.common.NoV); + float3 direct_f = F_Schlick(data.direct.LoH, f0_color, f90); + float direct_d = D_GGX(pbr.roughness, data.direct.NoH); #else - float3 direct_energy = energy_comp; bd.direct_g = G_GGXSmith(pbr.roughness, data.direct.NoL, data.common.NoV); bd.direct_f = F_Schlick(data.direct.LoH, f0_color, f90); bd.direct_d = D_GGX(pbr.roughness, data.direct.NoH); + float direct_g = bd.direct_g; + float3 direct_f = bd.direct_f; + float direct_d = bd.direct_d; #endif - float3 direct_specular = (bd.direct_d * bd.direct_g) * bd.direct_f; + float3 direct_specular = (direct_d * direct_g) * direct_f; direct_specular *= data.direct.color * data.direct.NoL; - direct_specular *= direct_energy; + direct_specular *= energy_comp; direct_specular *= remainder; - specular += direct_specular; + specular += direct_specular * data.common.spec_ao; #if defined(F_OREN_NAYAR) float Fd = Fd_OrenNayar(pbr.roughness, data.common.NoV, data.direct.NoL, data.direct.LoV); @@ -216,7 +263,6 @@ float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) { direct_diffuse *= remainder; direct_diffuse = max(0, direct_diffuse); diffuse += direct_diffuse; -#endif } // Indirect @@ -227,23 +273,35 @@ float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) { float3 cc_specular_dfg = bd.ibl_dfg_cc.xxx * cc_f0_color + bd.ibl_dfg_cc.yyy; // filament 5.3.4.6 float3 cc_indirect_specular = data.indirect.specular_cc * cc_specular_dfg; cc_indirect_specular *= cc_energy_comp; - specular += cc_indirect_specular; + specular += cc_indirect_specular * data.common.spec_ao; remainder -= cc_specular_dfg; #endif #if defined(_CLOTH) float3 specular_dfg = _Cloth_Sheen.rgb * bd.ibl_dfg.zzz; float3 indirect_specular = data.indirect.specular * specular_dfg; - specular += indirect_specular * remainder; + specular += indirect_specular * remainder * data.common.spec_ao; float3 indirect_diffuse = pbr.albedo.xyz * data.indirect.diffuse; diffuse += indirect_diffuse * remainder; #else +#if defined(_GLITTER) + GlitterDFG indirect_glitter = GetGlitterDFG(glitter_data, + glitter_world_to_tangent, pbr.roughness, data.indirect.H, + data.indirect.LoH, data.indirect.NoL, data.common.NoV); + float3 indirect_specular_glitter = (indirect_glitter.d * indirect_glitter.g) + * indirect_glitter.f * data.indirect.specular * data.indirect.NoL + * _Glitter_Tint; + // No spec ao for glitter, please. + specular += indirect_specular_glitter * remainder; + remainder *= saturate(1 - indirect_specular_glitter * remainder); +#endif + float3 specular_dfg = bd.ibl_dfg.xxx * f0_color + bd.ibl_dfg.yyy; // filament 5.3.4.6 float3 indirect_specular = data.indirect.specular * specular_dfg; indirect_specular *= energy_comp; - specular += indirect_specular * remainder; + specular += indirect_specular * remainder * data.common.spec_ao; float3 indirect_diffuse = pbr.albedo.xyz * data.indirect.diffuse * (1.0 - pbr.metallic); diffuse += indirect_diffuse * remainder; @@ -263,7 +321,6 @@ float4 brdf(v2f i, Pbr pbr, LightData data, out BrdfData bd) { #endif diffuse *= data.common.ao; - specular *= data.common.spec_ao; #if (defined(_EMISSIONS) || defined(_LETTER_GRID)) && defined(FORWARD_BASE_PASS) float3 emission = pbr.emission; |
