diff options
| author | yum <yum.food.vr@gmail.com> | 2026-03-30 15:25:43 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-03-30 15:25:43 -0700 |
| commit | 28d8c61b31954563b7aec754ca508665ca3b9df3 (patch) | |
| tree | 5bff4b22517d12f47cf11b5a6c00269536147653 | |
| parent | 4d02ae6522509f534beb5b4889bef47f58d19583 (diff) | |
asdf
| -rwxr-xr-x | 3ner.shader | 4 | ||||
| -rw-r--r-- | glitter.cginc | 80 |
2 files changed, 74 insertions, 10 deletions
diff --git a/3ner.shader b/3ner.shader index 66dfee8..3ec6e2d 100755 --- a/3ner.shader +++ b/3ner.shader @@ -661,8 +661,8 @@ 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, 4)) = 4 - [IntRange] _Glitter_Angular_Neighbor_Count("Angular Neighbor Count", Range(1, 4)) = 4 + [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 0588446..167490c 100644 --- a/glitter.cginc +++ b/glitter.cginc @@ -169,8 +169,59 @@ 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; +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. @@ -202,15 +253,28 @@ 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); - float2 base_i_a = clamp(round(x_a * res_a), 1, res_a-1); + int angular_neighbor_count_i = (int)angular_neighbor_count; + int spatial_neighbor_count_i = (int)spatial_neighbor_count; + + float2 angular_neighbor_offsets[8]; + GlitterNeighborOffsets(x_a, res_a, angular_neighbor_count_i, + angular_neighbor_offsets); + + float2 spatial_neighbor_offsets[8]; + GlitterNeighborOffsets(x_s, res_s, spatial_neighbor_count_i, + spatial_neighbor_offsets); + + float2 base_i_a = floor(x_a * res_a) + 0.5; [loop] - for (float j_a = 0.0; j_a < angular_neighbor_count; j_a += 1.0) { - float2 i_a = base_i_a + GlitterNeighborOffset(j_a); + 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 = round(x_s * res_s); + float2 base_i_s = floor(x_s * res_s) + 0.5; [loop] - for (float j_s = 0.0; j_s < spatial_neighbor_count; j_s += 1.0) { - float2 i_s = base_i_s + GlitterNeighborOffset(j_s); + 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; |
