summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-10-12 13:48:35 -0700
committeryum <yum.food.vr@gmail.com>2025-10-12 13:48:35 -0700
commitd2090f73f3e4f08cdbd3c3b82eb7f3ba9f459dd0 (patch)
treec4ca182ee132d01331e0d8d9bd95530cab61a6d0
parentb056c6935128dd7e4a9572a946bab5c4bc08da32 (diff)
add plane<->tube deformation shader
-rw-r--r--3ner.cginc5
-rw-r--r--3ner.shader4
-rw-r--r--custom31.slang92
-rw-r--r--globals.cginc5
-rw-r--r--vertex.cginc12
5 files changed, 74 insertions, 44 deletions
diff --git a/3ner.cginc b/3ner.cginc
index 4b98812..a1ab224 100644
--- a/3ner.cginc
+++ b/3ner.cginc
@@ -184,14 +184,15 @@ float4 frag(v2f i, uint facing : SV_IsFrontFace
i.normal *= facing ? 1 : -1;
i.normal = normalize(i.normal);
i.tangent.xyz = normalize(i.tangent.xyz);
+
Pbr pbr = getPbr(i);
#if defined(_UNLIT)
return pbr.albedo;
-#else
+#endif
+
LightData light_data;
GetLighting(i, pbr, light_data);
return brdf(pbr, light_data);
-#endif
}
#endif // __3NER_INC
diff --git a/3ner.shader b/3ner.shader
index 47d414b..b31e85f 100644
--- a/3ner.shader
+++ b/3ner.shader
@@ -48,9 +48,7 @@ Shader "yum_food/3ner"
//ifex _Custom31_Tubes_Enabled==0
[HideInInspector] m_start_Custom31_Tubes("Tubes", Float) = 0
[ThryToggle(_CUSTOM31_TUBES)] _Custom31_Tubes_Enabled("Enable", Float) = 0
- _Custom31_Tubes_A("A", Range(0,1)) = 0
- _Custom31_Tubes_k("k", Range(0,8)) = 1
- _Custom31_Tubes_tk("time factor", Range(0,10)) = 1
+ _Custom31_Tubes_t("t", Range(0,1)) = 1
[HideInInspector] m_end_Custom31_Tubes("Tubes", Float) = 0
//endex
diff --git a/custom31.slang b/custom31.slang
index 4b0e003..1254800 100644
--- a/custom31.slang
+++ b/custom31.slang
@@ -1,14 +1,44 @@
#ifndef __CUSTOM31_INC
#define __CUSTOM31_INC
-#define PI 3.14159265f
-
-float3x3 inverse(float3x3 m) {
- float det =
- m._11 * (m._22 * m._33 - m._23 * m._32) -
- m._12 * (m._21 * m._33 - m._23 * m._31) +
- m._13 * (m._21 * m._32 - m._22 * m._31);
-
+#define PI 3.14159265f
+#define PI_RCP 0.31830988f
+
+// Differentiable absolute value.
+#define dabs(x) length(float2(x, 1e-6))
+#define dlerp(x, y, t) ((x) * (1-t) + (y) * t)
+
+// Macros for transforming normal and tangent using autodiff.
+// r3r3 refers to "r3 to r3 transform", aka a mapping between 3d real-valued
+// spaces.
+#define R3R3_DECLARE_BASIS_VECTORS \
+ DifferentialPair<float3> dp_x = diffPair(xyz, float3(1, 0, 0)); \
+ DifferentialPair<float3> dp_y = diffPair(xyz, float3(0, 1, 0)); \
+ DifferentialPair<float3> dp_z = diffPair(xyz, float3(0, 0, 1))
+
+#define R3R3_AUTODIFF_BASIS_VECTORS(fun, ...) \
+ DifferentialPair<float3> dp_x_out = fwd_diff(fun)(dp_x, __VA_ARGS__); \
+ DifferentialPair<float3> dp_y_out = fwd_diff(fun)(dp_y, __VA_ARGS__); \
+ DifferentialPair<float3> dp_z_out = fwd_diff(fun)(dp_z, __VA_ARGS__)
+
+#define R3R3_DEFORM_NORMAL_AND_TANGENT(normal, tangent) \
+ float3x3 jacobian = float3x3( \
+ float3(dp_x_out.d.x, dp_y_out.d.x, dp_z_out.d.x), \
+ float3(dp_x_out.d.y, dp_y_out.d.y, dp_z_out.d.y), \
+ float3(dp_x_out.d.z, dp_y_out.d.z, dp_z_out.d.z) \
+ ); \
+ float jac_det = determinant(jacobian); \
+ float3x3 itjac = inverse(transpose(jacobian), jac_det); \
+ normal = normalize(mul(itjac, normal)) * sign(jac_det); \
+ tangent = normalize(mul(jacobian, tangent))
+
+// Syntactic sugar - wraps the previous three macros.
+#define R3R3_NORMALS(normal, tangent, fun, ...) \
+ R3R3_DECLARE_BASIS_VECTORS; \
+ R3R3_AUTODIFF_BASIS_VECTORS(fun, __VA_ARGS__); \
+ R3R3_DEFORM_NORMAL_AND_TANGENT(normal, tangent)
+
+float3x3 inverse(float3x3 m, float det) {
if (abs(det) < 1e-6) {
return float3x3(
1,0,0,
@@ -53,26 +83,34 @@ public float3 c31_deform(float3 xyz, no_diff float A, no_diff float k, no_diff f
);
}
+
// Deform a normal vector using the inverse transpose of the jacobian.
-public void c31_deform_normal(float3 xyz, inout float3 normal, inout float3 tangent, float A, float k, float t) {
- // Compute jacobian using autodiff applied to basis vectors.
- DifferentialPair<float3> dp_x = diffPair(xyz, float3(1, 0, 0));
- DifferentialPair<float3> dp_y = diffPair(xyz, float3(0, 1, 0));
- DifferentialPair<float3> dp_z = diffPair(xyz, float3(0, 0, 1));
-
- DifferentialPair<float3> dp_x_out = fwd_diff(c31_deform)(dp_x, A, k, t);
- DifferentialPair<float3> dp_y_out = fwd_diff(c31_deform)(dp_y, A, k, t);
- DifferentialPair<float3> dp_z_out = fwd_diff(c31_deform)(dp_z, A, k, t);
-
- // Transform normal and tangent using jacobian
- float3x3 jacobian = float3x3(
- float3(dp_x_out.d.x, dp_y_out.d.x, dp_z_out.d.x),
- float3(dp_x_out.d.y, dp_y_out.d.y, dp_z_out.d.y),
- float3(dp_x_out.d.z, dp_y_out.d.z, dp_z_out.d.z)
- );
- float3x3 itjac = inverse(transpose(jacobian));
- normal = normalize(mul(itjac, normal));
- tangent = normalize(mul(jacobian, tangent));
+public void c31_deform_normal(float3 xyz, inout float3 normal,
+ inout float3 tangent, float A, float k, float t) {
+ R3R3_NORMALS(normal, tangent, c31_deform, A, k, t);
+}
+
+// Takes map 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;
+ float radius = min(1e3, (1.0f / (t * t)));
+
+ float x = sin(theta / radius) * radius * PI_RCP;
+ // The z0 term here is required to make the jacobian invertible.
+ float z = z0 + (1.0f - cos(theta / radius)) * radius * PI_RCP;
+
+ return float3(x, y0, z);
+}
+
+public void plane_to_tube_normal(float3 xyz, inout float3 normal,
+ inout float3 tangent, float t) {
+ R3R3_NORMALS(normal, tangent, plane_to_tube, t);
}
#endif // __CUSTOM31_INC
diff --git a/globals.cginc b/globals.cginc
index f615136..38a1019 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -58,10 +58,7 @@ texture2D _Cloth_Sheen_DFG_LUT;
#endif // _CLOTH_SHEEN
#if defined(_CUSTOM31_TUBES)
-float _Custom31_Tubes_Speed;
-float _Custom31_Tubes_A;
-float _Custom31_Tubes_k;
-float _Custom31_Tubes_tk;
+float _Custom31_Tubes_t;
#endif // _CUSTOM31_TUBES
#endif // __GLOBALS_INC
diff --git a/vertex.cginc b/vertex.cginc
index 0140ff2..fd08bbb 100644
--- a/vertex.cginc
+++ b/vertex.cginc
@@ -5,19 +5,15 @@
void deform(inout float3 objPos) {
#if defined(_CUSTOM31_TUBES)
- float A = _Custom31_Tubes_A;
- float k = _Custom31_Tubes_k;
- float t = _Time[2] * _Custom31_Tubes_tk;
- objPos = c31_deform(objPos, A, k, t);
+ float t = _Custom31_Tubes_t;
+ objPos = plane_to_tube(objPos, t);
#endif // _CUSTOM31_TUBES
}
void deform_normal(float3 objPos, inout float3 objNorm, inout float3 objTan) {
#if defined(_CUSTOM31_TUBES)
- float A = _Custom31_Tubes_A;
- float k = _Custom31_Tubes_k;
- float t = _Time[2] * _Custom31_Tubes_tk;
- c31_deform_normal(objPos, objNorm, objTan, A, k, t);
+ float t = _Custom31_Tubes_t;
+ plane_to_tube_normal(objPos, objNorm, objTan, t);
#endif // _CUSTOM31_TUBES
}