diff options
| author | yum <yum.food.vr@gmail.com> | 2026-03-30 15:40:06 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-03-30 15:40:06 -0700 |
| commit | 03967824564349564c6968021d0b4955e377756c (patch) | |
| tree | ac44a0c741481aade9daa61703d618b71b79397e | |
| parent | 28d8c61b31954563b7aec754ca508665ca3b9df3 (diff) | |
Glitter: hardcode n=1 neighbors
| -rwxr-xr-x | 3ner.shader | 2 | ||||
| -rw-r--r-- | glitter.cginc | 119 | ||||
| -rwxr-xr-x | globals.cginc | 2 | ||||
| -rwxr-xr-x | lighting.cginc | 4 |
4 files changed, 20 insertions, 107 deletions
diff --git a/3ner.shader b/3ner.shader index 3ec6e2d..5cc10be 100755 --- a/3ner.shader +++ b/3ner.shader @@ -661,8 +661,6 @@ 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 - [IntRange] _Glitter_Spatial_Neighbor_Count("Spatial Neighbor Count", Range(1, 8)) = 4 - [IntRange] _Glitter_Angular_Neighbor_Count("Angular Neighbor Count", Range(1, 8)) = 4 _Glitter_Tint("Tint", Color) = (1, 1, 1, 1) [HideInInspector] m_end_Glitter("Glitter", Float) = 0 //endex diff --git a/glitter.cginc b/glitter.cginc index 167490c..09ba0ea 100644 --- a/glitter.cginc +++ b/glitter.cginc @@ -169,65 +169,9 @@ float3 disk_to_ndf_ggx(float2 v_disk, float alpha) { return float3(alpha * hemi.xy, hemi.z) / denom; } -void GlitterNeighborOffsets(float2 x, float res, int neighbor_count, - out float2 offsets[8]) { - float2 base = floor(x * res) + 0.5; - float2 candidate_offsets[9]; - float candidate_distances[9]; - - candidate_offsets[0] = float2(-1.0, -1.0); - candidate_offsets[1] = float2( 0.0, -1.0); - candidate_offsets[2] = float2( 1.0, -1.0); - candidate_offsets[3] = float2(-1.0, 0.0); - candidate_offsets[4] = float2( 0.0, 0.0); - candidate_offsets[5] = float2( 1.0, 0.0); - candidate_offsets[6] = float2(-1.0, 1.0); - candidate_offsets[7] = float2( 0.0, 1.0); - candidate_offsets[8] = float2( 1.0, 1.0); - - [unroll] - for (int candidate_index = 0; candidate_index < 9; ++candidate_index) { - float2 candidate = base + candidate_offsets[candidate_index]; - float2 candidate_delta = candidate - x * res; - candidate_distances[candidate_index] = dot(candidate_delta, candidate_delta); - } - - [unroll] - for (int output_index = 0; output_index < 8; ++output_index) { - offsets[output_index] = 0.0; - } - - [unroll] - for (int output_index = 0; output_index < 8; ++output_index) { - if (output_index >= neighbor_count) { - break; - } - - int best_candidate_index = output_index; - [unroll] - for (int candidate_index = output_index + 1; - candidate_index < 9; ++candidate_index) { - if (candidate_distances[candidate_index] - < candidate_distances[best_candidate_index]) { - best_candidate_index = candidate_index; - } - } - - float2 best_offset = candidate_offsets[best_candidate_index]; - float best_distance = candidate_distances[best_candidate_index]; - - candidate_offsets[best_candidate_index] = candidate_offsets[output_index]; - candidate_distances[best_candidate_index] = candidate_distances[output_index]; - candidate_offsets[output_index] = best_offset; - candidate_distances[output_index] = best_distance; - offsets[output_index] = best_offset; - } -} - // 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, float angular_neighbor_count, - float spatial_neighbor_count, out float3 micro_normal) { + float2x2 uv_J, float N, float filter_size, out float3 micro_normal) { float res = sqrt(N); float2 x_s = uv; float3 x_a_and_d = ndf_to_disk_ggx(h, alpha); @@ -253,43 +197,24 @@ float D_Kemppinen(float3 h, float alpha, float glint_alpha, float2 uv, float2x2 sigma_a = d * pow(glint_alpha, 2) * float2x2(1, 0, 0, 1); - int angular_neighbor_count_i = (int)angular_neighbor_count; - int spatial_neighbor_count_i = (int)spatial_neighbor_count; + float2 base_i_a = floor(x_a * res_a) + 0.5; + float2 i_a = clamp(base_i_a, 0.5, res_a - 0.5); - float2 angular_neighbor_offsets[8]; - GlitterNeighborOffsets(x_a, res_a, angular_neighbor_count_i, - angular_neighbor_offsets); + float2 base_i_s = floor(x_s * res_s) + 0.5; + float2 i_s = clamp(base_i_s, 0.5, res_s - 0.5); - float2 spatial_neighbor_offsets[8]; - GlitterNeighborOffsets(x_s, res_s, spatial_neighbor_count_i, - spatial_neighbor_offsets); + 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 base_i_a = floor(x_a * res_a) + 0.5; - [loop] - for (int j_a = 0; j_a < angular_neighbor_count_i; ++j_a) { - float2 i_a = clamp(base_i_a + angular_neighbor_offsets[j_a], - 0.5, res_a - 0.5); - - float2 base_i_s = floor(x_s * res_s) + 0.5; - [loop] - for (int j_s = 0; j_s < spatial_neighbor_count_i; ++j_s) { - float2 i_s = clamp(base_i_s + spatial_neighbor_offsets[j_s], - 0.5, res_s - 0.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; - - float r = Rand1D(i_s, i_a, l, 4u); - float roulette = smoothstep(max(.0, r-.1), min(1.0, r+.1), w_lambda); - - float w = roulette * normal(sigma_a, x_a - g_a) - * normal(sigma_s, x_s - g_s) / N; - D_filter += w; - if (w > best_weight) { - best_weight = w; - best_g_a = g_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 w = roulette * normal(sigma_a, x_a - g_a) + * normal(sigma_s, x_s - g_s) / N; + D_filter += w; + if (w > best_weight) { + best_weight = w; + best_g_a = g_a; } D_filter += w_lambda * compensation(x_a, sigma_a, res_a); } @@ -309,9 +234,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, + float glitter_amount, float glitter_roughness, float2 uv, float3x3 tbn, float roughness, float3 normal, float3 V, float3 direct_H, float3 indirect_dir) { LightGlitter g; const float glitter_filter_size = 0.7f; @@ -322,18 +245,14 @@ 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, - glitter_angular_neighbor_count, glitter_spatial_neighbor_count, - direct_micro_normal); + uv, uv_J, N, glitter_filter_size, 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, - glitter_angular_neighbor_count, glitter_spatial_neighbor_count, - indirect_micro_normal); + uv, uv_J, N, glitter_filter_size, indirect_micro_normal); g.indirect_NoL = max(1e-4, dot(normal, indirect_dir)); g.indirect_LoH = max(1e-4, dot(indirect_dir, indirect_H)); diff --git a/globals.cginc b/globals.cginc index d3d8958..88fb663 100755 --- a/globals.cginc +++ b/globals.cginc @@ -156,8 +156,6 @@ int _Details_UV_Channel; float _Glitter_Amount; float _Glitter_Roughness; float3 _Glitter_Tint; -float _Glitter_Spatial_Neighbor_Count; -float _Glitter_Angular_Neighbor_Count; #endif // _GLITTER #if defined(_UV_SCROLL) diff --git a/lighting.cginc b/lighting.cginc index 072e8d8..c1073d1 100755 --- a/lighting.cginc +++ b/lighting.cginc @@ -270,9 +270,7 @@ void GetLighting(v2f i, Pbr pbr, out LightData data) { data.indirect.L01b, data.indirect.dir); data.glitter = GetGlitterLighting( - _Glitter_Amount, _Glitter_Roughness, - _Glitter_Spatial_Neighbor_Count, _Glitter_Angular_Neighbor_Count, - i.uv01.xy, pbr.tbn, pbr.roughness, + _Glitter_Amount, _Glitter_Roughness, i.uv01.xy, pbr.tbn, pbr.roughness, pbr.normal, data.common.V, data.direct.H, glitter_indirect_dir); #endif |
