summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--3ner.shader9
-rw-r--r--globals.cginc16
-rw-r--r--vertex.cginc27
-rw-r--r--vertex_deformation.slang87
4 files changed, 105 insertions, 34 deletions
diff --git a/3ner.shader b/3ner.shader
index 1334699..249f02b 100644
--- a/3ner.shader
+++ b/3ner.shader
@@ -207,6 +207,9 @@ Shader "yum_food/3ner"
//ifex _Vertex_Deformation_XZ_Tube_Enabled==0
[HideInInspector] m_start_Vertex_Deformation_XZ_Tube("XZ Tube", Float) = 0
[ThryToggle(_VERTEX_DEFORMATION_XZ_TUBE)] _Vertex_Deformation_XZ_Tube_Enabled("Enable", Float) = 0
+ _Vertex_Deformation_XZ_Tube_p("p", Vector) = (0, 0, 1)
+ _Vertex_Deformation_XZ_Tube_r("r", Vector) = (0, 0, -1)
+ _Vertex_Deformation_XZ_Tube_r("s", Vector) = (0, 0, -1)
_Vertex_Deformation_XZ_Tube_t("t", Range(-1,1)) = 0
[HideInInspector] m_end_Vertex_Deformation_XZ_Tube("XZ Tube", Float) = 0
//endex
@@ -214,6 +217,9 @@ Shader "yum_food/3ner"
//ifex _Vertex_Deformation_YZ_Tube_Enabled==0
[HideInInspector] m_start_Vertex_Deformation_YZ_Tube("YZ Tube", Float) = 0
[ThryToggle(_VERTEX_DEFORMATION_YZ_TUBE)] _Vertex_Deformation_YZ_Tube_Enabled("Enable", Float) = 0
+ _Vertex_Deformation_YZ_Tube_p("p", Vector) = (0, 0, 1)
+ _Vertex_Deformation_YZ_Tube_r("r", Vector) = (0, 0, -1)
+ _Vertex_Deformation_YZ_Tube_s("s", Vector) = (0, 0, -1)
_Vertex_Deformation_YZ_Tube_t("t", Range(-1,1)) = 0
[HideInInspector] m_end_Vertex_Deformation_YZ_Tube("YZ Tube", Float) = 0
//endex
@@ -221,6 +227,9 @@ Shader "yum_food/3ner"
//ifex _Vertex_Deformation_XY_Tube_Enabled==0
[HideInInspector] m_start_Vertex_Deformation_XY_Tube("XY Tube", Float) = 0
[ThryToggle(_VERTEX_DEFORMATION_XY_TUBE)] _Vertex_Deformation_XY_Tube_Enabled("Enable", Float) = 0
+ _Vertex_Deformation_XY_Tube_p("p", Vector) = (0, 0, 1)
+ _Vertex_Deformation_XY_Tube_r("r", Vector) = (0, 0, -1)
+ _Vertex_Deformation_XY_Tube_s("s", Vector) = (0, 0, -1)
_Vertex_Deformation_XY_Tube_t("t", Range(-1,1)) = 0
[HideInInspector] m_end_Vertex_Deformation_XY_Tube("XY Tube", Float) = 0
//endex
diff --git a/globals.cginc b/globals.cginc
index 4e03e0b..c838091 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -75,9 +75,6 @@ float3 _Cloth_Sheen_Color;
texture2D _Cloth_Sheen_DFG_LUT;
#endif // _CLOTH_SHEEN
-#if defined(_VERTEX_DEFORMATION_XY_TUBE)
-float _Vertex_Deformation_XY_Tube_t;
-#endif // _VERTEX_DEFORMATION_XY_TUBE
#if defined(_VERTEX_DEFORMATION_XY_UNTUBE)
float _Vertex_Deformation_XY_Untube_t;
#endif // _VERTEX_DEFORMATION_XY_UNTUBE
@@ -87,10 +84,23 @@ float _Vertex_Deformation_XZ_Untube_t;
#if defined(_VERTEX_DEFORMATION_YZ_UNTUBE)
float _Vertex_Deformation_YZ_Untube_t;
#endif // _VERTEX_DEFORMATION_YZ_UNTUBE
+
+#if defined(_VERTEX_DEFORMATION_XY_TUBE)
+float3 _Vertex_Deformation_XY_Tube_p;
+float3 _Vertex_Deformation_XY_Tube_r;
+float3 _Vertex_Deformation_XY_Tube_s;
+float _Vertex_Deformation_XY_Tube_t;
+#endif // _VERTEX_DEFORMATION_XY_TUBE
#if defined(_VERTEX_DEFORMATION_XZ_TUBE)
+float3 _Vertex_Deformation_XZ_Tube_p;
+float3 _Vertex_Deformation_XZ_Tube_r;
+float3 _Vertex_Deformation_XZ_Tube_s;
float _Vertex_Deformation_XZ_Tube_t;
#endif // _VERTEX_DEFORMATION_XZ_TUBE
#if defined(_VERTEX_DEFORMATION_YZ_TUBE)
+float3 _Vertex_Deformation_YZ_Tube_p;
+float3 _Vertex_Deformation_YZ_Tube_r;
+float3 _Vertex_Deformation_YZ_Tube_s;
float _Vertex_Deformation_YZ_Tube_t;
#endif // _VERTEX_DEFORMATION_YZ_TUBE
diff --git a/vertex.cginc b/vertex.cginc
index f82fad6..daa5ce0 100644
--- a/vertex.cginc
+++ b/vertex.cginc
@@ -61,11 +61,14 @@
#if defined(_VERTEX_DEFORMATION_XZ_TUBE)
#define VERTEX_DEFORM_XZ_TUBE_PREAMBLE \
+ float3 p = _Vertex_Deformation_XZ_Tube_p; \
+ float3 r = _Vertex_Deformation_XZ_Tube_r; \
+ float3 s = _Vertex_Deformation_XZ_Tube_s; \
float t = _Vertex_Deformation_XZ_Tube_t
#define VERTEX_DEFORM_XZ_TUBE_POS \
- objPos = plane_to_tube(objPos.xyz, t)
+ objPos = plane_to_tube(objPos.xyz, p, r, s, t)
#define VERTEX_DEFORM_XZ_TUBE_NORM \
- plane_to_tube_normal(objPos, objNorm, objTan, t)
+ plane_to_tube_normal(objPos.xyz, objNorm, objTan, p, r, s, t)
#else
#define VERTEX_DEFORM_XZ_TUBE_PREAMBLE
#define VERTEX_DEFORM_XZ_TUBE_POS
@@ -74,15 +77,18 @@
#if defined(_VERTEX_DEFORMATION_YZ_TUBE)
#define VERTEX_DEFORM_YZ_TUBE_PREAMBLE \
+ float3 p = _Vertex_Deformation_YZ_Tube_p; \
+ float3 r = _Vertex_Deformation_YZ_Tube_r; \
+ float3 s = _Vertex_Deformation_YZ_Tube_s; \
float t = _Vertex_Deformation_YZ_Tube_t
#define VERTEX_DEFORM_YZ_TUBE_POS \
- objPos = plane_to_tube(objPos.yxz, t); \
+ objPos = plane_to_tube(objPos.yxz, p, r, s, t); \
objPos = objPos.yxz
#define VERTEX_DEFORM_YZ_TUBE_NORM \
float3 yzPos = objPos.yxz; \
float3 yzNorm = objNorm.yxz; \
float3 yzTan = objTan.yxz; \
- plane_to_tube_normal(yzPos, yzNorm, yzTan, t); \
+ plane_to_tube_normal(yzPos, yzNorm, yzTan, p, r, s, t); \
objPos = yzPos.yxz; \
objNorm = yzNorm.yxz; \
objTan = yzTan.yxz
@@ -94,15 +100,18 @@
#if defined(_VERTEX_DEFORMATION_XY_TUBE)
#define VERTEX_DEFORM_XY_TUBE_PREAMBLE \
+ float3 p = _Vertex_Deformation_XY_Tube_p; \
+ float3 r = _Vertex_Deformation_XY_Tube_r; \
+ float3 s = _Vertex_Deformation_XY_Tube_s; \
float t = _Vertex_Deformation_XY_Tube_t
#define VERTEX_DEFORM_XY_TUBE_POS \
- objPos = plane_to_tube(objPos.xzy, t); \
+ objPos = plane_to_tube(objPos.xzy, p, r, s, t); \
objPos = objPos.xzy
#define VERTEX_DEFORM_XY_TUBE_NORM \
float3 xyPos = objPos.xzy; \
float3 xyNorm = objNorm.xzy; \
float3 xyTan = objTan.xzy; \
- plane_to_tube_normal(xyPos, xyNorm, xyTan, t); \
+ plane_to_tube_normal(xyPos, xyNorm, xyTan, p, r, s, t); \
objPos = xyPos.xzy; \
objNorm = xyNorm.xzy; \
objTan = xyTan.xzy
@@ -406,7 +415,7 @@ void undeform_normal(inout float3 objPos, inout float3 objNorm, inout float3 obj
float3 xyPos = stageInput.xzy;
float3 xyNorm = objNorm.xzy;
float3 xyTan = objTan.xzy;
- plane_to_tube_undeform_normal(xyPos, xyNorm, xyTan, t);
+ plane_to_tube_undeform_normal(xyPos, xyNorm, xyTan, p, r, s, t);
objNorm = xyNorm.xzy;
objTan = xyTan.xzy;
objPos = stageInput;
@@ -420,7 +429,7 @@ void undeform_normal(inout float3 objPos, inout float3 objNorm, inout float3 obj
float3 yzPos = stageInput.yxz;
float3 yzNorm = objNorm.yxz;
float3 yzTan = objTan.yxz;
- plane_to_tube_undeform_normal(yzPos, yzNorm, yzTan, t);
+ plane_to_tube_undeform_normal(yzPos, yzNorm, yzTan, p, r, s, t);
objNorm = yzNorm.yxz;
objTan = yzTan.yxz;
objPos = stageInput;
@@ -431,7 +440,7 @@ void undeform_normal(inout float3 objPos, inout float3 objNorm, inout float3 obj
if (cursor > 0) {
VERTEX_DEFORM_XZ_TUBE_PREAMBLE;
float3 stageInput = posHistory[cursor - 1];
- plane_to_tube_undeform_normal(stageInput, objNorm, objTan, t);
+ plane_to_tube_undeform_normal(stageInput, objNorm, objTan, p, r, s, t);
objPos = stageInput;
cursor -= 1;
}
diff --git a/vertex_deformation.slang b/vertex_deformation.slang
index 577b0d2..f22e71f 100644
--- a/vertex_deformation.slang
+++ b/vertex_deformation.slang
@@ -5,6 +5,8 @@
#define PI_RCP 0.31830988f
#define TAU (2.0f * PI)
#define HALF_PI (0.5f * PI)
+#define RCP_PI (1.0f / PI)
+#define RCP_TAU (1.0f / TAU)
#define glsl_mod(x,y) (((x)-(y)*floor((x)/(y))))
@@ -65,7 +67,8 @@
R3R3_DEFORM_NORMAL_AND_TANGENT(normal, tangent); \
xyz = fun(xyz, __VA_ARGS__)
-float3x3 inverse(float3x3 m, float det) {
+[Differentiable]
+float3x3 inverse(no_diff float3x3 m, no_diff float det) {
det = max(1e-6 * abs(det), abs(det)) * sign(det);
float invDet = 1.0f / det;
@@ -84,34 +87,70 @@ float3x3 inverse(float3x3 m, float det) {
return inv;
}
+float2 project_x_onto_y(float2 x, float2 y) {
+ return (dot(x, y) / dot(y, y)) * y;
+}
+
// Maps a 2x2 quad on the xy plane to a tube. The circular cross section
// is on the xz plane.
[Differentiable]
-public float3 plane_to_tube(float3 xyz, no_diff float t) {
- float x0 = xyz.x;
- float y0 = xyz.y;
- float z0 = xyz.z;
-
- float theta = x0 * PI;
-
- // Equivalent to (1 / (|t| + eps)) * sign(t)
- float radius = 1.0f / (dabs(t) + 1e-4f) * sign(t);
+public float3 plane_to_tube(float3 xyz, no_diff float3 p, no_diff float3 r, no_diff float3 s, no_diff float t) {
+ xyz = 0;
+ // Convert from cartesian to (r, s, r x s) space.
+ // Ensure orthonormal basis vectors.
+ // TODO remove normalize, do at higher level of stack.
+ r = normalize(r);
+ s = normalize(s);
+ float3 rxs = cross(r, s);
+ float3x3 to_rsrxs = transpose(float3x3(r, s, rxs));
+ float3x3 to_cart = inverse(to_rsrxs, determinant(to_rsrxs));
+
+ // Translate origin to `p` then change into (r, s, r x s) basis.
+ xyz = mul(to_rsrxs, xyz - p);
+
+ // Project onto (r, r x s) plane.
+ float2 v0 = xyz.xz;
+
+ float2 v0_hat = normalize(v0);
+ float2 Lr = float2(v0.x, 0);
+ float2 Lv0 = float2(0, v0.y);
+ float Lr_norm = abs(Lr.x);
+ float Lv0_norm = abs(Lv0.y);
+ float epsilon = 1e-4;
+ float theta = Lv0_norm / (Lr_norm + epsilon);
+ float phi = atan2(Lv0_norm, Lr_norm);
+ float theta_p = lerp(theta, phi, t);
+ float2x2 rot = float2x2(
+ cos(theta_p), -sin(theta_p),
+ sin(theta_p), cos(theta_p));
+
+ // float2(1, 0) is written as `r` in (2) in the notes. We just rewrite it
+ // here since we're in the rotated frame.
+ // We also don't have to add p since again we're in the rotated and
+ // translated frame.
+ float2 v = mul(rot, dlerp(float2(1, 0) * Lv0_norm, Lr, t));
+
+ // Un-project.
+ xyz.xz = v.xy;
+
+ // Move back into cartesian basis.
+ xyz = mul(to_cart, xyz);
+
+ // Translate p back away from origin.
+ xyz += p;
- float x = sin(theta / radius) * (radius * PI_RCP - z0);
- float z = (1.0f - cos(theta / radius)) * (radius * PI_RCP) + cos(theta / radius) * z0;
-
- return float3(x, y0, z);
+ return xyz;
}
public void plane_to_tube_normal(inout float3 xyz, inout float3 normal,
- inout float3 tangent, float t) {
- R3R3_NORMALS(xyz, normal, tangent, plane_to_tube, t);
+ inout float3 tangent, float3 p, float3 r, float3 s, float t) {
+ R3R3_NORMALS(xyz, normal, tangent, plane_to_tube, p, r, s, t);
}
public void plane_to_tube_undeform_normal(float3 xyz, inout float3 normal,
- inout float3 tangent, float t) {
+ inout float3 tangent, float3 p, float3 r, float3 s, float t) {
R3R3_DECLARE_BASIS_VECTORS(xyz);
- R3R3_AUTODIFF_BASIS_VECTORS(plane_to_tube, t);
+ R3R3_AUTODIFF_BASIS_VECTORS(plane_to_tube, p, r, s, t);
R3R3_UNDEFORM_NORMAL_AND_TANGENT(normal, tangent);
}
@@ -123,10 +162,15 @@ public float3 tube_to_plane(float3 xyz, no_diff float t) {
float y0 = xyz.y;
float z0 = xyz.z;
- float theta = atan2(z0, x0) - PI;
+ // Tube has 2m circumference.
+ // C = pi d = 2 pi r
+ // r = C / (2 pi) = 2 / 2 pi = 1 / pi
+ float ref_r = RCP_PI;
+ float theta = atan2(z0 - ref_r, x0 - ref_r) - PI;
float r = length(float2(x0, z0));
- x0 = r * cos(theta);
- z0 = r * sin(theta);
+
+ x0 = x0 + r * cos(theta);
+ z0 = z0 - r * sin(theta);
// Equivalent to (1 / (|t| + eps)) * sign(t)
float radius = 1.0f / (dabs(t) + 1e-4f) * sign(t);
@@ -245,7 +289,6 @@ float rand3_hash1(float3 p)
// Calculate value noise and jacobian in one shot.
// Based on https://iquilezles.org/articles/morenoise/
-[Differentiable]
float3 value_noise(float3 xyz, out float3 dx, out float3 dy, out float3 dz) {
float3 cell = floor(xyz);
float3 f = xyz - cell;