From 688a9de062980519e6aacc0aa0255d17a4a88324 Mon Sep 17 00:00:00 2001 From: yum Date: Sun, 2 Nov 2025 19:55:40 -0800 Subject: adjust ray marching loop structure --- 3ner.shader | 8 +++- features.cginc | 4 ++ ray_marching.cginc | 131 ++++++++++++++++++++++++++++------------------------- 3 files changed, 81 insertions(+), 62 deletions(-) diff --git a/3ner.shader b/3ner.shader index a6c8af4..9315aed 100644 --- a/3ner.shader +++ b/3ner.shader @@ -64,10 +64,16 @@ Shader "yum_food/3ner" //ifex _Ray_Marching_Overstepping_Enabled==0 [HideInInspector] m_start_Ray_Marching_Overstepping("Overstepping", Float) = 0 [ThryToggle(_RAY_MARCHING_OVERSTEP)] _Ray_Marching_Overstepping_Enabled("Enable", Float) = 0 - _Ray_Marching_Overstepping_Factor("Factor", Range(1,2)) = 1.3 + _Ray_Marching_Overstepping_Factor("Factor", Range(1,5)) = 1.3 [HideInInspector] m_end_Ray_Marching_Overstepping("Overstepping", Float) = 0 //endex + //ifex _Ray_Marching_Correct_Repetition_Enabled==0 + [HideInInspector] m_start_Ray_Marching_Correct_Repetition("Correct Repetition", Float) = 0 + [ThryToggle(_RAY_MARCHING_CORRECT_REPETITION)] _Ray_Marching_Correct_Repetition_Enabled("Enable", Float) = 0 + [HideInInspector] m_end_Ray_Marching_Correct_Repetition("Correct Repetition", Float) = 0 + //endex + //ifex _Ray_Marching_Baked_Origins_Enabled==0 [HideInInspector] m_start_Ray_Marching_Baked_Origins("Baked Origins", Float) = 0 [ThryToggle(_RAY_MARCHING_BAKED_ORIGINS)] _Ray_Marching_Baked_Origins_Enabled("Enable", Float) = 0 diff --git a/features.cginc b/features.cginc index d74ef01..3a1a773 100644 --- a/features.cginc +++ b/features.cginc @@ -80,6 +80,10 @@ #pragma shader_feature_local _RAY_MARCHING_OVERSTEP //endex +//ifex _Ray_Marching_Correct_Repetition_Enabled==0 +#pragma shader_feature_local _RAY_MARCHING_CORRECT_REPETITION +//endex + //ifex _Ray_Marching_Baked_Origins_Enabled==0 #pragma shader_feature_local _RAY_MARCHING_BAKED_ORIGINS //endex diff --git a/ray_marching.cginc b/ray_marching.cginc index 6184881..39da35c 100644 --- a/ray_marching.cginc +++ b/ray_marching.cginc @@ -23,6 +23,75 @@ void GetRoRd(v2f i, out float3 ro, out float3 rd) { rd = mul((float3x3)unity_WorldToObject, rd_world); } +float map(float3 p) { + float d = 1e9; +#if defined(_RAY_MARCHING_BALL) + { + float r = _Ray_Marching_Ball_Radius; + d = min(d, map_ball(p, _Ray_Marching_Ball_Radius)); + } +#endif +#if defined(_RAY_MARCHING_HEXAGON) + { + float r = _Ray_Marching_Hexagon_Radius; + float h = _Ray_Marching_Hexagon_Height; + d = min(d, map_hexagon(p, float2(r, h))); + } +#endif + return d; +} + +float domain_repeat(inout float3 p) { + float d; +#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; + } + d = map(p); + } +#elif 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)); + + d = map(p); + } +#endif + return d; +} + void ray_march(inout v2f i) { #if defined(_RAY_MARCHING) float3 ro, rd; @@ -44,68 +113,8 @@ void ray_march(inout v2f i) { float3 hit_pos; for (uint ii = 0; ii < kMaxIter; ++ii) { float3 p = ro + rd * d_acc; - d_cur = 1e9; - - // 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_HEXAGON) - { - float r = _Ray_Marching_Hexagon_Radius; - float h = _Ray_Marching_Hexagon_Height; - d_cur = min(d_cur, map_hexagon(p, float2(r, h))); - } -#endif + d_cur = domain_repeat(p); #if defined(_RAY_MARCHING_OVERSTEP) d_cur *= (d_cur > 0 ? _Ray_Marching_Overstepping_Factor : 1.0f); -- cgit v1.2.3