summaryrefslogtreecommitdiffstats
path: root/downstairs_02.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-01-01 17:42:11 -0800
committeryum <yum.food.vr@gmail.com>2025-01-01 17:42:11 -0800
commitdf8aa8f2b59bad2269f9228d5ed25e7454ca3971 (patch)
tree9ae33b187458a2c5e5245c65208aad68a526ee4b /downstairs_02.cginc
parent4880e4125f529496a48269eda545ca006db17646 (diff)
More work on downstairs 2 gimmicks
* Use float param to select which gimmick to show * Add colors & domain warping to gimmick 2 * Also optimize it. Colors let us avoid 4-fold neighbor check fanout * Add rough/unoptimized version of gimmick 3
Diffstat (limited to 'downstairs_02.cginc')
-rw-r--r--downstairs_02.cginc261
1 files changed, 212 insertions, 49 deletions
diff --git a/downstairs_02.cginc b/downstairs_02.cginc
index 844731c..56884da 100644
--- a/downstairs_02.cginc
+++ b/downstairs_02.cginc
@@ -4,6 +4,7 @@
#include "iq_sdf.cginc"
#include "math.cginc"
#include "oklab.cginc"
+#include "poi.cginc"
#ifndef __DOWNSTAIRS_02_INC
#define __DOWNSTAIRS_02_INC
@@ -113,10 +114,12 @@ Gimmick_DS2_Output Gimmick_DS2_00(v2f i)
uv *= 2;
uv -= 1;
float2 warping_speed_vector = normalize(float2(97, 101));
+ const float t = _Time[0] * 10;
+ const float warping_strength_anim = smoothstep(0, 1, sin(t*0.31));
for (uint ii = 0; ii < _Gimmick_DS2_00_Domain_Warping_Octaves; ii++)
{
float2 noise = _Gimmick_DS2_Noise.SampleLevel(linear_repeat_s, uv * _Gimmick_DS2_00_Domain_Warping_Scale + _Time[0] * _Gimmick_DS2_00_Domain_Warping_Speed * warping_speed_vector, 0);
- uv += noise * _Gimmick_DS2_00_Domain_Warping_Strength;
+ uv += noise * _Gimmick_DS2_00_Domain_Warping_Strength * warping_strength_anim;
}
float3 camera_position = float3(0.0, 0.0, -5.0);
@@ -127,8 +130,9 @@ Gimmick_DS2_Output Gimmick_DS2_00(v2f i)
float which;
bool hit = __ds2_00_march(ro, rd, normal, which);
- float3 shaded_color = LRGBtoOKLCH(float3(0.7, 0, 0));
- shaded_color[2] = which * TAU * 1.1 + _Time[1];
+ float3 shaded_color = LRGBtoOKLCH(float3(1, .05, .12));
+ shaded_color[0] += smoothstep(-1, 1, sin(t*2.3 + which * TAU * 1.1)) * .5;
+ shaded_color[2] += smoothstep(-1, 1, sin(t*2.9 + which * TAU * 1.1)) * .05;
shaded_color = OKLCHtoLRGB(shaded_color);
shaded_color *= hit;
@@ -255,10 +259,34 @@ Gimmick_DS2_Output Gimmick_DS2_01(inout v2f i)
return o;
}
-float ds2_02_map(float3 p, out float which)
+// which == -10 -> capped cylinder
+// which == 1 -> cylinder
+float ds2_10_map_repeated(float3 p, out float which)
{
float depth = .2;
- which = 0;
+ float d0 = distance_from_capped_cylinder(abs(p) - float3(0, .45, depth * .5), .05, .02);
+ float d1 = distance_from_cylinder(abs(p) - float3(0, 0, depth * .5), float3(0, 0, .015));
+ which = d0 < d1 ? -10 : 1;
+ return min(d0, d1);
+}
+
+float ds2_10_map_dr(
+ float3 p,
+ float3 period,
+ float3 count,
+ out float which
+ )
+{
+ which = round(p / period);
+ float3 rid = clamp(which, ceil(-(count)*0.5), floor((count-1)*0.5));
+ float3 r = p - period * rid;
+ return ds2_10_map_repeated(r, which);
+}
+
+float ds2_10_map(float3 p, out float which)
+{
+ float depth = .2;
+ which = -10;
// Create frame for lights.
float d0 = distance_from_box(p - float3(0, 0, depth), float3(.50, .50, depth));
@@ -266,50 +294,42 @@ float ds2_02_map(float3 p, out float which)
float d2 = op_sub(d1, d0);
// Create lights.
- float light_spacing = .12;
- float d3 = d2;
- which = -1;
- for (uint i = 0; i < 3; i++) {
- float d4 = distance_from_capped_cylinder(abs(p) - float3(i * light_spacing + light_spacing * .5, .45, depth * .5), .05, .03);
- d3 = min(d3, d4);
- }
- for (uint i = 0; i < 3; i++) {
- float d4 = distance_from_cylinder(abs(p) - float3(i * light_spacing + light_spacing * .5, 0, depth * .5), float3(0, 0, .025));
- which = d4 < d3 ? ((int) i + 1) * 2 + (sign(p.x) > 0 ? 1 : 0) : which;
- d3 = min(d3, d4);
- }
+ float light_spacing = .17;
+ float which_tmp;
+ float d3 = ds2_10_map_dr(p, float3(light_spacing, 1, 1), float3(5, 1, 1), which_tmp);
+ which = d3 < d2 ? which_tmp : which;
- return d3;
+ return min(d2, d3);
}
-float3 ds2_02_calc_normal(float3 p)
+float3 ds2_10_calc_normal(float3 p)
{
float3 small_step = float3(1E-5, 0.0, 0.0);
float which;
- float center = ds2_02_map(p, which);
+ float center = ds2_10_map(p, which);
return normalize(float3(
- ds2_02_map(p + small_step.xyz, which) - center,
- ds2_02_map(p + small_step.zxy, which) - center,
- ds2_02_map(p + small_step.yzx, which) - center
+ ds2_10_map(p + small_step.xyz, which) - center,
+ ds2_10_map(p + small_step.zxy, which) - center,
+ ds2_10_map(p + small_step.yzx, which) - center
));
}
-Gimmick_DS2_Output Gimmick_DS2_02(inout v2f i)
+Gimmick_DS2_Output Gimmick_DS2_10(inout v2f i)
{
float3 camera_position = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1));
float3 ro = i.objPos;
float3 rd = normalize(i.objPos - camera_position);
- #define DS2_02_MARCH_STEPS 30
+ #define DS2_10_MARCH_STEPS 30
float total_distance_traveled = 0.0;
const float MINIMUM_HIT_DISTANCE = 1E-3;
- const float MAXIMUM_TRACE_DISTANCE = 30.0;
+ const float MAXIMUM_TRACE_DISTANCE = 1;
float distance_to_closest;
float which;
- for (uint ii = 0; ii < DS2_02_MARCH_STEPS; ii++)
+ for (uint ii = 0; ii < DS2_10_MARCH_STEPS; ii++)
{
float3 current_position = ro + total_distance_traveled * rd;
- distance_to_closest = ds2_02_map(current_position, which);
+ distance_to_closest = ds2_10_map(current_position, which);
total_distance_traveled += distance_to_closest;
if (distance_to_closest < MINIMUM_HIT_DISTANCE ||
total_distance_traveled > MAXIMUM_TRACE_DISTANCE) {
@@ -318,60 +338,192 @@ Gimmick_DS2_Output Gimmick_DS2_02(inout v2f i)
}
float3 normal = i.normal;
+ const float3 final_position = ro + total_distance_traveled * rd;
bool hit = distance_to_closest < MINIMUM_HIT_DISTANCE;
- float3 color = (which == -1 ? 0.01 : 1.5);
+ float3 color = (which == -10 ? 0.01 : 1.5);
if (hit) {
- normal = ds2_02_calc_normal(ro + total_distance_traveled * rd);
+ normal = ds2_10_calc_normal(final_position);
normal = UnityObjectToWorldNormal(normal);
}
Gimmick_DS2_Output o;
- o.albedo = hit ? float4(color, 1) : 0;
+ //o.albedo = hit ? float4(color, 1) : 0;
+ o.albedo = hit ? 1 : 0;
o.emission = color;
o.normal = normal;
o.metallic = 0;
o.roughness = 0.3;
- o.worldPos = mul(unity_ObjectToWorld, float4(ro + total_distance_traveled * rd, 1));
+ o.worldPos = mul(unity_ObjectToWorld, float4(final_position, 1));
+
return o;
}
-float ds2_03_map(float3 p)
+float ds2_02_map(float3 p)
{
- float edge = _Gimmick_DS2_03_Edge_Length;
+ float edge = _Gimmick_DS2_02_Edge_Length;
float thickness = edge*10;
return distance_from_round_box(p - float3(0, 0, thickness*.99), float3(edge, edge, thickness), edge * .1);
}
-float3 ds2_03_nudge_p(float3 p, float3 which)
+float3 ds2_02_nudge_p(float3 p, float3 which)
{
- float noise = _Gimmick_DS2_Noise.SampleLevel(linear_repeat_s, which.xy * _Gimmick_DS2_03_Period.xy * .2 + _Time[0] * .1, 0);
+ float noise = _Gimmick_DS2_Noise.SampleLevel(linear_repeat_s, which.xy * _Gimmick_DS2_02_Period.xy * .2 + _Time[0] * .1, 0);
return p - float3(0, 0, noise * .01);
- //return p + sin(e*TAU+_Time[0]*4) * _Gimmick_DS2_03_Edge_Length * .2 - noise;
+ //return p + sin(e*TAU+_Time[0]*4) * _Gimmick_DS2_02_Edge_Length * .2 - noise;
//return p;
}
-float ds2_03_map_dr(
+float ds2_02_map_dr(
float3 p,
float3 period,
float3 count,
out float3 which
)
{
- which = round(p / period);
+ 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 < 2; xi++)
- for (uint yi = 0; yi < 2; yi++)
+ for (uint xi = 0; xi < 1; xi++)
+ for (uint yi = 0; yi < 1; yi++)
{
float3 rid = which + float3(xi, yi, 0) * o;
rid = clamp(rid, ceil(-(count)*0.5), floor((count-1)*0.5));
float3 r = p - period * rid;
+ r = ds2_02_nudge_p(r, rid);
+ float cur_d = ds2_02_map(r);
+ which_tmp = cur_d < d ? rid : which_tmp;
+ d = min(d, cur_d);
+ }
+
+ which = which_tmp;
+ return d;
+}
+
+float3 ds2_02_calc_normal(float3 p)
+{
+ float3 small_step = float3(1E-5, 0.0, 0.0);
+ float3 which;
+ float center = ds2_02_map_dr(p, _Gimmick_DS2_02_Period.xyz, _Gimmick_DS2_02_Count.xyz, which);
+ return normalize(float3(
+ ds2_02_map_dr(p + small_step.xyz, _Gimmick_DS2_02_Period.xyz, _Gimmick_DS2_02_Count.xyz, which) - center,
+ ds2_02_map_dr(p + small_step.zxy, _Gimmick_DS2_02_Period.xyz, _Gimmick_DS2_02_Count.xyz, which) - center,
+ ds2_02_map_dr(p + small_step.yzx, _Gimmick_DS2_02_Period.xyz, _Gimmick_DS2_02_Count.xyz, which) - center
+ ));
+}
+
+Gimmick_DS2_Output Gimmick_DS2_02(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_DS2_02_Domain_Warping_Octaves; ii++)
+ {
+ float2 noise = _Gimmick_DS2_Noise.SampleLevel(linear_repeat_s, ro.xy * _Gimmick_DS2_02_Domain_Warping_Scale + _Time[0] * _Gimmick_DS2_02_Domain_Warping_Speed * warping_speed_vector, 0);
+ ro.xy += noise * _Gimmick_DS2_02_Domain_Warping_Strength;
+ }
+
+ #define DS2_02_MARCH_STEPS 40
+ 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;
+ for (uint ii = 0; ii < DS2_02_MARCH_STEPS; ii++)
+ {
+ float3 current_position = ro + total_distance_traveled * rd;
+ distance_to_closest = ds2_02_map_dr(current_position, _Gimmick_DS2_02_Period.xyz, _Gimmick_DS2_02_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(ds2_02_calc_normal(final_position)) : i.normal;
+
+ float3 light_dir = normalize(float3(0.5, -0.5, -0.5));
+ float3 light_color = float3(1, 1, 1);
+ float ndotl = saturate(dot(normal, light_dir));
+ float wrap_factor = 0.7;
+ float4 wrapped = pow(max(1E-4, (ndotl + wrap_factor) / (1 + wrap_factor)), 1 + wrap_factor);
+ float3 light_intensity = light_color * wrapped;
+ float3 color = hit ? 1 : 0;
+ color *= _Gimmick_DS2_Noise.SampleLevel(linear_repeat_s, which.xy * _Gimmick_DS2_02_Period.xy * .1 + _Time[0] * warping_speed_vector * .01, 0);
+ // Reinterpret greyscale as OKLCH.
+ //color = saturate(color * 2 - (sin(_Time[0] + 1) * .5 + .6));
+ color = saturate(color * 2 - 0.4);
+ float hue_noise = _Gimmick_DS2_Noise.SampleLevel(linear_repeat_s, which.xy * _Gimmick_DS2_02_Period.xy * .1 - _Time[0] * warping_speed_vector.yx * .02, 0);
+ color = OKLCHtoLRGB(float3(
+ color.x * 20,
+ color.x * 10,
+ color.x * TAU * .2 + hue_noise * 10 + _Time[0] * 10
+ ));
+ color = max(color, 0.005);
+ color *= light_intensity;
+
+ Gimmick_DS2_Output o;
+ o.albedo = float4(color, 1);
+ o.emission = o.albedo;
+ 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));
+ return o;
+}
+
+float ds2_03_map(float3 p, float3 rid)
+{
+ float edge = _Gimmick_DS2_03_Edge_Length;
+ float thickness = edge * .5;
+
+ float3 pp = p - float3(0, 0, thickness*1);
+
+ float wave_str = 0;
+ float t = _Time[3];
+ for (uint i = 0; i < 6; i++) {
+ float wave_r = fmod(t + 50 * i, 300) - 5;
+ float wave_d2 = dot(rid.xy, rid.xy) * .01 - wave_r;
+ wave_str += (1 / (1 + exp(-wave_d2*.3)) - 0.5) * 2;
+ }
+ wave_str += (_Gimmick_DS2_Noise.SampleLevel(linear_repeat_s, rid.xy * .001 + t *.001, 0) * 2 - 1) * .75;
+ float4 quat = get_quaternion(float3(0, 1, 0), wave_str * PI);
+ pp = rotate_vector(pp, quat);
+ return distance_from_hex_prism(pp, float2(edge, thickness));
+}
+
+float3 ds2_03_nudge_p(float3 p, float3 which)
+{
+ return p - float3(_Gimmick_DS2_03_Period.x, _Gimmick_DS2_03_Period.y * (which.x % 2 == 0), 0) * .5;
+}
+
+float ds2_03_map_dr(
+ float3 p,
+ float3 period,
+ float3 count,
+ out float3 which
+ )
+{
+ which = floor(p / period);
+
+ float d = 1E9;
+ float3 which_tmp = which;
+ for (uint xi = 0; xi < 3; xi++)
+ for (uint yi = 0; yi < 3; yi++)
+ {
+ float3 rid = which + (float3(xi, yi, 0) - 1);
+ rid = clamp(rid, ceil(-(count)*0.5), floor((count-1)*0.5));
+ float3 r = p - period * rid;
r = ds2_03_nudge_p(r, rid);
- float cur_d = ds2_03_map(r);
+ float cur_d = ds2_03_map(r, rid);
which_tmp = cur_d < d ? rid : which_tmp;
d = min(d, cur_d);
}
@@ -398,10 +550,17 @@ Gimmick_DS2_Output Gimmick_DS2_03(inout v2f i)
float3 ro = i.objPos;
float3 rd = normalize(i.objPos - camera_position);
- #define DS2_03_MARCH_STEPS 30
+ float2 warping_speed_vector = normalize(float2(97, 101));
+ for (uint ii = 0; ii < _Gimmick_DS2_03_Domain_Warping_Octaves; ii++)
+ {
+ float2 noise = _Gimmick_DS2_Noise.SampleLevel(linear_repeat_s, ro.xy * _Gimmick_DS2_03_Domain_Warping_Scale + _Time[0] * _Gimmick_DS2_03_Domain_Warping_Speed * warping_speed_vector, 0);
+ ro.xy += noise * _Gimmick_DS2_03_Domain_Warping_Strength;
+ }
+
+ #define DS2_03_MARCH_STEPS 3
float total_distance_traveled = 0.0;
- const float MINIMUM_HIT_DISTANCE = 1E-3;
- const float MAXIMUM_TRACE_DISTANCE = 30.0;
+ const float MINIMUM_HIT_DISTANCE = 1E-4;
+ const float MAXIMUM_TRACE_DISTANCE = 1E-1;
float distance_to_closest;
float3 which;
for (uint ii = 0; ii < DS2_03_MARCH_STEPS; ii++)
@@ -416,22 +575,26 @@ Gimmick_DS2_Output Gimmick_DS2_03(inout v2f i)
}
bool hit = distance_to_closest < MINIMUM_HIT_DISTANCE;
- float3 normal = hit ? UnityObjectToWorldNormal(ds2_03_calc_normal(ro + total_distance_traveled * rd)) : i.normal;
+ float3 final_position = ro + total_distance_traveled * rd;
+ float3 normal = hit ? UnityObjectToWorldNormal(ds2_03_calc_normal(final_position)) : i.normal;
float3 light_dir = normalize(float3(0.5, -0.5, -0.5));
float3 light_color = float3(1, 1, 1);
float ndotl = saturate(dot(normal, light_dir));
- float wrap_factor = 0.5;
+ float wrap_factor = 0.7;
float4 wrapped = pow(max(1E-4, (ndotl + wrap_factor) / (1 + wrap_factor)), 1 + wrap_factor);
float3 light_intensity = light_color * wrapped;
+ float3 color = hit ? 1 : 0;
+ color *= light_intensity;
Gimmick_DS2_Output o;
- o.albedo = hit ? float4(light_intensity, 1) : 0;
+ o.albedo = float4(color, 1);
o.emission = o.albedo;
o.normal = normal;
o.metallic = 0;
o.roughness = 0;
- o.worldPos = mul(unity_ObjectToWorld, float4(ro + total_distance_traveled * rd, 1));
+ // 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));
return o;
}