yum-archive/Tooner
A toon shader for Unity's BIRP.
git clone https://git.yummers.dev/yum-archive/Tooner
b679eb3
master
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