diff options
| author | yum <yum.food.vr@gmail.com> | 2025-11-02 18:10:55 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-11-02 18:10:55 -0800 |
| commit | 0d7e2444c55eb2067792c6da57dad370e997fa4d (patch) | |
| tree | 65b54f861119866a1c5e9675c2defe2698c3ca47 /ray_marching.cginc | |
| parent | 4d3648b160efbd59bd270b4e4813501c8453c44a (diff) | |
add hex grid tiling
Diffstat (limited to 'ray_marching.cginc')
| -rw-r--r-- | ray_marching.cginc | 70 |
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 - |
