summaryrefslogtreecommitdiffstats
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
parenta7547f351228b1d0ab380096438b6664d925e07d (diff)
Refactor & credit glitter
-rwxr-xr-x3ner.shader1
-rwxr-xr-xbrdf.cginc119
-rw-r--r--glitter.cginc238
-rwxr-xr-xglobals.cginc1
-rwxr-xr-xmath.cginc9
5 files changed, 219 insertions, 149 deletions
diff --git a/3ner.shader b/3ner.shader
index 1f313e7..5cc10be 100755
--- a/3ner.shader
+++ b/3ner.shader
@@ -661,6 +661,7 @@ Shader "yum_food/3ner"
[ThryToggle(_GLITTER)] _Glitter_Enabled("Enable", Float) = 0
_Glitter_Amount("Amount", Range(0, 1)) = 0.5
_Glitter_Roughness("Roughness", Range(0.001, 0.1)) = 0.01
+ _Glitter_Tint("Tint", Color) = (1, 1, 1, 1)
[HideInInspector] m_end_Glitter("Glitter", Float) = 0
//endex
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;
diff --git a/glitter.cginc b/glitter.cginc
index 2744d6b..2ed0ef4 100644
--- a/glitter.cginc
+++ b/glitter.cginc
@@ -1,183 +1,203 @@
#ifndef __GLITTER_INC
#define __GLITTER_INC
-#include "math.cginc"
-
/*
-@article{KPT:2025:Glinty,
- title = {Evaluating and Sampling Glinty NDFs in Constant Time},
- author = {Kemppinen, Pauli and Paulin, LoÏs and Thonat, Théo and Thiery, Jean-Marc and Lehtinen, Jaakko and Boubekeur, Tamy},
- year = {2025},
- journal = {ACM Transactions on Graphics (Proc. SIGGRAPH Asia 2025)},
- volume = {44},
- number = {6},
- articleno = {255},
-}
-*/
-// Ported from: https://www.shadertoy.com/view/tcdGDl
+ * This is an implementation of Kemppinen et. al.'s "Evaluating and Sampling
+ * Glinty NDFs in Constant Time".
+ * It is ported from: https://www.shadertoy.com/view/tcdGDl
+ * Since no license terms are listed in the shader body, it is protected by
+ * the default Shadertoy license (per https://www.shadertoy.com/terms),
+ * which is the Creative Commons Attribution-NonCommercial-ShareAlike 3.0
+ * Unported License: https://creativecommons.org/licenses/by-nc-sa/3.0/deed.en
+ *
+ * I have made changes to this code. They are:
+ * 1. Syntax changes required to translate GLSL to HLSL.
+ * 2. Stylistic preferences, like using "1" or "1.0" instead of "1.".
+ *
+ * @article{KPT:2025:Glinty,
+ * title = {Evaluating and Sampling Glinty NDFs in Constant Time},
+ * author = {Kemppinen, Pauli and Paulin, LoÏs and Thonat,
+ * Théo and Thiery, Jean-Marc and Lehtinen, Jaakko and Boubekeur,
+ * Tamy},
+ * year = {2025},
+ * journal = {ACM Transactions on Graphics (Proc. SIGGRAPH Asia 2025)},
+ * volume = {44},
+ * number = {6},
+ * articleno = {255},
+ * }
+ */
+
+#define PI 3.1415926535897932384626433832795028841971
+// Remaps [0, UINT_MAX] to [0, 1]
+#define UINT_TO_UNIT (1.0 / 4294967296.0)
// Lambert azimuthal equal area projection
float2 lambert(float3 v) {
return v.xy / sqrt(1 + v.z);
}
-// Rebuild GLSL mat2 column semantics explicitly in HLSL.
-float2 mat2_col(float2x2 m, uint i) {
- return float2(m[0][i], m[1][i]);
-}
-
-float2x2 mat2_from_cols(float2 c0, float2 c1) {
- return float2x2(c0.x, c1.x,
- c0.y, c1.y);
-}
-
// v is a microfacet normal that has been squished according to alpha, a
// roughness parameter.
float3 ndf_to_disk_ggx(float3 v, float alpha) {
- // Map `v` onto a hemisphere.
- float3 hemi = float3(v.xy / alpha, v.z);
- float denom = dot(hemi, hemi);
- // Project onto circle with equal area projection, and remap from [-1, 1]
- // to [0, 1].
- float2 v_disk = lambert(normalize(hemi)) * 0.5 + 0.5;
- float jacobian_determinant = 1.0 / (alpha * alpha * denom * denom);
- return float3(v_disk, jacobian_determinant);
+ // Map `v` onto a hemisphere.
+ float3 hemi = float3(v.xy / alpha, v.z);
+ float denom = dot(hemi, hemi);
+ // Project onto circle with equal area projection, and remap from [-1, 1]
+ // to [0, 1].
+ float2 v_disk = lambert(normalize(hemi)) * 0.5 + 0.5;
+ float jacobian_determinant = 1.0 / (alpha * alpha * denom * denom);
+ return float3(v_disk, jacobian_determinant);
}
// Computes (M^T M)^-1
float2x2 inv_quadratic(float2x2 M) {
- float D = determinant(M);
- float2 c0 = mat2_col(M, 0) / D;
- float2 c1 = mat2_col(M, 1) / D;
- float A = dot(c0, c0);
- float B = -dot(c0, c1);
- float C = dot(c1, c1);
- return mat2_from_cols(float2(C, B), float2(B, A));
+ float D = determinant(M);
+ float2 c0 = transpose(M)[0] / D;
+ float2 c1 = transpose(M)[1] / D;
+ float A = dot(c0, c0);
+ float B = -dot(c0, c1);
+ float C = dot(c1, c1);
+ return transpose(float2x2(float2(C, B), float2(B, A)));
}
float2x2 uv_ellipsoid(float2x2 uv_J) {
- float2x2 Q = inv_quadratic(transpose(uv_J));
- float2 q0 = mat2_col(Q, 0);
- float2 q1 = mat2_col(Q, 1);
- float tr = 0.5 * (q0.x + q1.y);
- float D = sqrt(max(0.0, tr * tr - determinant(Q)));
- float l1 = tr - D;
- float l2 = tr + D;
- float2 v1 = float2(l1 - q1.y, q0.y);
- float2 v2 = float2(q1.x, l2 - q0.x);
- float2 n = 1.f/sqrt(float2(l1, l2));
- return mat2_from_cols(normalize(v1) * n.x, normalize(v2) * n.y);
+ float2x2 Q = inv_quadratic(transpose(uv_J));
+ float2 q0 = transpose(Q)[0];
+ float2 q1 = transpose(Q)[1];
+ float tr = 0.5 * (q0.x + q1.y);
+ float D = sqrt(max(0.0, tr * tr - determinant(Q)));
+ float l1 = tr - D;
+ float l2 = tr + D;
+ float2 v1 = float2(l1 - q1.y, q0.y);
+ float2 v2 = float2(q1.x, l2 - q0.x);
+ float2 n = 1.0/sqrt(float2(l1, l2));
+ return transpose(float2x2(normalize(v1) * n.x, normalize(v2) * n.y));
}
float QueryLod(float2x2 uv_J, float filter_size) {
- float s0 = length(mat2_col(uv_J, 0));
- float s1 = length(mat2_col(uv_J, 1));
- return log2(max(s0, s1) * filter_size) + pow(2.0, filter_size);
+ float s0 = length(transpose(uv_J)[0]);
+ float s1 = length(transpose(uv_J)[1]);
+ return log2(max(s0, s1) * filter_size) + pow(2.0, filter_size);
+}
+
+float2x2 inverse(float2x2 m) {
+ float det = (m[0][0] * m[1][1]) - (m[0][1] * m[1][0]);
+
+ return float2x2(
+ m[1][1], -m[0][1],
+ -m[1][0], m[0][0]
+ ) / det;
}
float normal(float2x2 cov, float2 x) {
- return exp(-.5 * dot(x, mul(inverse(cov), x))) / (sqrt(determinant(cov)) * 2.0 * PI);
+ return exp(-.5 * dot(x, mul(inverse(cov), x))) / (sqrt(determinant(cov)) * 2.0 * PI);
}
uint2 shuffle(uint2 v) {
- v = v * 1664525u + 1013904223u;
- v.x += v.y * 1664525u;
- v.y += v.x * 1664525u;
+ v = v * 1664525u + 1013904223u;
+ v.x += v.y * 1664525u;
+ v.y += v.x * 1664525u;
- v = v ^ (v>>16u);
+ v = v ^ (v>>16u);
- v.x += v.y * 1664525u;
- v.y += v.x * 1664525u;
- v = v ^ (v>>16u);
- return v;
+ v.x += v.y * 1664525u;
+ v.y += v.x * 1664525u;
+ v = v ^ (v>>16u);
+ return v;
}
float2 rand(uint2 v) {
- return float2(shuffle(v)) * pow(0.5, 32.0);
+ return float2(shuffle(v)) * UINT_TO_UNIT;
}
float2 Rand2D(float2 x, float2 y, float l, uint i) {
- uint2 ux = asuint(x);
- uint2 uy = asuint(y);
- uint ul = asuint(l);
- return rand((ux>>16|ux<<16) ^ uy ^ ul ^ (i*0x124u));
+ uint2 ux = asuint(x);
+ uint2 uy = asuint(y);
+ uint ul = asuint(l);
+ // This is broken, but looks cool.
+ //return hash22_fast(asfloat((ux>>16|ux<<16) ^ uy ^ ul ^ (i*0x124u)));
+ return rand((ux>>16|ux<<16) ^ uy ^ ul ^ (i*0x124u));
}
float Rand1D(float2 x, float2 y, float l, uint i) {
- return Rand2D(x, y, l, i).x;
+ return Rand2D(x, y, l, i).x;
}
// Bürmann series, see https://en.wikipedia.org/wiki/Error_function
float erf(float x) {
- float e = exp(-x*x);
- return sign(x) * 2.0 * sqrt((1.0 - e) / PI) *
- (sqrt(PI) * 0.5 + 31./200. * e - 341.0/8000.0 * e * e);
+ float e = exp(-x*x);
+ return sign(x) * 2.0 * sqrt((1.0 - e) / PI) *
+ (sqrt(PI) * 0.5 + 31.0/200.0 * e - 341.0/8000.0 * e * e);
}
float cdf(float x, float mu, float sigma) {
- return 0.5 + 0.5 * erf((x-mu)/(sigma*sqrt(2.0)));
+ return 0.5 + 0.5 * erf((x-mu)/(sigma*sqrt(2.0)));
}
float integrate_interval(float x, float size, float mu, float stdev, float lower_limit, float upper_limit) {
- return cdf(min(x+size, upper_limit), mu, stdev) - cdf(max(x-size, lower_limit), mu, stdev);
+ return cdf(min(x+size, upper_limit), mu, stdev) - cdf(max(x-size, lower_limit), mu, stdev);
}
float integrate_box(float2 x, float2 size, float2 mu, float2x2 sigma, float2 lower_limit, float2 upper_limit) {
- return
- integrate_interval(x.x, size.x, mu.x, sqrt(sigma[0][0]), lower_limit.x, upper_limit.x) *
- integrate_interval(x.y, size.y, mu.y, sqrt(sigma[1][1]), lower_limit.y, upper_limit.y);
+ return
+ integrate_interval(x.x, size.x, mu.x, sqrt(sigma[0][0]), lower_limit.x, upper_limit.x) *
+ integrate_interval(x.y, size.y, mu.y, sqrt(sigma[1][1]), lower_limit.y, upper_limit.y);
}
float compensation(float2 x_a, float2x2 sigma_a, float res_a) {
- float containing = integrate_box(0.5, 0.5, x_a, sigma_a, 0.0, 1.0);
- float explicitly_evaluated = integrate_box(round(x_a*res_a)/res_a, 1.0/res_a, x_a, sigma_a, 0, 1);
- return containing - explicitly_evaluated;
+ float containing = integrate_box(0.5, 0.5, x_a, sigma_a, 0.0, 1.0);
+ float explicitly_evaluated = integrate_box(round(x_a*res_a)/res_a, 1.0/res_a, x_a, sigma_a, 0, 1);
+ return containing - explicitly_evaluated;
}
float D_Kemppinen(float3 h, float alpha, float glint_alpha, float2 uv, float2x2 uv_J, float N, float filter_size) {
- float res = sqrt(N);
- float2 x_s = uv;
- float3 x_a_and_d = ndf_to_disk_ggx(h, alpha);
- float2 x_a = x_a_and_d.xy;
- float d = x_a_and_d.z;
+ float res = sqrt(N);
+ float2 x_s = uv;
+ float3 x_a_and_d = ndf_to_disk_ggx(h, alpha);
+ float2 x_a = x_a_and_d.xy;
+ float d = x_a_and_d.z;
- float lambda = QueryLod(res * uv_J, filter_size);
+ float lambda = QueryLod(res * uv_J, filter_size);
- float D_filter = .0;
+ float D_filter = 0;
- for(float m = .0; m<2.; m += 1.) {
- float l = floor(lambda) + m;
+ [loop]
+ for (float m = 0; m < 2; m += 1) {
+ float l = floor(lambda) + m;
- float w_lambda = 1. - abs(lambda - l);
- float res_s = res * pow(2., -l);
- float res_a = pow(2., l);
+ float w_lambda = 1.0 - abs(lambda - l);
+ float res_s = res * pow(2, -l);
+ float res_a = pow(2, l);
- float2x2 uv_J2 = filter_size * uv_J;
- float2x2 sigma_s = mul(uv_J2, transpose(uv_J2));
+ float2x2 uv_J2 = filter_size * uv_J;
+ float2x2 sigma_s = mul(uv_J2, transpose(uv_J2));
- float2x2 sigma_a = d * pow(glint_alpha, 2.) * float2x2(1., .0, .0, 1.);
+ float2x2 sigma_a = d * pow(glint_alpha, 2) * float2x2(1, 0, 0, 1);
- float2 base_i_a = clamp(round(x_a * res_a), 1., res_a-1.);
- for(int j_a = 0; j_a < 4; ++j_a) {
- float2 i_a = base_i_a + float2(int2(j_a, j_a/2)%2)-.5;
+ float2 base_i_a = clamp(round(x_a * res_a), 1, res_a-1);
+ [loop]
+ for (uint j_a = 0; j_a < 4; ++j_a) {
+ float2 i_a = base_i_a + float2(int2(j_a, j_a/2)%2)-.5;
- float2 base_i_s = round(x_s * res_s);
- for(int j_s = 0; j_s < 4; ++j_s) {
- float2 i_s = base_i_s + float2(int2(j_s, j_s/2)%2)-.5;
+ float2 base_i_s = round(x_s * res_s);
+ [loop]
+ for (uint j_s = 0; j_s < 4; ++j_s) {
+ float2 i_s = base_i_s + float2(int2(j_s, j_s/2)%2)-.5;
- float2 g_s = (i_s + Rand2D(i_s, i_a, l, 1u) - .5) / res_s;
- float2 g_a = (i_a + Rand2D(i_s, i_a, l, 2u) - .5) / res_a;
+ float2 g_s = (i_s + Rand2D(i_s, i_a, l, 1u) - .5) / res_s;
+ float2 g_a = (i_a + Rand2D(i_s, i_a, l, 2u) - .5) / res_a;
- float r = Rand1D(i_s, i_a, l, 4u);
- float roulette = smoothstep(max(.0, r-.1), min(1.0, r+.1), w_lambda);
+ float r = Rand1D(i_s, i_a, l, 4u);
+ float roulette = smoothstep(max(.0, r-.1), min(1.0, r+.1), w_lambda);
- D_filter += roulette * normal(sigma_a, x_a - g_a) * normal(sigma_s, x_s - g_s) / N;
- }
- }
- D_filter += w_lambda * compensation(x_a, sigma_a, res_a);
- }
+ D_filter += roulette * normal(sigma_a, x_a - g_a) * normal(sigma_s, x_s - g_s) / N;
+ }
+ }
+ D_filter += w_lambda * compensation(x_a, sigma_a, res_a);
+ }
- return D_filter * d / PI;
+ return D_filter * d / PI;
}
#endif // __GLITTER_INC
+
diff --git a/globals.cginc b/globals.cginc
index 770a497..88fb663 100755
--- a/globals.cginc
+++ b/globals.cginc
@@ -155,6 +155,7 @@ int _Details_UV_Channel;
#if defined(_GLITTER)
float _Glitter_Amount;
float _Glitter_Roughness;
+float3 _Glitter_Tint;
#endif // _GLITTER
#if defined(_UV_SCROLL)
diff --git a/math.cginc b/math.cginc
index 55e1e35..15d02eb 100755
--- a/math.cginc
+++ b/math.cginc
@@ -258,13 +258,4 @@ float3 srgb_to_linear(float3 srgb_color) {
return lerp(lo, hi, step(0.04045f, srgb_color));
}
-float2x2 inverse(float2x2 m) {
- float det = (m[0][0] * m[1][1]) - (m[0][1] * m[1][0]);
-
- return float2x2(
- m[1][1], -m[0][1],
- -m[1][0], m[0][0]
- ) / det;
-}
-
#endif // __MATH_INC