summaryrefslogtreecommitdiffstats
path: root/ray_marching.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-11-02 18:10:55 -0800
committeryum <yum.food.vr@gmail.com>2025-11-02 18:10:55 -0800
commit0d7e2444c55eb2067792c6da57dad370e997fa4d (patch)
tree65b54f861119866a1c5e9675c2defe2698c3ca47 /ray_marching.cginc
parent4d3648b160efbd59bd270b4e4813501c8453c44a (diff)
add hex grid tiling
Diffstat (limited to 'ray_marching.cginc')
-rw-r--r--ray_marching.cginc70
1 files changed, 61 insertions, 9 deletions
diff --git a/ray_marching.cginc b/ray_marching.cginc
index b13bee0..57a3dff 100644
--- a/ray_marching.cginc
+++ b/ray_marching.cginc
@@ -42,12 +42,63 @@ void ray_march(inout v2f i) {
const uint kMaxIter = _Ray_Marching_Max_Iter;
float d_cur;
float d_acc = 0;
+ float3 hit_pos;
for (uint ii = 0; ii < kMaxIter; ++ii) {
float3 p = ro + rd * d_acc;
d_cur = 1e9;
-#if defined(_RAY_MARCHING_BALL_GRID)
- float3 count = float3(_Ray_Marching_Ball_Grid_Count_X, _Ray_Marching_Ball_Grid_Count_Y, _Ray_Marching_Ball_Grid_Count_Z);
- d_cur = min(d_cur, map_ball_grid(p, count));
+
+ // Coordinate system transformations.
+#if defined(_RAY_MARCHING_CART_GRID)
+ {
+ float3 count = float3(_Ray_Marching_Cart_Grid_Count_X, _Ray_Marching_Cart_Grid_Count_Y, _Ray_Marching_Cart_Grid_Count_Z);
+ float3 period = 1.0f / count;
+ period *= 2;
+ float3 half_period = period*0.5f;
+ float3 which = floor((p + half_period) / period);
+ if (any(abs(which) > count/2)) {
+ p = 1e6;
+ } else {
+ p = glsl_mod(p + half_period, period) - half_period;
+ }
+ }
+#endif
+#if defined(_RAY_MARCHING_HEX_GRID)
+ {
+ const float3 count = _Ray_Marching_Hex_Grid_Count * 0.5f;
+ const float3 period = 1.0f / count;
+ const float3 hex = cart_to_hex(p.xy);
+
+ float half_period = period * 0.5;
+ float3 which = floor((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)
+ const float3 hex_inst = hex - period * round_hex(hex / period);
+
+ p.xy = (any(abs(which) > count/2) ? 1e9 : hex_to_cart(hex_inst));
+ }
+#endif
+
+ // Sdfs.
+#if defined(_RAY_MARCHING_BALL)
+ {
+ float r = _Ray_Marching_Ball_Radius;
+ d_cur = min(d_cur, map_ball(p, _Ray_Marching_Ball_Radius));
+ }
#endif
#if defined(_RAY_MARCHING_OVERSTEP)
@@ -56,6 +107,7 @@ void ray_march(inout v2f i) {
d_acc += d_cur;
if (abs(d_cur) < kMinDist) {
+ hit_pos = p;
break;
}
if (d_acc > kMaxDist) {
@@ -67,13 +119,14 @@ void ray_march(inout v2f i) {
discard;
}
- // TODO clip / hit detection
- float3 lclPos = ro + rd * d_acc;
+ float3 lclPos = hit_pos;
float3 lclNorm;
float3 lclTan;
-#if defined(_RAY_MARCHING_BALL_GRID)
- float3 count = float3(_Ray_Marching_Ball_Grid_Count_X, _Ray_Marching_Ball_Grid_Count_Y, _Ray_Marching_Ball_Grid_Count_Z);
- map_ball_grid_normal(count, lclPos, lclNorm, lclTan);
+#if defined(_RAY_MARCHING_BALL)
+ {
+ float r = _Ray_Marching_Ball_Radius;
+ map_ball_normal(r, lclPos, lclNorm, lclTan);
+ }
#endif
i.objPos = lclPos;
@@ -83,4 +136,3 @@ void ray_march(inout v2f i) {
}
#endif // __RAY_MARCHING_INC
-