yum-archive/2ner
A toon shader for Unity's BIRP.
git clone https://git.yummers.dev/yum-archive/2ner
72806ff
master
1#ifndef __EYES_INC 2#define __EYES_INC 3 4#include "globals.cginc" 5#include "interpolators.cginc" 6#include "math.cginc" 7#include "oklab.cginc" 8#include "quilez.cginc" 9 10#if defined(_EYE_EFFECT_00) 11 12struct EyeEffectOutput { 13 float4 albedo; 14 float3 emission; 15 float3 normal; 16 float3 worldPos; 17 float4 fog; 18 float2 uv; 19 float metallic; 20 float roughness; 21}; 22 23float eye_effect_00_map(float3 p) 24{ 25 float edge = _Gimmick_Eye_Effect_00_Edge_Length; 26 float thickness = edge*10; 27 return distance_from_round_box(p - float3(0, thickness*.99, 0), float3(edge, thickness, edge), edge * .1); 28} 29 30float3 eye_effect_00_nudge_p(float3 p, float3 which) 31{ 32 float noise = _Gimmick_Eye_Effect_00_Noise.SampleLevel(linear_repeat_s, which.xz * _Gimmick_Eye_Effect_00_Period.xz * .005 + _Time[0] * .05, 0); 33 return p - float3(0, noise * .01, 0); 34} 35 36float eye_effect_00_map_dr( 37 float3 p, 38 float3 period, 39 float3 count, 40 out float3 which 41 ) 42{ 43 which = floor(p / period); 44 // Direction to nearest neighboring cell. 45 float3 min_d = p - period * which; 46 float3 o = sign(min_d); 47 48 float d = 1E9; 49 float3 which_tmp = which; 50 for (uint xi = 0; xi < 1; xi++) 51 for (uint zi = 0; zi < 1; zi++) 52 { 53 float3 rid = which + float3(xi, 0, zi) * o; 54 rid = clamp(rid, ceil(-(count)*0.5), floor((count-1)*0.5)); 55 float3 r = p - period * rid; 56 r = eye_effect_00_nudge_p(r, rid); 57 float cur_d = eye_effect_00_map(r); 58 which_tmp = cur_d < d ? rid : which_tmp; 59 d = min(d, cur_d); 60 } 61 62 which = which_tmp; 63 return d; 64} 65 66float3 eye_effect_00_calc_normal(float3 p) 67{ 68 float3 small_step = float3(1E-5, 0.0, 0.0); 69 float3 which; 70 float center = eye_effect_00_map_dr(p, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which); 71 return normalize(float3( 72 eye_effect_00_map_dr(p + small_step.xyz, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which) - center, 73 eye_effect_00_map_dr(p + small_step.zxy, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which) - center, 74 eye_effect_00_map_dr(p + small_step.yzx, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which) - center 75 )); 76} 77 78// derived from downstairs_02.cginc effect 02 79EyeEffectOutput EyeEffect_00(inout v2f i) 80{ 81 float3 camera_position = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1)); 82 float3 ro = i.objPos; 83 float3 rd = normalize(i.objPos - camera_position); 84 85 float2 warping_speed_vector = normalize(float2(97, 101)); 86 for (uint ii = 0; ii < _Gimmick_Eye_Effect_00_Domain_Warping_Octaves; ii++) 87 { 88 float2 noise = _Gimmick_Eye_Effect_00_Noise.SampleLevel(linear_repeat_s, ro.xz * _Gimmick_Eye_Effect_00_Domain_Warping_Scale + _Time[0] * _Gimmick_Eye_Effect_00_Domain_Warping_Speed * warping_speed_vector, 0) * 2 - 1; 89 ro.xz += noise * _Gimmick_Eye_Effect_00_Domain_Warping_Strength; 90 } 91 92 #define eye_effect_00_MARCH_STEPS 1 93 float total_distance_traveled = 0.0; 94 const float MINIMUM_HIT_DISTANCE = 1E-4; 95 const float MAXIMUM_TRACE_DISTANCE = 1E-1; 96 float distance_to_closest; 97 float3 which; 98 [loop] 99 for (uint ii = 0; ii < eye_effect_00_MARCH_STEPS; ii++) 100 { 101 float3 current_position = ro + total_distance_traveled * rd; 102 distance_to_closest = eye_effect_00_map_dr(current_position, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which); 103 total_distance_traveled += distance_to_closest; 104 if (distance_to_closest < MINIMUM_HIT_DISTANCE || 105 total_distance_traveled > MAXIMUM_TRACE_DISTANCE) { 106 break; 107 } 108 } 109 110 bool hit = distance_to_closest < MINIMUM_HIT_DISTANCE; 111 float3 final_position = ro + total_distance_traveled * rd; 112 float3 normal = hit ? UnityObjectToWorldNormal(eye_effect_00_calc_normal(final_position)) : i.normal; 113 114 float3 color = hit ? 1 : 0; 115 116 EyeEffectOutput o; 117 o.albedo = float4(color, hit); 118 o.emission = o.albedo; 119 o.fog = 0; 120 o.normal = normal; 121 o.metallic = 0; 122 o.roughness = 0; 123 // Depth gets all fucked up unless we use i.objPos instead of ro, which is domain warped. 124 o.worldPos = mul(unity_ObjectToWorld, float4(i.objPos + rd * total_distance_traveled, 1)); 125 o.uv = ((which.xz + _Gimmick_Eye_Effect_00_Count.xz * .5) / _Gimmick_Eye_Effect_00_Count.xz) * float2(1, -1); 126 return o; 127} 128 129#endif // _EYE_EFFECT_00 130 131#endif // __EYES_INC 132 133