summaryrefslogtreecommitdiffstats
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
parent4d3648b160efbd59bd270b4e4813501c8453c44a (diff)
add hex grid tiling
-rw-r--r--3ner.shader29
-rw-r--r--features.cginc12
-rw-r--r--globals.cginc16
-rw-r--r--math.cginc15
-rw-r--r--ray_marching.cginc70
-rw-r--r--ray_marching_maps.slang19
6 files changed, 127 insertions, 34 deletions
diff --git a/3ner.shader b/3ner.shader
index d755f64..8d3a577 100644
--- a/3ner.shader
+++ b/3ner.shader
@@ -75,14 +75,27 @@ Shader "yum_food/3ner"
[HideInInspector] m_end_Ray_Marching_Baked_Origins("Baked Origins", Float) = 0
//endex
- //ifex _Ray_Marching_Ball_Grid_Enabled==0
- [HideInInspector] m_start_Ray_Marching_Ball_Grid("Ball Grid", Float) = 0
- [ThryToggle(_RAY_MARCHING_BALL_GRID)] _Ray_Marching_Ball_Grid_Enabled("Enable", Float) = 0
- _Ray_Marching_Ball_Grid_Radius("Radius", Float) = 1
- _Ray_Marching_Ball_Grid_Count_X("Count X", Range(0,40)) = 5
- _Ray_Marching_Ball_Grid_Count_Y("Count Y", Range(0,40)) = 5
- _Ray_Marching_Ball_Grid_Count_Z("Count Z", Range(0,40)) = 5
- [HideInInspector] m_end_Ray_Marching_Ball_Grid("Ball Grid", Float) = 0
+ //ifex _Ray_Marching_Cart_Grid_Enabled==0
+ [HideInInspector] m_start_Ray_Marching_Cart_Grid("Cart Grid", Float) = 0
+ [ThryToggle(_RAY_MARCHING_CART_GRID)] _Ray_Marching_Cart_Grid_Enabled("Enable", Float) = 0
+ _Ray_Marching_Cart_Grid_Count_X("Count X", Range(0,40)) = 5
+ _Ray_Marching_Cart_Grid_Count_Y("Count Y", Range(0,40)) = 5
+ _Ray_Marching_Cart_Grid_Count_Z("Count Z", Range(0,40)) = 5
+ [HideInInspector] m_end_Ray_Marching_Cart_Grid("Cart Grid", Float) = 0
+ //endex
+
+ //ifex _Ray_Marching_Hex_Grid_Enabled==0
+ [HideInInspector] m_start_Ray_Marching_Hex_Grid("Hex Grid", Float) = 0
+ [ThryToggle(_RAY_MARCHING_HEX_GRID)] _Ray_Marching_Hex_Grid_Enabled("Enable", Float) = 0
+ _Ray_Marching_Hex_Grid_Count("CountX", Range(0,40)) = 5
+ [HideInInspector] m_end_Ray_Marching_Hex_Grid("Hex Grid", Float) = 0
+ //endex
+
+ //ifex _Ray_Marching_Ball_Enabled==0
+ [HideInInspector] m_start_Ray_Marching_Ball("Ball", Float) = 0
+ [ThryToggle(_RAY_MARCHING_BALL)] _Ray_Marching_Ball_Enabled("Enable", Float) = 0
+ _Ray_Marching_Ball_Radius("Radius", Range(0,1)) = 1
+ [HideInInspector] m_end_Ray_Marching_Ball("Ball", Float) = 0
//endex
[HideInInspector] m_end_Ray_Marching("Ray Marching", Float) = 0
diff --git a/features.cginc b/features.cginc
index 49aa3e7..9b76cd4 100644
--- a/features.cginc
+++ b/features.cginc
@@ -84,8 +84,16 @@
#pragma shader_feature_local _RAY_MARCHING_BAKED_ORIGINS
//endex
-//ifex _Ray_Marching_Ball_Grid_Enabled==0
-#pragma shader_feature_local _RAY_MARCHING_BALL_GRID
+//ifex _Ray_Marching_Cart_Grid_Enabled==0
+#pragma shader_feature_local _RAY_MARCHING_CART_GRID
+//endex
+
+//ifex _Ray_Marching_Hex_Grid_Enabled==0
+#pragma shader_feature_local _RAY_MARCHING_HEX_GRID
+//endex
+
+//ifex _Ray_Marching_Ball_Enabled==0
+#pragma shader_feature_local _RAY_MARCHING_BALL
//endex
#endif // __FEATURES_INC
diff --git a/globals.cginc b/globals.cginc
index 533e102..181e71f 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -134,6 +134,18 @@ float _Ray_Marching_Overstepping_Factor;
int _Baked_Origins_UV_Channel_Index;
#endif // _RAY_MARCHING_BAKED_ORIGINS
+#if defined(_RAY_MARCHING_CART_GRID)
+float _Ray_Marching_Cart_Grid_Radius;
+float _Ray_Marching_Cart_Grid_Count_X;
+float _Ray_Marching_Cart_Grid_Count_Y;
+float _Ray_Marching_Cart_Grid_Count_Z;
+#endif // _RAY_MARCHING_CART_GRID
+
+#if defined(_RAY_MARCHING_HEX_GRID)
+float _Ray_Marching_Hex_Grid_Radius;
+float _Ray_Marching_Hex_Grid_Count;
+#endif // _RAY_MARCHING_HEX_GRID
+
#if defined(_RAY_MARCHING_BALL_GRID)
float _Ray_Marching_Ball_Grid_Radius;
float _Ray_Marching_Ball_Grid_Count_X;
@@ -141,4 +153,8 @@ float _Ray_Marching_Ball_Grid_Count_Y;
float _Ray_Marching_Ball_Grid_Count_Z;
#endif // _RAY_MARCHING_BALL_GRID
+#if defined(_RAY_MARCHING_BALL)
+float _Ray_Marching_Ball_Radius;
+#endif // _RAY_MARCHING_BALL
+
#endif // __GLOBALS_INC
diff --git a/math.cginc b/math.cginc
index 58a9c08..f188a91 100644
--- a/math.cginc
+++ b/math.cginc
@@ -74,5 +74,20 @@ float2 hex_to_cart(float3 cart) {
(cart[1] - cart[2]) * SQRT_3_OVER_2);
}
+
+float3 round_hex(float3 hex_coord) {
+ float3 rounded = round(hex_coord);
+ float3 diff = abs(rounded - hex_coord);
+ float error = rounded.x - rounded.y - rounded.z;
+
+ float3 max_mask = float3(
+ diff.x > diff.y && diff.x > diff.z,
+ diff.y > diff.x && diff.y > diff.z,
+ diff.z > diff.x && diff.z > diff.y);
+
+ rounded += error * float3(-1, 1, 1) * max_mask;
+ return rounded;
+}
+
#endif // __MATH_INC
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
-
diff --git a/ray_marching_maps.slang b/ray_marching_maps.slang
index 3c83a19..002ef90 100644
--- a/ray_marching_maps.slang
+++ b/ray_marching_maps.slang
@@ -32,25 +32,14 @@
R3R1_AUTODIFF_BASIS_VECTORS(fun, __VA_ARGS__); \
R3R1_DEFORM_NORMAL_AND_TANGENT(normal, tangent)
-// Just trace a sphere of radius 0.1 for now.
[Differentiable]
-public float map_ball_grid(float3 p, no_diff float3 count) {
- 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;
- }
-
- return length(p) - half_period.x;
+public float map_ball(float3 p, no_diff float r) {
+ return length(p) - r;
}
-public void map_ball_grid_normal(float3 count, inout float3 xyz, inout float3 normal,
+public void map_ball_normal(float r, inout float3 xyz, inout float3 normal,
inout float3 tangent) {
- R3R1_RAY_MARCH_NORMALS(xyz, normal, tangent, map_ball_grid, count);
+ R3R1_RAY_MARCH_NORMALS(xyz, normal, tangent, map_ball, r);
}
#endif // __RAY_MARCHING_MAPS_INC