diff options
| author | yum <yum.food.vr@gmail.com> | 2025-10-28 21:33:40 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-10-28 21:33:40 -0700 |
| commit | 15f9778a65a0f163627bd229b8f212cc5c7c0c22 (patch) | |
| tree | b4b6c90defa76b9086b3b1f02bcd2a6401e019e7 /ray_marching_maps.slang | |
| parent | 6c93421c1a10caf9e4f6996e1109379a504c19a7 (diff) | |
some ray marching
Diffstat (limited to 'ray_marching_maps.slang')
| -rw-r--r-- | ray_marching_maps.slang | 89 |
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 + |
