yum-archive/2ner
A toon shader for Unity's BIRP.
git clone https://git.yummers.dev/yum-archive/2ner
4885fb4
master
1#ifndef __GLITTER_INC 2#define __GLITTER_INC 3 4#include "math.cginc" 5#include "pema99.cginc" 6#include "quilez.cginc" 7 8struct GlitterParams { 9 float4 color; 10 float2 uv_channel; 11 uint layers; 12 float cell_size; 13 float size; 14 float major_minor_ratio; 15 float angle_randomization_range; 16 float center_randomization_range; 17 float size_randomization_range; 18 float existence_chance; 19 float seed; 20#if defined(_GLITTER_ANGLE_LIMIT) 21 float angle_limit; 22 float angle_limit_transition_width; 23#endif 24#if defined(_GLITTER_MASK) 25 float mask; 26#endif 27}; 28 29static const float2 glitter_offset_vectors[6] = { 30 float2(0.0, 1.0), // 0 degrees 31 float2(0.866025, 0.5), // 60 degrees 32 float2(0.866025, -0.5), // 120 degrees 33 float2(0.0, -1.0), // 180 degrees 34 float2(-0.866025, -0.5), // 240 degrees 35 float2(-0.866025, 0.5) // 300 degrees 36}; 37 38 39float4 getGlitter(v2f i, f2f f, GlitterParams params, float3 normal) { 40 float c_acc = 0; 41 [loop] 42 for (uint layer_i = 0; layer_i < params.layers; layer_i++) { 43 float2 uv = get_uv_by_channel(i, params.uv_channel); 44 float2 p = uv + glitter_offset_vectors[layer_i] * params.cell_size * 0.5; 45 46 float3 cell_id = float3(floor(p / params.cell_size), layer_i); 47 float cell_rand = rand3(cell_id*.0001+params.seed); 48 float cell_rand2 = rand3((cell_id+1)*.0001+params.seed); 49 p = glsl_mod(p, params.cell_size); 50 p -= params.cell_size * 0.5; 51 // Apply center randomization 52 p.x += (cell_rand * 2 - 1) * params.center_randomization_range * (params.cell_size * (1 - params.size)) * 0.5; 53 // Apply angle randomization 54 float2x2 p_rot = float2x2( 55 cos(cell_rand * TAU * params.angle_randomization_range), -sin(cell_rand * TAU * params.angle_randomization_range), 56 sin(cell_rand * TAU * params.angle_randomization_range), cos(cell_rand * TAU * params.angle_randomization_range) 57 ); 58 p = mul(p_rot, p); 59 60 // Draw ellipses 61 // First arg is position to evaluate distance at. We project onto z=0. 62 // Second arg is the size of the ellipse. We set z to cell size because I 63 // think setting it to 0 would probably create fucked up curvature. 64 float3 size = float3(params.size * float2(params.major_minor_ratio, 1) * params.cell_size * 0.5, params.cell_size); 65 // Apply size randomization 66 size *= (1 - cell_rand * params.size_randomization_range); 67 // TODO find a good 2d ellipse sdf 68 float d = distance_from_ellipsoid(float3(p, 0), size); 69 // TODO antialias using fwidth 70 float c = (d < 0) * params.color.a; 71 c *= (cell_rand2 < params.existence_chance); 72 c_acc = c + (1 - c) * c_acc; 73 } 74#if defined(_GLITTER_ANGLE_LIMIT) 75 float VdotN = dot(-f.viewDir, normal); 76 float angle_mask = smoothstep( 77 cos(params.angle_limit * PI), 78 cos(params.angle_limit * (1 - params.angle_limit_transition_width) * PI), 79 VdotN); 80 c_acc *= angle_mask; 81#endif 82#if defined(_GLITTER_MASK) 83 c_acc *= params.mask; 84#endif 85 return float4(params.color.rgb, c_acc); 86} 87 88#endif // __GLITTER_INC 89 90