diff options
| author | yum <yum.food.vr@gmail.com> | 2025-10-12 13:48:35 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-10-12 13:48:35 -0700 |
| commit | d2090f73f3e4f08cdbd3c3b82eb7f3ba9f459dd0 (patch) | |
| tree | c4ca182ee132d01331e0d8d9bd95530cab61a6d0 | |
| parent | b056c6935128dd7e4a9572a946bab5c4bc08da32 (diff) | |
add plane<->tube deformation shader
| -rw-r--r-- | 3ner.cginc | 5 | ||||
| -rw-r--r-- | 3ner.shader | 4 | ||||
| -rw-r--r-- | custom31.slang | 92 | ||||
| -rw-r--r-- | globals.cginc | 5 | ||||
| -rw-r--r-- | vertex.cginc | 12 |
5 files changed, 74 insertions, 44 deletions
@@ -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 } |
