diff options
| -rw-r--r-- | 3ner.cginc | 2 | ||||
| -rw-r--r-- | 3ner.shader | 37 | ||||
| -rw-r--r-- | features.cginc | 8 | ||||
| -rw-r--r-- | globals.cginc | 21 | ||||
| -rw-r--r-- | math.cginc | 2 | ||||
| -rw-r--r-- | ray_marching.cginc | 207 |
6 files changed, 168 insertions, 109 deletions
@@ -111,9 +111,9 @@ tess_factors patch_constant(InputPatch<v2f, 3> patch) { // Scale tessellation by screen-space edge length and falloff factor float k = _Tessellation_Falloff_Factor; - f.edge[2] = min(_Tessellation_Factor, k * edge01); f.edge[0] = min(_Tessellation_Factor, k * edge12); f.edge[1] = min(_Tessellation_Factor, k * edge20); + f.edge[2] = min(_Tessellation_Factor, k * edge01); f.inside = (f.edge[0] + f.edge[1] + f.edge[2]) * 0.333333f; diff --git a/3ner.shader b/3ner.shader index 9315aed..3e7e9e0 100644 --- a/3ner.shader +++ b/3ner.shader @@ -81,12 +81,39 @@ Shader "yum_food/3ner" [HideInInspector] m_end_Ray_Marching_Baked_Origins("Baked Origins", Float) = 0 //endex + //ifex _Ray_Marching_Cart_Instancing_Enabled==0 + [HideInInspector] m_start_Ray_Marching_Cart_Instancing("Cartesian Instancing", Float) = 0 + [ThryToggle(_RAY_MARCHING_CART_INSTANCING)] _Ray_Marching_Cart_Instancing_Enabled("Enable", Float) = 0 + [IntRange] _Ray_Marching_Cart_Instancing_Count_X("Count X", Range(1,3)) = 1 + [IntRange] _Ray_Marching_Cart_Instancing_Count_Y("Count Y", Range(1,3)) = 1 + [IntRange] _Ray_Marching_Cart_Instancing_Count_Z("Count Z", Range(1,3)) = 1 + _Ray_Marching_Cart_Instancing_Span_X("Span X", Range(0,2)) = 0.1 + _Ray_Marching_Cart_Instancing_Span_Y("Span Y", Range(0,2)) = 0.1 + _Ray_Marching_Cart_Instancing_Span_Z("Span Z", Range(0,2)) = 0.1 + + //ifex _Ray_Marching_Cart_Instancing_Offsets_Enabled==0 + [HideInInspector] m_start_Ray_Marching_Cart_Instancing_Offsets("Offsets", Float) = 0 + [ThryToggle(_RAY_MARCHING_CART_INSTANCING_OFFSETS)] _Ray_Marching_Cart_Instancing_Offsets_Enabled("Enable", Float) = 0 + _Ray_Marching_Cart_Instancing_Offsets_X_Every_Y("X every Y", Range(0,1)) = 0 + _Ray_Marching_Cart_Instancing_Offsets_X_Every_Z("X every Z", Range(0,1)) = 0 + _Ray_Marching_Cart_Instancing_Offsets_Y_Every_X("Y every X", Range(0,1)) = 0 + _Ray_Marching_Cart_Instancing_Offsets_Y_Every_Z("Y every Z", Range(0,1)) = 0 + _Ray_Marching_Cart_Instancing_Offsets_Z_Every_X("Z every X", Range(0,1)) = 0 + _Ray_Marching_Cart_Instancing_Offsets_Z_Every_Y("Z every Y", Range(0,1)) = 0 + [HideInInspector] m_end_Ray_Marching_Cart_Instancing_Offsets("Offsets", Float) = 0 + //endex + [HideInInspector] m_end_Ray_Marching_Cart_Instancing("Cartesian Instancing", Float) = 0 + //endex + //ifex _Ray_Marching_Cart_Grid_Enabled==0 - [HideInInspector] m_start_Ray_Marching_Cart_Grid("Cart Grid", Float) = 0 + [HideInInspector] m_start_Ray_Marching_Cart_Grid("Cartesian 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 + [IntRange] _Ray_Marching_Cart_Grid_Count_X("Count X", Range(0,40)) = 5 + [IntRange] _Ray_Marching_Cart_Grid_Count_Y("Count Y", Range(0,40)) = 5 + [IntRange] _Ray_Marching_Cart_Grid_Count_Z("Count Z", Range(0,40)) = 5 + _Ray_Marching_Cart_Grid_Span_X("Span X", Range(0,40)) = 0.1 + _Ray_Marching_Cart_Grid_Span_Y("Span Y", Range(0,40)) = 0.1 + _Ray_Marching_Cart_Grid_Span_Z("Span Z", Range(0,40)) = 0.1 [HideInInspector] m_end_Ray_Marching_Cart_Grid("Cart Grid", Float) = 0 //endex @@ -225,7 +252,7 @@ Shader "yum_food/3ner" [ThryToggle(_TESSELLATION)] _Tessellation_Enabled("Enable", Float) = 0 _Tessellation_Factor("Factor", Range(1, 64)) = 1 _Tessellation_Frustum_Culling_Bias("Frustum culling bias", Float) = 35 - _Tessellation_Falloff_Factor("Falloff factor", Float) = 50 + _Tessellation_Falloff_Factor("Falloff factor", Float) = 0.05 // Shit for thry [HideInInspector] Tessellation_Enabled("Enabled", Float) = 1 [HideInInspector] Tessellation_EnabledForwardBase("Enabled (ForwardBase)", Float) = 1 diff --git a/features.cginc b/features.cginc index 3a1a773..39fc34a 100644 --- a/features.cginc +++ b/features.cginc @@ -88,6 +88,14 @@ #pragma shader_feature_local _RAY_MARCHING_BAKED_ORIGINS //endex +//ifex _Ray_Marching_Cart_Instancing_Enabled==0 +#pragma shader_feature_local _RAY_MARCHING_CART_INSTANCING +//endex + +//ifex _Ray_Marching_Cart_Instancing_Offsets_Enabled==0 +#pragma shader_feature_local _RAY_MARCHING_CART_INSTANCING_OFFSETS +//endex + //ifex _Ray_Marching_Cart_Grid_Enabled==0 #pragma shader_feature_local _RAY_MARCHING_CART_GRID //endex diff --git a/globals.cginc b/globals.cginc index 6e0d71f..c2b38cb 100644 --- a/globals.cginc +++ b/globals.cginc @@ -134,11 +134,32 @@ float _Ray_Marching_Overstepping_Factor; int _Baked_Origins_UV_Channel_Index; #endif // _RAY_MARCHING_BAKED_ORIGINS +#if defined(_RAY_MARCHING_CART_INSTANCING) +float _Ray_Marching_Cart_Instancing_Count_X; +float _Ray_Marching_Cart_Instancing_Count_Y; +float _Ray_Marching_Cart_Instancing_Count_Z; +float _Ray_Marching_Cart_Instancing_Span_X; +float _Ray_Marching_Cart_Instancing_Span_Y; +float _Ray_Marching_Cart_Instancing_Span_Z; +#endif // _RAY_MARCHING_CART_INSTANCING + +#if defined(_RAY_MARCHING_CART_INSTANCING_OFFSETS) +float _Ray_Marching_Cart_Instancing_Offsets_X_Every_Y; +float _Ray_Marching_Cart_Instancing_Offsets_X_Every_Z; +float _Ray_Marching_Cart_Instancing_Offsets_Y_Every_X; +float _Ray_Marching_Cart_Instancing_Offsets_Y_Every_Z; +float _Ray_Marching_Cart_Instancing_Offsets_Z_Every_X; +float _Ray_Marching_Cart_Instancing_Offsets_Z_Every_Y; +#endif // _RAY_MARCHING_CART_INSTANCING_OFFSETS + #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; +float _Ray_Marching_Cart_Grid_Span_X; +float _Ray_Marching_Cart_Grid_Span_Y; +float _Ray_Marching_Cart_Grid_Span_Z; #endif // _RAY_MARCHING_CART_GRID #if defined(_RAY_MARCHING_HEX_GRID) @@ -65,7 +65,7 @@ float3 cart_to_hex(float2 cart) { float q = dot(cart, float2(0.5f, SQRT_3_OVER_2)); float r = dot(cart, float2(0.5f, -SQRT_3_OVER_2)); - return float3(p, q, r) * TWO_OVER_THREE; + return float3(p, q, r) * 0.5f; } float2 hex_to_cart(float3 cart) { diff --git a/ray_marching.cginc b/ray_marching.cginc index 9cb8dd0..daba713 100644 --- a/ray_marching.cginc +++ b/ray_marching.cginc @@ -48,27 +48,30 @@ float map(float3 p) { #if defined(_RAY_MARCHING_HEX_GRID) float domain_repeat_hex_grid(inout float3 p) { const float gridCount = max(_Ray_Marching_Hex_Grid_Count, 1.0f); - const float halfCount = gridCount * 0.5f; - const float3 count = float3(halfCount, halfCount, halfCount); - const float3 period = 1.0f / count; + const float invGridCount = 1.0f / gridCount; const float3 hex = cart_to_hex(p.xy); + const float3 scaledHex = hex * gridCount; // Cell ID. - const float3 id = round_hex(hex / period); + const float3 id = round_hex(scaledHex); // Coordinates within the current cell. - const float3 local = hex - period * id; - float3 candidate = p; - candidate.xy = hex_to_cart(local); - float d = map(candidate); - float3 bestPos = candidate; - -#if defined(_RAY_MARCHING_CORRECT_REPETITION) + const float3 local = (scaledHex - id) * invGridCount; const float3 cubeId = float3(id.y, id.z, -id.y - id.z); const float limit = max((gridCount - 1.0f) * 0.5f, 0.0f); const float3 cubeLimit = float3(limit, limit, limit); - if (any(abs(cubeId) > cubeLimit)) { - p = float3(1e9, 1e9, 1e9); - return 1e9; + + float3 bestPos = p; + float d = 1e9; + if (!any(abs(cubeId) > cubeLimit)) { + float3 pp = p; + pp.xy = hex_to_cart(local); + const float d_cur = map(pp); + if (d_cur < d) { + d = d_cur; + bestPos = pp; + } } + +#if defined(_RAY_MARCHING_CORRECT_REPETITION) const float3 cubeOffsets[6] = { float3( 1.0f, -1.0f, 0.0f), float3( 1.0f, 0.0f, -1.0f), @@ -78,81 +81,17 @@ float domain_repeat_hex_grid(inout float3 p) { float3( 0.0f, -1.0f, 1.0f), }; - float neighborDistSq[4] = { 1e9, 1e9, 1e9, 1e9 }; - float3 neighborIds[4] = { - float3(0.0f, 0.0f, 0.0f), - float3(0.0f, 0.0f, 0.0f), - float3(0.0f, 0.0f, 0.0f), - float3(0.0f, 0.0f, 0.0f)}; - float2 neighborLoc[4] = { - float2(0.0f, 0.0f), - float2(0.0f, 0.0f), - float2(0.0f, 0.0f), - float2(0.0f, 0.0f)}; - - [unroll] for (int idx = 0; idx < 6; ++idx) { const float3 cube = cubeId + cubeOffsets[idx]; - const float3 rid = float3(cube.x + cube.y, cube.x, cube.y); if (any(abs(cube) > cubeLimit)) { continue; } - const float2 localXY = hex_to_cart(hex - period * rid); - const float distSq = dot(localXY, localXY); - - if (distSq >= neighborDistSq[3]) { - continue; - } - - neighborDistSq[3] = distSq; - neighborIds[3] = rid; - neighborLoc[3] = localXY; - - if (neighborDistSq[3] < neighborDistSq[2]) { - const float tmpDist = neighborDistSq[2]; - const float3 tmpId = neighborIds[2]; - const float2 tmpLoc = neighborLoc[2]; - neighborDistSq[2] = neighborDistSq[3]; - neighborIds[2] = neighborIds[3]; - neighborLoc[2] = neighborLoc[3]; - neighborDistSq[3] = tmpDist; - neighborIds[3] = tmpId; - neighborLoc[3] = tmpLoc; - } - if (neighborDistSq[2] < neighborDistSq[1]) { - const float tmpDist = neighborDistSq[1]; - const float3 tmpId = neighborIds[1]; - const float2 tmpLoc = neighborLoc[1]; - neighborDistSq[1] = neighborDistSq[2]; - neighborIds[1] = neighborIds[2]; - neighborLoc[1] = neighborLoc[2]; - neighborDistSq[2] = tmpDist; - neighborIds[2] = tmpId; - neighborLoc[2] = tmpLoc; - } - if (neighborDistSq[1] < neighborDistSq[0]) { - const float tmpDist = neighborDistSq[0]; - const float3 tmpId = neighborIds[0]; - const float2 tmpLoc = neighborLoc[0]; - neighborDistSq[0] = neighborDistSq[1]; - neighborIds[0] = neighborIds[1]; - neighborLoc[0] = neighborLoc[1]; - neighborDistSq[1] = tmpDist; - neighborIds[1] = tmpId; - neighborLoc[1] = tmpLoc; - } - } - - [unroll] - for (int idx = 0; idx < 4; ++idx) { - if (neighborDistSq[idx] >= 1e9) { - continue; - } - + const float3 rid = float3(cube.x + cube.y, cube.x, cube.y); + const float3 neighbourHex = (scaledHex - rid) * invGridCount; float3 neighbour = p; - neighbour.xy = neighborLoc[idx]; + neighbour.xy = hex_to_cart(neighbourHex); const float d_cur = map(neighbour); if (d_cur < d) { d = d_cur; @@ -170,9 +109,9 @@ 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; + const float3 count = float3(_Ray_Marching_Cart_Grid_Count_X, _Ray_Marching_Cart_Grid_Count_Y, _Ray_Marching_Cart_Grid_Count_Z); + const float3 span = float3(_Ray_Marching_Cart_Grid_Span_X, _Ray_Marching_Cart_Grid_Span_Y, _Ray_Marching_Cart_Grid_Span_Z); + const float3 period = span / count; float3 half_period = period*0.5f; float3 which = floor((p + half_period) / period); if (any(abs(which) > count/2)) { @@ -190,27 +129,13 @@ float domain_repeat(inout float3 p) { return d; } -void ray_march(inout v2f i) { #if defined(_RAY_MARCHING) - float3 ro, rd; - GetRoRd(i, ro, rd); - -#if defined(_VERTEX_DEFORMATION) - // TODO optimize, we don't need to pass in `dummy`. - { - float3 dummy = 0; - float3 tmp_pos = ro; - undeform_normal(tmp_pos, dummy, rd); - rd = normalize(rd); - } -#endif - +bool get_one_hit(float3 ro, float3 rd, out float3 hitPos, out float hitD) { const float kMinDist = _Ray_Marching_Min_Dist; const float kMaxDist = _Ray_Marching_Max_Dist; 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; @@ -222,15 +147,93 @@ void ray_march(inout v2f i) { d_acc += d_cur; if (abs(d_cur) < kMinDist) { - hit_pos = p; - break; + hitPos = p; + hitD = d_acc; + return true; } if (d_acc > kMaxDist) { break; } } - if (abs(d_cur) >= kMinDist) { + return false; +} + +bool get_hit(float3 ro, float3 rd, out float3 hitPos, out float hitD) { +#if defined(_RAY_MARCHING_CART_INSTANCING) + const float3 span = float3( + _Ray_Marching_Cart_Instancing_Span_X, + _Ray_Marching_Cart_Instancing_Span_Y, + _Ray_Marching_Cart_Instancing_Span_Z) * 2.0f; + const float3 count = float3( + _Ray_Marching_Cart_Instancing_Count_X, + _Ray_Marching_Cart_Instancing_Count_Y, + _Ray_Marching_Cart_Instancing_Count_Z); + const float3 count_minus_1 = count - 1.0f; + const float3 offset = span / count; + const float3 midpoint = offset * count_minus_1 * 0.5f; +#if defined(_RAY_MARCHING_CART_INSTANCING_OFFSETS) + const float x_every_y = _Ray_Marching_Cart_Instancing_Offsets_X_Every_Y; + const float x_every_z = _Ray_Marching_Cart_Instancing_Offsets_X_Every_Z; + const float y_every_x = _Ray_Marching_Cart_Instancing_Offsets_Y_Every_X; + const float y_every_z = _Ray_Marching_Cart_Instancing_Offsets_Y_Every_Z; + const float z_every_x = _Ray_Marching_Cart_Instancing_Offsets_Z_Every_X; + const float z_every_y = _Ray_Marching_Cart_Instancing_Offsets_Z_Every_Y; + const float3 max_offset = float3( + count_minus_1.y * x_every_y + count_minus_1.z * x_every_z, + count_minus_1.x * y_every_x + count_minus_1.z * y_every_z, + count_minus_1.x * z_every_x + count_minus_1.y * z_every_y + ); + const float3 offset_midpoint = max_offset * 0.5f; +#endif + + hitD = 1e9; + for (uint xi = 0; xi < count.x; ++xi) + for (uint yi = 0; yi < count.y; ++yi) + for (uint zi = 0; zi < count.z; ++zi) { + float3 hitPos_tmp; + float hitD_tmp; + float3 cur_pos = ro + offset * float3(xi, yi, zi) - midpoint; +#if defined(_RAY_MARCHING_CART_INSTANCING_OFFSETS) + const float3 cur_offset = float3( + x_every_y * yi + x_every_z * zi, + y_every_x * xi + y_every_z * zi, + z_every_x * xi + z_every_y * yi); + cur_pos += cur_offset - offset_midpoint; +#endif + if (!get_one_hit(cur_pos, rd, hitPos_tmp, hitD_tmp)) { + continue; + } + if (hitD_tmp < hitD) { + hitPos = hitPos_tmp; + hitD = hitD_tmp; + } + } + return hitD != 1e9; +#else + return get_one_hit(ro, rd, hitPos, hitD); +#endif +} +#endif // _RAY_MARCHING + +void ray_march(inout v2f i) { +#if defined(_RAY_MARCHING) + float3 ro, rd; + GetRoRd(i, ro, rd); + +#if defined(_VERTEX_DEFORMATION) + // TODO optimize, we don't need to pass in `dummy`. + { + float3 dummy = 0; + float3 tmp_pos = ro; + undeform_normal(tmp_pos, dummy, rd); + rd = normalize(rd); + } +#endif + + float3 hit_pos; + float hit_d; + if (!get_hit(ro, rd, hit_pos, hit_d)) { discard; } |
