yum-archive/2ner

A toon shader for Unity's BIRP.

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

yumadd ltcgi, alpha multiplierf478606

master
1.8 KiB57 linesraw
1#ifndef __SSFD_INC
2#define __SSFD_INC
3
4#include "globals.cginc"
5
6float ssfd(float2 uv, float scale, float max_fwidth, float2 uv_offset, texture3D noise)
7{
8  //float uv_fw = fwidth(uv.x) + fwidth(uv.y);
9  // Original paper uses SVD instead of fwidth.
10  float2x2 M = float2x2(ddx(uv), ddy(uv));
11  float2x2 MtM = mul(transpose(M), M);
12  float trace = MtM[0][0] + MtM[1][1];
13  float det = determinant(MtM);
14  // Calculate eigenvalues using quadratic formula.
15  float tmp = sqrt(trace * trace - 4 * det);
16  float e1 = (trace + tmp) * 0.5;
17  float e2 = (trace - tmp) * 0.5;
18  float2 singular_values = sqrt(float2(e1, e2));
19  // Logic from original paper: the smaller eigenvalue corresponds to the
20  // largest amount of stretching, so we use it to determine when to
21  // subdivide.
22  float uv_fw = singular_values.y;
23  uv_fw *= scale;
24
25  uint width, height, depth;
26  noise.GetDimensions(width, height, depth);
27  float bayer_res = sqrt(depth);
28
29  // Suppose max_fwidth is 1.
30  // uv_fw is 16. That means UV is changing a lot per pixel. That means we want to shrink the scale of the UV.
31  // Factor is 16.
32  // log_2(factor) is 4.
33  // Divide original by 16.
34  float fw_factor = uv_fw / max_fwidth;
35  // log_b(x) = log_a(x) / log_a(b)
36  float fractal_level = log2(fw_factor) / log2(bayer_res);
37  float fractal_level_floor = floor(fractal_level);
38  float fractal_remainder = fractal_level - fractal_level_floor;
39
40  uv *= pow(bayer_res, -fractal_level_floor);
41  uv += uv_offset * pow(bayer_res, -fractal_level_floor);
42
43  float n_layers = depth;
44  float not_used_lo = 1/(n_layers*2);
45  float not_used_hi = 1 - not_used_lo;
46
47  float uvw = (not_used_hi - not_used_lo) * (1 - fractal_remainder) + not_used_lo;
48
49  float3 uv_3d = float3(uv, uvw);
50
51  float dither = noise.SampleLevel(linear_repeat_s, uv_3d, 0);
52
53  return dither;
54}
55
56#endif  // __SSFD_INC
57