summaryrefslogtreecommitdiffstats
path: root/Shaders/ray_march.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2023-08-09 18:54:17 -0700
committeryum <yum.food.vr@gmail.com>2023-08-09 18:54:17 -0700
commit3bf013dc3b5479f4fbb458d44801403afe0bb1d2 (patch)
treed91ef918797b2036e1005afa1e9b221d293b696f /Shaders/ray_march.cginc
parent1285caf31578d758c2b52b915eedb17cc12a1826 (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.cginc142
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__
+