summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--3ner.cginc2
-rw-r--r--3ner.shader37
-rw-r--r--features.cginc8
-rw-r--r--globals.cginc21
-rw-r--r--math.cginc2
-rw-r--r--ray_marching.cginc207
6 files changed, 168 insertions, 109 deletions
diff --git a/3ner.cginc b/3ner.cginc
index d5f380f..e45e0cd 100644
--- a/3ner.cginc
+++ b/3ner.cginc
@@ -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)
diff --git a/math.cginc b/math.cginc
index f188a91..c37ce07 100644
--- a/math.cginc
+++ b/math.cginc
@@ -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;
}