diff options
| author | yum <yum.food.vr@gmail.com> | 2025-02-20 19:57:54 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-02-20 19:57:54 -0800 |
| commit | 72806ff9f71bd98973f51a4b67de00c056fe8d89 (patch) | |
| tree | 2a7d1ed7a8cbb563ed79ef18e363ef3b4efccd3a /eyes.cginc | |
| parent | 14cdf12e17d2b17676135457e42bde391ff3f313 (diff) | |
add eye shader
Diffstat (limited to 'eyes.cginc')
| -rw-r--r-- | eyes.cginc | 133 |
1 files changed, 133 insertions, 0 deletions
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
+
+
|
