summaryrefslogtreecommitdiffstats
path: root/glitter.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2026-03-30 15:15:36 -0700
committeryum <yum.food.vr@gmail.com>2026-03-30 15:15:36 -0700
commit4d02ae6522509f534beb5b4889bef47f58d19583 (patch)
treec752f5eacc63ffc2de65af11a1d18e59070e03ac /glitter.cginc
parentf009c086daa3f93de4a3d9ede315e6bc5f0e8d9b (diff)
Glitter: parameterize neighbor loop iterations
Diffstat (limited to 'glitter.cginc')
-rw-r--r--glitter.cginc26
1 files changed, 18 insertions, 8 deletions
diff --git a/glitter.cginc b/glitter.cginc
index 022b176..0588446 100644
--- a/glitter.cginc
+++ b/glitter.cginc
@@ -169,9 +169,14 @@ float3 disk_to_ndf_ggx(float2 v_disk, float alpha) {
return float3(alpha * hemi.xy, hemi.z) / denom;
}
+float2 GlitterNeighborOffset(float index) {
+ return float2(frac(index * 0.5) * 2.0, floor(index * 0.5)) - 0.5;
+}
+
// Algorithm 1 from Kemppinen et. al.
float D_Kemppinen(float3 h, float alpha, float glint_alpha, float2 uv,
- float2x2 uv_J, float N, float filter_size, out float3 micro_normal) {
+ float2x2 uv_J, float N, float filter_size, float angular_neighbor_count,
+ float spatial_neighbor_count, out float3 micro_normal) {
float res = sqrt(N);
float2 x_s = uv;
float3 x_a_and_d = ndf_to_disk_ggx(h, alpha);
@@ -199,13 +204,13 @@ float D_Kemppinen(float3 h, float alpha, float glint_alpha, float2 uv,
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;
+ for (float j_a = 0.0; j_a < angular_neighbor_count; j_a += 1.0) {
+ float2 i_a = base_i_a + GlitterNeighborOffset(j_a);
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;
+ for (float j_s = 0.0; j_s < spatial_neighbor_count; j_s += 1.0) {
+ float2 i_s = base_i_s + GlitterNeighborOffset(j_s);
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;
@@ -241,6 +246,7 @@ struct LightGlitter {
// Glitter data getter to be run from lighting code.
LightGlitter GetGlitterLighting(
float glitter_amount, float glitter_roughness,
+ float glitter_spatial_neighbor_count, float glitter_angular_neighbor_count,
float2 uv, float3x3 tbn, float roughness,
float3 normal, float3 V, float3 direct_H, float3 indirect_dir) {
LightGlitter g;
@@ -252,19 +258,23 @@ LightGlitter GetGlitterLighting(
float3 direct_H_tangent = mul(direct_H, transpose(tbn));
float3 direct_micro_normal; // unused
g.direct_D = D_Kemppinen(direct_H_tangent, roughness, glitter_roughness,
- uv, uv_J, N, glitter_filter_size, direct_micro_normal);
+ uv, uv_J, N, glitter_filter_size,
+ glitter_angular_neighbor_count, glitter_spatial_neighbor_count,
+ direct_micro_normal);
// Indirect
float3 indirect_H = normalize(V + indirect_dir);
float3 indirect_H_tangent = mul(indirect_H, transpose(tbn));
float3 indirect_micro_normal; // unused, but required by D_Kemppinen
g.indirect_D = D_Kemppinen(indirect_H_tangent, roughness, glitter_roughness,
- uv, uv_J, N, glitter_filter_size, indirect_micro_normal);
+ uv, uv_J, N, glitter_filter_size,
+ glitter_angular_neighbor_count, glitter_spatial_neighbor_count,
+ indirect_micro_normal);
g.indirect_NoL = max(1e-4, dot(normal, indirect_dir));
g.indirect_LoH = max(1e-4, dot(indirect_dir, indirect_H));
return g;
}
-#endif
+#endif // _GLITTER
#endif // __GLITTER_INC