From 72806ff9f71bd98973f51a4b67de00c056fe8d89 Mon Sep 17 00:00:00 2001 From: yum Date: Thu, 20 Feb 2025 19:57:54 -0800 Subject: add eye shader --- eyes.cginc | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 eyes.cginc (limited to 'eyes.cginc') diff --git a/eyes.cginc b/eyes.cginc new file mode 100644 index 0000000..81456d2 --- /dev/null +++ b/eyes.cginc @@ -0,0 +1,133 @@ +#ifndef __EYES_INC +#define __EYES_INC + +#include "globals.cginc" +#include "interpolators.cginc" +#include "math.cginc" +#include "oklab.cginc" +#include "quilez.cginc" + +#if defined(_EYE_EFFECT_00) + +struct EyeEffectOutput { + float4 albedo; + float3 emission; + float3 normal; + float3 worldPos; + float4 fog; + float2 uv; + float metallic; + float roughness; +}; + +float eye_effect_00_map(float3 p) +{ + float edge = _Gimmick_Eye_Effect_00_Edge_Length; + float thickness = edge*10; + return distance_from_round_box(p - float3(0, thickness*.99, 0), float3(edge, thickness, edge), edge * .1); +} + +float3 eye_effect_00_nudge_p(float3 p, float3 which) +{ + float noise = _Gimmick_Eye_Effect_00_Noise.SampleLevel(linear_repeat_s, which.xz * _Gimmick_Eye_Effect_00_Period.xz * .005 + _Time[0] * .05, 0); + return p - float3(0, noise * .01, 0); +} + +float eye_effect_00_map_dr( + float3 p, + float3 period, + float3 count, + out float3 which + ) +{ + which = floor(p / period); + // Direction to nearest neighboring cell. + float3 min_d = p - period * which; + float3 o = sign(min_d); + + float d = 1E9; + float3 which_tmp = which; + for (uint xi = 0; xi < 1; xi++) + for (uint zi = 0; zi < 1; zi++) + { + float3 rid = which + float3(xi, 0, zi) * o; + rid = clamp(rid, ceil(-(count)*0.5), floor((count-1)*0.5)); + float3 r = p - period * rid; + r = eye_effect_00_nudge_p(r, rid); + float cur_d = eye_effect_00_map(r); + which_tmp = cur_d < d ? rid : which_tmp; + d = min(d, cur_d); + } + + which = which_tmp; + return d; +} + +float3 eye_effect_00_calc_normal(float3 p) +{ + float3 small_step = float3(1E-5, 0.0, 0.0); + float3 which; + float center = eye_effect_00_map_dr(p, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which); + return normalize(float3( + eye_effect_00_map_dr(p + small_step.xyz, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which) - center, + eye_effect_00_map_dr(p + small_step.zxy, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which) - center, + eye_effect_00_map_dr(p + small_step.yzx, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which) - center + )); +} + +// derived from downstairs_02.cginc effect 02 +EyeEffectOutput EyeEffect_00(inout v2f i) +{ + float3 camera_position = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1)); + float3 ro = i.objPos; + float3 rd = normalize(i.objPos - camera_position); + + float2 warping_speed_vector = normalize(float2(97, 101)); + for (uint ii = 0; ii < _Gimmick_Eye_Effect_00_Domain_Warping_Octaves; ii++) + { + 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; + ro.xz += noise * _Gimmick_Eye_Effect_00_Domain_Warping_Strength; + } + + #define eye_effect_00_MARCH_STEPS 1 + float total_distance_traveled = 0.0; + const float MINIMUM_HIT_DISTANCE = 1E-4; + const float MAXIMUM_TRACE_DISTANCE = 1E-1; + float distance_to_closest; + float3 which; + [loop] + for (uint ii = 0; ii < eye_effect_00_MARCH_STEPS; ii++) + { + float3 current_position = ro + total_distance_traveled * rd; + distance_to_closest = eye_effect_00_map_dr(current_position, _Gimmick_Eye_Effect_00_Period.xyz, _Gimmick_Eye_Effect_00_Count.xyz, which); + total_distance_traveled += distance_to_closest; + if (distance_to_closest < MINIMUM_HIT_DISTANCE || + total_distance_traveled > MAXIMUM_TRACE_DISTANCE) { + break; + } + } + + bool hit = distance_to_closest < MINIMUM_HIT_DISTANCE; + float3 final_position = ro + total_distance_traveled * rd; + float3 normal = hit ? UnityObjectToWorldNormal(eye_effect_00_calc_normal(final_position)) : i.normal; + + float3 color = hit ? 1 : 0; + + EyeEffectOutput o; + o.albedo = float4(color, hit); + o.emission = o.albedo; + o.fog = 0; + o.normal = normal; + o.metallic = 0; + o.roughness = 0; + // Depth gets all fucked up unless we use i.objPos instead of ro, which is domain warped. + o.worldPos = mul(unity_ObjectToWorld, float4(i.objPos + rd * total_distance_traveled, 1)); + o.uv = ((which.xz + _Gimmick_Eye_Effect_00_Count.xz * .5) / _Gimmick_Eye_Effect_00_Count.xz) * float2(1, -1); + return o; +} + +#endif // _EYE_EFFECT_00 + +#endif // __EYES_INC + + -- cgit v1.2.3