diff options
Diffstat (limited to 'Shaders/ray_march.cginc')
| -rw-r--r-- | Shaders/ray_march.cginc | 361 |
1 files changed, 0 insertions, 361 deletions
diff --git a/Shaders/ray_march.cginc b/Shaders/ray_march.cginc deleted file mode 100644 index bdedc8b..0000000 --- a/Shaders/ray_march.cginc +++ /dev/null @@ -1,361 +0,0 @@ -#ifndef __RAY_MARCH_INC__ -#define __RAY_MARCH_INC__ - -#include "eyes_data.cginc" -#include "iq_sdf.cginc" -#include "math.cginc" -#include "Motion.cginc" -#include "pbr.cginc" -#include "pema99.cginc" -#include "poi.cginc" -#include "stt_text.cginc" - -float _Emerge; -float _Ellipsis; - -float4 _Text_Color; -float _Text_Metallic; -float _Text_Smoothness; -float _Text_Emissive; - -float4 _BG_Color; -float _BG_Metallic; -float _BG_Smoothness; -float _BG_Emissive; - -float4 _Frame_Color; -float _Frame_Metallic; -float _Frame_Smoothness; -float _Frame_Emissive; - -#define MY_COORD_SCALE 100 -#define MY_COORD_SCALE_INV 1.0 / MY_COORD_SCALE -#define OBJ_SPACE_TO_MINE \ - float4x4( \ - MY_COORD_SCALE, 0, 0, 0, \ - 0, MY_COORD_SCALE, 0, 0, \ - 0, 0, MY_COORD_SCALE, 0, \ - 0, 0, 0, MY_COORD_SCALE \ - ) -#define WORLD_SPACE_TO_MINE \ - mul(unity_WorldToObject, OBJ_SPACE_TO_MINE) -#define MY_SPACE_TO_OBJ \ - float4x4( \ - MY_COORD_SCALE_INV, 0, 0, 0, \ - 0, MY_COORD_SCALE_INV, 0, 0, \ - 0, 0, MY_COORD_SCALE_INV, 0, \ - 0, 0, 0, MY_COORD_SCALE_INV \ - ) -#define MY_SPACE_TO_WORLD \ - mul(MY_SPACE_TO_OBJ, unity_ObjectToWorld) - -#define MINIMUM_HIT_DISTANCE .00002 * MY_COORD_SCALE -#define MAXIMUM_TRACE_DISTANCE 2 * MY_COORD_SCALE - -// Allows us to divide [0,1] into `n_phases` equal-sized slices and remap `r` -// onto the `nth_phase`. -// -// A few examples: -// get_phase_fraction(0.9, 0, 2) = 1.0 -// get_phase_fraction(0.9, 1, 2) = 0.8 -// get_phase_fraction(0.5, 0, 3) = 1.0 -// get_phase_fraction(0.5, 1, 3) = 0.5 -// get_phase_fraction(0.5, 2, 3) = 0.0 -// -// So if `r` is past the slice we're looking at, it returns 1; if it's before -// the slice we're looking at, it returns 0; if it's on the slice we're looking -// at, it gets remapped onto [0,1]. -float get_phase_fraction(float r, float nth_phase, float n_phases) { - float stride = 1.0 / n_phases; - - // Prevent boundary condition where saturated values get set to 0 by the - // glsl_mod below. - r = min(.9999 * (nth_phase + 1) * stride, r); - - float r0 = clamp(r, nth_phase * stride, (nth_phase + 1) * stride); - r0 = glsl_mod(r0, stride); - - return r0 / stride; -} - -// d = base edge length -// h = height -// e = frame thickness -// Pyramid base is on xy plane. -float distance_from_rect_pyramid_frame(float3 p, float dx, float dy, float h, float e, float skew) -{ - float3 p0 = float3(dx/2, dy/2, 0); - float3 p1 = float3(dx/2, -dy/2, 0); - float3 p3 = float3(-dx/2, dy/2, 0); - float3 p4 = float3(skew, 0, h); - - float3 pp = p; - // Symmetry - pp.x = abs(pp.x); - float d01 = distance_from_line_segment(pp, p0, p1, e); - - pp = p; - pp.y = abs(pp.y); - float d03 = distance_from_line_segment(pp, p0, p3, e); - float d04 = distance_from_line_segment(pp, p0, p4, e); - float d14 = distance_from_line_segment(pp, p3, p4, e); - - float dist = 1000; - dist = min(dist, d01); - dist = min(dist, d04); - dist = min(dist, d03); - dist = min(dist, d14); - - return dist; -} - -#define OBJ_ID_NONE 0 -#define OBJ_ID_FRAME 1 -#define OBJ_ID_BG 2 - -float stt_map(float3 p, out int obj_id, out float2 text_uv) -{ - obj_id = OBJ_ID_NONE; - - float p0r = get_phase_fraction(_Emerge, 0, 4); - float p1r = get_phase_fraction(_Emerge, 1, 4); - float p2r = get_phase_fraction(_Emerge, 2, 4); - float p3r = get_phase_fraction(_Emerge, 3, 4); - - float dist = 1000 * 1000 * 1000; - float3 box_scale_g = float3(1, 1, .85) * MY_COORD_SCALE; - float3 box_center_g = float3(.020, 0, .0122) * MY_COORD_SCALE; - { - float3 pp = p; - pp -= box_center_g; - - float box_thck = .0002 * MY_COORD_SCALE; - - float3 box_sz = float3(6, .5, 3) * .003 * box_scale_g; - - // Use this to make the box grow out of the bottom left corner instead of the - // middle. - float3 emerge_offset = 0; - emerge_offset.x = lerp(box_sz.x, box_thck, p1r); - emerge_offset.z = lerp(box_sz.z, box_thck, p2r); - pp += emerge_offset; - - box_sz.y = lerp(box_thck, box_sz.y, p0r) * p0r; - box_sz.x = lerp(box_thck, box_sz.x, p1r) * p0r; - box_sz.z = lerp(box_thck, box_sz.z, p2r) * p0r; - - float d = distance_from_box_frame(pp, box_sz, box_thck); - - obj_id = lerp(obj_id, OBJ_ID_FRAME, d < dist); - dist = min(dist, d); - } - { - float3 pp = p; - pp -= box_center_g; - //pp -= float3(-0.00018, .0013, -.0002) * MY_COORD_SCALE; - pp -= float3(-0.00018, 0, -.0002) * MY_COORD_SCALE; - - float3 box_scale = float3(10, 0.1, 4.9) * .00175 * box_scale_g; - float3 box_pad = float3(.001, 0, .001) * MY_COORD_SCALE; - box_scale -= box_pad; - - // Use this to make the board grow out of the left edge instead of from the - // center. - float3 emerge_offset = 0; - emerge_offset.x = lerp(box_scale.x, 0, p3r); - pp += emerge_offset; - - box_scale.x = lerp(0, box_scale.x, p3r); - box_scale.y *= ceil(p3r); - box_scale.z *= ceil(p3r); - - // Only use calculation when in phase 3. - float d = lerp(1000, distance_from_box(pp, box_scale), ceil(p3r)); - - text_uv = (clamp(pp.xz, -1 * box_scale.xz, box_scale.xz) / box_scale.xz); - text_uv = (text_uv + 1) / 2; - - bool in_mirror = !((unity_CameraProjection[2][0] == 0.0) * (unity_CameraProjection[2][1] == 0.0)); - text_uv = lerp(text_uv, float2(1.0 - text_uv.x, text_uv.y), in_mirror); - - obj_id = lerp(obj_id, OBJ_ID_BG, d < dist); - dist = min(dist, d); - } - { - float3 pp = p; - - pp -= box_center_g - float3(6, 0, 3) * .003 * box_scale_g; - - float scale = .0025 + .0002; - scale *= MY_COORD_SCALE; - pp.x -= scale/2; - - float edgex = 1 * scale; - float edgey = 1 * scale; - float height = -1.3 * scale; - float r = .06 * scale; - float skew = -.75 * scale; - - pp.z += lerp(0, .0008 * MY_COORD_SCALE, p0r) * p0r; - r = lerp(0, r, p0r) * p0r; - edgey = lerp(0, edgey, p0r) * p0r; - - pp.x += lerp(edgex/2, 0, p1r); - edgex = lerp(0, edgex, p1r); - - height = lerp(0, height, p2r); - skew = lerp(0, skew, p3r); - - float d = distance_from_rect_pyramid_frame(pp, edgex, edgey, height, r, skew); - obj_id = lerp(obj_id, OBJ_ID_FRAME, d < dist); - dist = min(dist, d); - } - if (_Ellipsis > 0.1 && _Emerge > .99) { - float3 pp = p; - - float3 xoff = float3(.003, 0, 0) * MY_COORD_SCALE; - - float r_small = .0005 * MY_COORD_SCALE; - float r_big = .001 * MY_COORD_SCALE; - float r_phase = glsl_mod(_Time[1], 1.0); - - float r0_p0r = get_phase_fraction(r_phase, 0, 8); - float r0_p2r = get_phase_fraction(r_phase, 3, 8); - float r1_p0r = get_phase_fraction(glsl_mod(r_phase + .25, 1.0), 0, 8); - float r1_p2r = get_phase_fraction(glsl_mod(r_phase + .25, 1.0), 3, 8); - float r2_p0r = get_phase_fraction(glsl_mod(r_phase + .50, 1.0), 0, 8); - float r2_p2r = get_phase_fraction(glsl_mod(r_phase + .50, 1.0), 3, 8); - - float r0 = lerp(r_small, r_big, r0_p0r * (1 - r0_p2r)); - float r1 = lerp(r_small, r_big, r1_p0r * (1 - r1_p2r)); - float r2 = lerp(r_small, r_big, r2_p0r * (1 - r2_p2r)); - - pp -= box_center_g; - - float d = distance_from_sphere(pp - xoff, 0, r0); - d = min(d, distance_from_sphere(pp, 0, r1)); - d = min(d, distance_from_sphere(pp + xoff, 0, r2)); - - obj_id = lerp(obj_id, OBJ_ID_FRAME, d < dist); - dist = min(dist, d); - } - - return dist; -} - -// Calculate normals for ray-marched STT structure. -float3 stt_calculate_normal(in float3 p) -{ - const float3 small_step = float3(0.0001, 0.0, 0.0); - - // Calculate the 3D gradient. By definition, the gradient is orthogonal - // (normal) to the surface. - int obj_id; - float2 text_uv; - float gradient_x = stt_map(p + small_step.xyy, obj_id, text_uv) - stt_map(p - small_step.xyy, obj_id, text_uv); - float gradient_y = stt_map(p + small_step.yxy, obj_id, text_uv) - stt_map(p - small_step.yxy, obj_id, text_uv); - float gradient_z = stt_map(p + small_step.yyx, obj_id, text_uv) - stt_map(p - small_step.yyx, obj_id, text_uv); - - float3 normal = float3(gradient_x, gradient_y, gradient_z); - - return normalize(normal); -} - -float get_letter_mask(float2 text_uv, bool mirror) -{ - float epsilon = .005; - if (text_uv.x > epsilon && text_uv.x < 1 - epsilon && - text_uv.y > epsilon && text_uv.y < 1 - epsilon) { - text_uv.y = 1.0 - text_uv.y; - // Make backside render left-to-right. - text_uv.x = lerp(text_uv.x, 1.0 - text_uv.x, mirror); - text_uv = AddMarginToUV(1.0 - text_uv, .01); - return GetLetter(text_uv); - } - return 0; -} - -float3 stt_march(float3 ro, float3 rd, out int obj_id, out float2 text_uv, int steps) -{ - float total_distance_traveled = 0.0; - float3 current_position = 0; - float distance_to_closest = 1; - - #define STT_RAY_MARCH_STEPS 48 - for (int i = 0; (i < steps) * - (distance_to_closest > MINIMUM_HIT_DISTANCE/4) * - (total_distance_traveled < MAXIMUM_TRACE_DISTANCE); i++) - { - current_position = ro + total_distance_traveled * rd; - distance_to_closest = stt_map(current_position, obj_id, text_uv); - total_distance_traveled += distance_to_closest; - } - obj_id = lerp(OBJ_ID_NONE, obj_id, distance_to_closest < MINIMUM_HIT_DISTANCE); - - return current_position; -} - -float4 stt_ray_march(float3 ro, float3 rd, inout v2f v2f_i, inout float depth) -{ - - // TODO(yum) remove - float3 old_world_pos = v2f_i.worldPos; - depth = getWorldSpaceDepth(old_world_pos); - - int obj_id; - float2 text_uv; - float3 current_position = stt_march(ro, rd, obj_id, text_uv, /*steps=*/48); - - float3 normal = stt_calculate_normal(current_position); - v2f_i.normal = normalize(mul(MY_SPACE_TO_WORLD, normal)); - v2f_i.worldPos = mul(MY_SPACE_TO_WORLD, float4(current_position, 1.0)).xyz; - - float letter_mask = get_letter_mask(text_uv, ((normal.y + 1) / 2) > .01); - - float4 text = light(v2f_i, _Text_Color, _Text_Metallic, _Text_Smoothness); - text += _Text_Color * _Text_Emissive; - text = clamp(text, 0, 1); - - float4 bg = light(v2f_i, _BG_Color, _BG_Metallic, _BG_Smoothness); - bg += _BG_Color * _BG_Emissive; - bg = clamp(bg, 0, 1); - - float4 frame = light(v2f_i, _Frame_Color, _Frame_Metallic, _Frame_Smoothness); - frame += _Frame_Color * _Frame_Emissive; - frame = clamp(frame, 0, 1); - - frame += _Frame_Color * _Frame_Emissive; - frame = clamp(frame, 0, 1); - - // TODO(yum) restore - //depth = getWorldSpaceDepth(v2f_i.worldPos); - - [forcecase] - switch (obj_id) { - case OBJ_ID_NONE: - depth = -1000; - return 0; - case OBJ_ID_FRAME: - return frame; - case OBJ_ID_BG: - return lerp(bg, text, letter_mask); - } -} - -float4 stt_ray_march(inout v2f v2f_i, inout float depth) -{ - float4 ray_march_color; - { - float3 camera_position = mul(WORLD_SPACE_TO_MINE, float4(_WorldSpaceCameraPos, 1.0)).xyz; - float3 ro = camera_position; - float3 rd = normalize(mul(WORLD_SPACE_TO_MINE, float4(v2f_i.worldPos, 1.0)).xyz - ro); - float3 old_normal = v2f_i.normal; - ray_march_color = stt_ray_march(ro, rd, v2f_i, depth); - //v2f_i.normal = old_normal; - } - - return ray_march_color; -} - -#endif // __RAY_MARCH_INC__ - |
