summaryrefslogtreecommitdiffstats
path: root/ray_marching_maps.slang
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-10-28 21:33:40 -0700
committeryum <yum.food.vr@gmail.com>2025-10-28 21:33:40 -0700
commit15f9778a65a0f163627bd229b8f212cc5c7c0c22 (patch)
treeb4b6c90defa76b9086b3b1f02bcd2a6401e019e7 /ray_marching_maps.slang
parent6c93421c1a10caf9e4f6996e1109379a504c19a7 (diff)
some ray marching
Diffstat (limited to 'ray_marching_maps.slang')
-rw-r--r--ray_marching_maps.slang89
1 files changed, 89 insertions, 0 deletions
diff --git a/ray_marching_maps.slang b/ray_marching_maps.slang
new file mode 100644
index 0000000..d98248b
--- /dev/null
+++ b/ray_marching_maps.slang
@@ -0,0 +1,89 @@
+#ifndef __RAY_MARCHING_MAPS_INC
+#define __RAY_MARCHING_MAPS_INC
+
+#include "math.cginc"
+#include "pema99.cginc"
+
+// Macros for transforming normal and tangent using autodiff.
+// r3r1 refers to "r3 to r1 transform", aka a mapping from a 3d real-valued
+// space to a 1d space. This is intended for use with a ray marcher.
+#define R3R1_DECLARE_BASIS_VECTORS(xyz) \
+ DifferentialPair<float3> dp_x = diffPair(xyz, float3(1, 0, 0)); \
+ DifferentialPair<float3> dp_y = diffPair(xyz, float3(0, 1, 0)); \
+ DifferentialPair<float3> dp_z = diffPair(xyz, float3(0, 0, 1))
+
+#define R3R1_AUTODIFF_BASIS_VECTORS(fun, ...) \
+ DifferentialPair<float> dp_x_out = fwd_diff(fun)(dp_x, ##__VA_ARGS__); \
+ DifferentialPair<float> dp_y_out = fwd_diff(fun)(dp_y, ##__VA_ARGS__); \
+ DifferentialPair<float> dp_z_out = fwd_diff(fun)(dp_z, ##__VA_ARGS__)
+
+#define R3R1_DEFORM_NORMAL_AND_TANGENT(normal, tangent) \
+ { \
+ float3 gradient = float3(dp_x_out.d, dp_y_out.d, dp_z_out.d); \
+ normal = normalize(gradient); \
+ float3 helper = abs(normal.z) < 0.999 ? float3(0, 0, 1) : float3(0, 1, 0); \
+ tangent = normalize(cross(helper, normal)); \
+ }
+
+// Syntactic sugar - wraps the previous three macros.
+#define R3R1_RAY_MARCH_NORMALS(xyz, normal, tangent, fun, ...) \
+ R3R1_DECLARE_BASIS_VECTORS(xyz); \
+ R3R1_AUTODIFF_BASIS_VECTORS(fun, ##__VA_ARGS__); \
+ R3R1_DEFORM_NORMAL_AND_TANGENT(normal, tangent)
+
+float distance_from_hex_comb(
+ float3 p,
+ float3 period,
+ float count) {
+ float3 p_hex = cart_to_hex(p.yz);
+
+ float3 half_period = period * 0.5;
+ float3 which = abs(floor((p_hex + half_period) / period));
+
+ // The original code here was this:
+ // p_hex = glsl_mod(p_hex + half_period, period) - half_period;
+ //
+ // But you can simplify it. Given the definition of glsl_mod:
+ // #define glsl_mod(x,y) (((x)-(y)*floor((x)/(y))))
+ //
+ // You can plug in terms:
+ // (p_hex + half_period) - (period) * floor((p_hex + half_period) / period)
+ // = p_hex + half_period - period * floor(p_hex/period + 0.5)
+ //
+ // For all x,
+ // round(x) = floor(x + 0.5)
+ //
+ // Continuing to simplify:
+ // (p_hex + half_period - period * round(p_hex/period)) - half_period
+ // = p_hex - period * round(p_hex / period)
+ p_hex = p_hex - period * round(p_hex / period);
+
+ p.yz = hex_to_cart(p_hex);
+
+ float hex_d = length(p) - 0.15;
+ return hex_d;
+}
+
+// Just trace a sphere of radius 0.1 for now.
+[Differentiable]
+public float map(float3 p) {
+ float period = 0.2f;
+ float3 count = float3(6,5,1);
+ float half_period = period * 0.5f;
+ float3 which = abs(floor((p + half_period) / period));
+ if (any(abs(which) >= count)) {
+ p = 1e6;
+ } else {
+ p = glsl_mod(p + half_period, period) - half_period;
+ }
+ p.z += 0.1f;
+ return length(p) - 0.1f;
+}
+
+public void map_normal(inout float3 xyz, inout float3 normal,
+ inout float3 tangent) {
+ R3R1_RAY_MARCH_NORMALS(xyz, normal, tangent, map);
+}
+
+#endif // __RAY_MARCHING_MAPS_INC
+