diff options
| author | yum <yum.food.vr@gmail.com> | 2023-08-09 18:54:17 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2023-08-09 18:54:17 -0700 |
| commit | 3bf013dc3b5479f4fbb458d44801403afe0bb1d2 (patch) | |
| tree | d91ef918797b2036e1005afa1e9b221d293b696f /Shaders/ray_march.cginc | |
| parent | 1285caf31578d758c2b52b915eedb17cc12a1826 (diff) | |
Add ray-marched custom chatbox
* Refactor shader code to make development easier. Templates are now
as small as possible.
* Update scaling code. Use Unity scaling instead of a blendshape.
* Check in a fuckton of shader FOSS. Mostly unused.
* Update TaSTT.fbx. Now has 6 faces instead of 2.
Diffstat (limited to 'Shaders/ray_march.cginc')
| -rw-r--r-- | Shaders/ray_march.cginc | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/Shaders/ray_march.cginc b/Shaders/ray_march.cginc new file mode 100644 index 0000000..3dce6dd --- /dev/null +++ b/Shaders/ray_march.cginc @@ -0,0 +1,142 @@ +#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 stt_map(float3 p, out float3 hsv, out float smoothness, out float alpha, out float2 text_uv) +{ + hsv[0] = 0; + hsv[1] = 1; + hsv[2] = 1; + smoothness = 0.3; + alpha = 0; + + float dist = 1000 * 1000 * 1000; + { + float3 pp = p; + + pp.x -= 0.02; + pp.z -= 0.01; + + float d = distance_from_box_frame(pp, float3(6, .5, 3) * .003, .0002); + + alpha = (d < dist) * 1 + (d >= dist) * alpha; + dist = min(dist, d); + } + { + float3 pp = p; + + pp.x -= 0.02; + pp.z -= 0.01; + + float3 box_scale = float3(.01, .0001, .005) * 1.6; + float d = distance_from_box(pp, box_scale); + + text_uv = (clamp(pp.xz, -1 * box_scale.xz, box_scale.xz) / box_scale.xz); + text_uv = (text_uv + 1) / 2; + + alpha = (d < dist) * 1 + (d >= dist) * alpha; + hsv[1] = (d < dist) * 0 + (d >= dist) * hsv[1]; + hsv[2] = (d < dist) * 0 + (d >= dist) * hsv[2]; + dist = min(dist, d); + } + + return dist; +} + +float3 stt_calculate_normal(in float3 p) +{ + // Setting a very low value makes the surface normals look noisy. In this + // case. that's desired, since it produces a glittery effect. + 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. + float3 hsv; + float smoothness; + float alpha; + float2 text_uv; + float gradient_x = stt_map(p + small_step.xyy, hsv, smoothness, alpha, text_uv) - stt_map(p - small_step.xyy, hsv, smoothness, alpha, text_uv); + float gradient_y = stt_map(p + small_step.yxy, hsv, smoothness, alpha, text_uv) - stt_map(p - small_step.yxy, hsv, smoothness, alpha, text_uv); + float gradient_z = stt_map(p + small_step.yyx, hsv, smoothness, alpha, text_uv) - stt_map(p - small_step.yyx, hsv, smoothness, alpha, text_uv); + + float3 normal = float3(gradient_x, gradient_y, gradient_z); + + return normalize(normal); +} + +float4 stt_ray_march(float3 ro, float3 rd, inout v2f v2f_i, inout float depth) +{ + float total_distance_traveled = 0.0; + const float MINIMUM_HIT_DISTANCE = 1.0 / (1000 * 20); + const float MAXIMUM_TRACE_DISTANCE = 1000.0; + float3 current_position = 0; + float distance_to_closest = 1; + + #define STT_RAY_MARCH_STEPS 32 + float4 color = 0; + float metallic = 0.5; + float smoothness; + float alpha; + float3 hsv; + float2 text_uv; + + for (int i = 0; i < STT_RAY_MARCH_STEPS && + distance_to_closest > MINIMUM_HIT_DISTANCE && + total_distance_traveled < MAXIMUM_TRACE_DISTANCE; i++) + { + current_position = ro + total_distance_traveled * rd; + distance_to_closest = stt_map(current_position, hsv, smoothness, alpha, text_uv); + total_distance_traveled += distance_to_closest; + } + + float3 normal = stt_calculate_normal(current_position); + v2f_i.normal = normalize(mul(unity_ObjectToWorld, normal)); + + 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, (normal.y + 1) / 2); + hsv[0] = 0; + text_uv = AddMarginToUV(1.0 - text_uv, .01); + hsv[1] = 0; + hsv[2] = GetLetter(text_uv); + } + + depth = getWorldSpaceDepth(mul(unity_ObjectToWorld, float4(current_position, 1.0)).xyz); + color.xyz = HSVtoRGB(hsv); + color.w = alpha; + + depth = lerp(-1000, depth, distance_to_closest < MINIMUM_HIT_DISTANCE); + return lerp(0, light(v2f_i, color, metallic, smoothness), distance_to_closest < MINIMUM_HIT_DISTANCE); +} + +float4 stt_ray_march(inout v2f v2f_i, inout float depth) +{ + float4 ray_march_color; + { + float3 camera_position = mul(unity_WorldToObject, float4(_WorldSpaceCameraPos, 1.0)).xyz; + float3 ro = camera_position; + float3 rd = normalize(mul(unity_WorldToObject, 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; + } + + float4 background_color = float4(0, 0, 0, 0); + + float3 final_color = lerp(background_color.rgb, ray_march_color.rgb, ray_march_color.a); + return float4(final_color, 1.0); +} + +#endif // __RAY_MARCH_INC__ + |
