summaryrefslogtreecommitdiffstats
path: root/brdf.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2026-03-29 22:43:01 -0700
committeryum <yum.food.vr@gmail.com>2026-03-29 22:43:01 -0700
commitb5197bed4cad2a8452bcbfa8e116497760edf1ba (patch)
tree25144eed48099554aa4da829580a812e421fd191 /brdf.cginc
parenta7547f351228b1d0ab380096438b6664d925e07d (diff)
Refactor & credit glitter
Diffstat (limited to 'brdf.cginc')
-rwxr-xr-xbrdf.cginc119
1 files changed, 88 insertions, 31 deletions
diff --git a/brdf.cginc b/brdf.cginc
index fcc2594..92fd8bb 100755
--- a/brdf.cginc
+++ b/brdf.cginc
@@ -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;