yum-archive/Tooner

A toon shader for Unity's BIRP.

git clone https://git.yummers.dev/yum-archive/Tooner

yumAdd UV domain warping, box discard gimmicksb679eb3

master
7.1 KiB200 linesraw
1#include "cnlohr.cginc"
2#include "globals.cginc"
3#include "math.cginc"
4
5#ifndef __TROCHOID_MATH
6#define __TROCHOID_MATH
7
8#if defined(_TROCHOID)
9
10#define TROCH_POSITION_SCALE 0.1
11#define TROCH_Z_THETA_SCALE 0.0002
12#define TROCH_EPSILON 1e-5
13
14float3 cyl2_to_troch_map(float3 v)
15{
16  float R = abs(_Trochoid_R) > abs(_Trochoid_r) ? _Trochoid_R : _Trochoid_r;
17  float r = abs(_Trochoid_R) > abs(_Trochoid_r) ? _Trochoid_r : _Trochoid_R;
18  const float d = _Trochoid_d;
19  const float rrrr = (R - r) * R / r;
20
21#if 1
22  float rr_gcd = gcd(abs(round(R)), abs(round(r)));
23  float rr_lcm = (R * r) / rr_gcd;
24  float rr_lcm_factor = abs(rr_lcm / R);
25#else
26  float rr_lcm_factor = r;
27#endif
28
29  float toff = _Time[0] * _Trochoid_Speed;
30
31  float x =
32      cos((v.x / rr_lcm_factor) * R + toff * 2.3 + toff) * v.y * (R - r) * TROCH_POSITION_SCALE +
33      cos((v.x / rr_lcm_factor) * rrrr - toff * 2.9 + toff) * v.y * d * TROCH_POSITION_SCALE;
34  float y =
35      sin((v.x / rr_lcm_factor) * R - toff * 3.1 + toff) * v.y * (R - r) * TROCH_POSITION_SCALE -
36      sin((v.x / rr_lcm_factor) * rrrr + toff * 3.7 + toff) * v.y * d * TROCH_POSITION_SCALE;
37  float z =
38      ((v.x / rr_lcm_factor) * v.y * R * TROCH_Z_THETA_SCALE +
39      cos((v.x / rr_lcm_factor) * R * 5 + toff * 4.1 + toff) * v.y * TROCH_POSITION_SCALE +
40      v.z);
41
42  return float3(x, y, z);
43}
44
45float3 cyl_to_cyl2_map(float3 v)
46{
47  float power_scale = pow(100, _Trochoid_Radius_Power - 1);
48  return float3(v.x * .5, pow(v.y, _Trochoid_Radius_Power) * _Trochoid_Radius_Scale * power_scale, v.z * _Trochoid_Height_Scale);
49}
50
51float3 cart_to_cyl_map(float3 v)
52{
53  return float3(atan2(v.y, v.x), length(v.xy), v.z);
54}
55
56float3 cart_to_troch_map(float3 v)
57{
58  [branch]
59  if (_Trochoid_Distance_Culling_Enable) {
60    float3 activation_center = _Trochoid_Activation_Center;
61    float activation_radius = _Trochoid_Activation_Radius;
62    float cur_radius = length(_WorldSpaceCameraPos - activation_center);
63    [branch]
64    //if (cur_radius > activation_radius) {
65    if (getCenterCamPos().y > activation_center.y + activation_radius) {
66      return v;
67    }
68  }
69
70  return cyl2_to_troch_map(cyl_to_cyl2_map(cart_to_cyl_map(v)));
71}
72
73float3x3 cart_to_troch_jacobian(float3 v)
74{
75  float epsilon = 1e-5;
76  float3 df_dx = (cart_to_troch_map(v + float3(epsilon, 0, 0)) - cart_to_troch_map(v - float3(epsilon, 0, 0))) / (2 * epsilon);
77  float3 df_dy = (cart_to_troch_map(v + float3(0, epsilon, 0)) - cart_to_troch_map(v - float3(0, epsilon, 0))) / (2 * epsilon);
78  float3 df_dz = (cart_to_troch_map(v + float3(0, 0, epsilon)) - cart_to_troch_map(v - float3(0, 0, epsilon))) / (2 * epsilon);
79  return transpose(float3x3(df_dx, df_dy, df_dz));
80}
81
82// Compute partial derivatives of trochoid function with respect to cylindrical coordinates
83float3x3 cyl2_to_troch_jacobian(float3 v)
84{
85  const float R = _Trochoid_R;
86  const float r = _Trochoid_r;
87  const float d = _Trochoid_d;
88  const float rrrr = (R - r) * R / r;
89
90#if 1
91  float rr_gcd = gcd(abs(round(R)), abs(round(r)));
92  float rr_lcm = (R * r) / rr_gcd;
93  float rr_lcm_factor = rr_lcm / R;
94#else
95  float rr_lcm_factor = r;
96#endif
97
98  float toff = _Time[0] * _Trochoid_Speed;
99
100#if 1
101  float3 df_dt = float3(
102    -R * rr_lcm_factor * sin(v.x * rr_lcm_factor * R + toff * 2.3 + toff) * v.y * (R - r) * TROCH_POSITION_SCALE +
103    -rrrr * rr_lcm_factor * sin(v.x * rr_lcm_factor * rrrr - toff * 2.9 + toff) * v.y * d * TROCH_POSITION_SCALE,
104
105    R * rr_lcm_factor * cos(v.x * rr_lcm_factor * R - toff * 3.1 + toff) * v.y * (R - r) * TROCH_POSITION_SCALE -
106    rrrr * rr_lcm_factor * cos(v.x * rr_lcm_factor * rrrr + toff * 3.7 + toff) * v.y * d * TROCH_POSITION_SCALE,
107
108    v.y * R * TROCH_Z_THETA_SCALE -
109    R * rr_lcm_factor *5 * sin(v.x * rr_lcm_factor * R * 5 + toff * 4.1 + toff) * v.y * TROCH_POSITION_SCALE);
110#else
111  float3 df_dt = (cyl2_to_troch_map(v + float3(TROCH_EPSILON, 0, 0)) - cyl2_to_troch_map(v - float3(TROCH_EPSILON, 0, 0))) / (2 * TROCH_EPSILON);
112#endif
113
114#if 1
115  float3 df_dr = float3(
116    ((R - r) * rr_lcm_factor * cos(v.x * rr_lcm_factor * R + toff * 2.3) + d * rr_lcm_factor * cos((R - r) * v.x * rr_lcm_factor * R / r + toff * 2.9)) * TROCH_POSITION_SCALE,
117    ((R - r) * rr_lcm_factor * sin(v.x * rr_lcm_factor * R + toff * 3.1) - d * rr_lcm_factor * sin((R - r) * v.x * rr_lcm_factor * R / r + toff * 3.7)) * TROCH_POSITION_SCALE,
118    rr_lcm_factor * cos(v.x * rr_lcm_factor * R * 5 + toff * 4.1) * TROCH_POSITION_SCALE);
119#else
120  float3 df_dr = (cyl2_to_troch_map(v + float3(0, TROCH_EPSILON, 0)) - cyl2_to_troch_map(v - float3(0, TROCH_EPSILON, 0))) / (2 * TROCH_EPSILON);
121#endif
122
123#if 1
124  float3 df_dz = float3(
125    0,
126    0,
127    1);
128#else
129  float3 df_dz = (cyl2_to_troch_map(v + float3(0, 0, TROCH_EPSILON)) - cyl2_to_troch_map(v - float3(0, 0, TROCH_EPSILON))) / (2 * TROCH_EPSILON);
130#endif
131
132  float3x3 jacobian_cyl;
133  jacobian_cyl[0] = df_dt;
134  jacobian_cyl[1] = df_dr;
135  jacobian_cyl[2] = df_dz;
136  return transpose(jacobian_cyl);
137}
138
139float3x3 cyl_to_cyl2_jacobian(float3 v)
140{
141  // f(x, y, z) = <x, (y^_Trochoid_Radiu1_Power) * _Trochoid_Radius_Scale, z * _Trochoid_Height_Scale>
142#if 1
143  float3 df_dx = float3(1, 0, 0);
144  float3 df_dy = float3(0, _Trochoid_Radius_Power * pow(v.y, _Trochoid_Radius_Power - 1) * _Trochoid_Radius_Scale, 0);
145  float3 df_dz = float3(0, 0, _Trochoid_Height_Scale);
146#else
147  float3 df_dx = (cyl_to_cyl2_map(v + float3(TROCH_EPSILON, 0, 0)) - cyl_to_cyl2_map(v - float3(TROCH_EPSILON, 0, 0))) / (2 * TROCH_EPSILON);
148  float3 df_dy = (cyl_to_cyl2_map(v + float3(0, TROCH_EPSILON, 0)) - cyl_to_cyl2_map(v - float3(0, TROCH_EPSILON, 0))) / (2 * TROCH_EPSILON);
149  float3 df_dz = (cyl_to_cyl2_map(v + float3(0, 0, TROCH_EPSILON)) - cyl_to_cyl2_map(v - float3(0, 0, TROCH_EPSILON))) / (2 * TROCH_EPSILON);
150#endif
151  float3x3 jacobian_cyl_to_cyl2;
152  jacobian_cyl_to_cyl2[0] = df_dx;
153  jacobian_cyl_to_cyl2[1] = df_dy;
154  jacobian_cyl_to_cyl2[2] = df_dz;
155  return transpose(jacobian_cyl_to_cyl2);
156}
157
158// Compute partial derivatives of transform from cartesian to cylindrical coordinates
159float3x3 cart_to_cyl_jacobian(float3 v)
160{
161  // Compute partial derivatives of transform from cartesian to cylindrical coordinates
162  // return float3(atan2(v.y, v.x), length(v.xy), v.z);
163  // theta = atan2(y, x)
164#if 1
165  float3 dtheta_dcart = float3(
166    -v.y / dot(v.xy, v.xy),
167    v.x / dot(v.xy, v.xy),
168    0);
169#else
170  float3 dtheta_dcart = (cart_to_cyl_map(v + float3(TROCH_EPSILON, 0, 0)) - cart_to_cyl_map(v - float3(TROCH_EPSILON, 0, 0))) / (2 * TROCH_EPSILON);
171#endif
172
173  // radius = (x^2 + y^2)^(1/2)
174#if 1
175  float3 dr_dcart = float3(
176    v.x / sqrt(v.x * v.x + v.y * v.y),
177    v.y / sqrt(v.x * v.x + v.y * v.y),
178    0);
179#else
180  float3 dr_dcart = (cart_to_cyl_map(v + float3(0, TROCH_EPSILON, 0)) - cart_to_cyl_map(v - float3(0, TROCH_EPSILON, 0))) / (2 * TROCH_EPSILON);
181#endif
182
183#if 1
184  float3 dz_dcart = float3(
185    0,
186    0,
187    1);
188#else
189  float3 dz_dcart = (cart_to_cyl_map(v + float3(0, 0, TROCH_EPSILON)) - cart_to_cyl_map(v - float3(0, 0, TROCH_EPSILON))) / (2 * TROCH_EPSILON);
190#endif
191  float3x3 jacobian_cart_to_cyl;
192  jacobian_cart_to_cyl[0] = dtheta_dcart;
193  jacobian_cart_to_cyl[1] = dr_dcart;
194  jacobian_cart_to_cyl[2] = dz_dcart;
195  return transpose(jacobian_cart_to_cyl);
196}
197
198#endif  // _TROCHOID
199
200#endif  // __TROCHOID_MATH