yum-archive/2ner

A toon shader for Unity's BIRP.

git clone https://git.yummers.dev/yum-archive/2ner

yumRemove worldPos interpolator4885fb4

master
3.1 KiB90 linesraw
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