From 228e555dbd07dd1a332a07770106dfd98f918c9b Mon Sep 17 00:00:00 2001 From: yum Date: Sun, 12 Oct 2025 21:52:50 -0700 Subject: fornite update --- 3ner.cginc | 12 ++--- 3ner.shader | 96 +++++++++++++++++++++------------------ brdf.cginc | 10 ++-- custom31.slang | 89 ------------------------------------ features.cginc | 21 +++++---- globals.cginc | 24 ++++++---- interpolators.cginc | 2 +- vertex.cginc | 54 ++++++++++++++-------- vertex_deformation.slang | 116 +++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 244 insertions(+), 180 deletions(-) delete mode 100644 custom31.slang create mode 100644 vertex_deformation.slang diff --git a/3ner.cginc b/3ner.cginc index bac74ad..26b2a3d 100644 --- a/3ner.cginc +++ b/3ner.cginc @@ -28,14 +28,14 @@ v2f vert(appdata v) { #endif o.uv0 = v.uv0; o.objPos = v.vertex; -#if defined(_CUSTOM31_FRAGMENT_NORMALS) || defined(_CUSTOM31_TESSELLATION) +#if defined(_VERTEX_DEFORMATION_FRAGMENT_NORMALS) || defined(_VERTEX_DEFORMATION_TESSELLATION) o.objPos_orig = v.vertex; #endif // Normal and tangent are in object space. o.normal = v.normal; o.tangent = v.tangent; -#if !defined(_CUSTOM31_FRAGMENT_NORMALS) +#if !defined(_VERTEX_DEFORMATION_FRAGMENT_NORMALS) deform_normal(o.objPos, o.normal.xyz, o.tangent.xyz); #endif deform(o.objPos); @@ -158,7 +158,7 @@ v2f domain( o.objPos = DOMAIN_INTERP(objPos); #endif -#if defined(_CUSTOM31_FRAGMENT_NORMALS) || defined(_CUSTOM31_TESSELLATION) +#if defined(_VERTEX_DEFORMATION_FRAGMENT_NORMALS) || defined(_VERTEX_DEFORMATION_TESSELLATION) o.objPos_orig = DOMAIN_INTERP(objPos_orig); o.objPos = o.objPos_orig; deform(o.objPos); @@ -189,7 +189,7 @@ void geom(triangle v2f tri_in[3], float3 n0 = v0.normal; float3 n1 = v1.normal; float3 n2 = v2.normal; -#if defined(_CUSTOM31_FRAGMENT_NORMALS) || defined(_CUSTOM31_TESSELLATION) +#if defined(_VERTEX_DEFORMATION_FRAGMENT_NORMALS) || defined(_VERTEX_DEFORMATION_TESSELLATION) float3 tmp; deform_normal(v0.objPos_orig, n0, tmp); deform_normal(v1.objPos_orig, n1, tmp); @@ -218,11 +218,11 @@ void geom(triangle v2f tri_in[3], //endex float4 frag(v2f i, uint facing : SV_IsFrontFace -#if defined(_CUSTOM31_TUBES) +#if defined(_VERTEX_DEFORMATION_TUBES) , out float depth : SV_DepthLessEqual #endif ) : SV_Target { -#if defined(_CUSTOM31_FRAGMENT_NORMALS) +#if defined(_VERTEX_DEFORMATION_FRAGMENT_NORMALS) deform_normal(i.objPos_orig, i.normal, i.tangent.xyz); #endif diff --git a/3ner.shader b/3ner.shader index aad3949..d8c9f56 100644 --- a/3ner.shader +++ b/3ner.shader @@ -55,61 +55,71 @@ Shader "yum_food/3ner" [HideInInspector] m_end_Geometry_Shader("Geometry Shader", Float) = 0 //endex - //ifex _Custom31_Enabled==0 - [HideInInspector] m_start_Custom31("Custom31", Float) = 0 - [ThryToggle(_CUSTOM31)] _Custom31_Enabled("Enable", Float) = 0 - [ThryToggle(_CUSTOM31_FRAGMENT_NORMALS)] _Custom31_Fragment_Normals_Enabled("Fragment normals", Float) = 0 - [ThryToggle(_CUSTOM31_TESSELLATION)] _Custom31_Tessellation_Enabled("Tesellation support", Float) = 1 - - //ifex _Custom31_Tubes_Enabled==0 - [HideInInspector] m_start_Custom31_Tubes("Tubes", Float) = 0 - [ThryToggle(_CUSTOM31_TUBES)] _Custom31_Tubes_Enabled("Enable", Float) = 0 - - //ifex _Custom31_XZ_Tube_Enabled==0 - [HideInInspector] m_start_Custom31_XZ_Tube("XZ Tube", Float) = 0 - [ThryToggle(_CUSTOM31_XZ_TUBE)] _Custom31_XZ_Tube_Enabled("Enable", Float) = 0 + //ifex _Vertex_Deformation_Enabled==0 + [HideInInspector] m_start_Vertex_Deformation("Vertex Deformation", Float) = 0 + [ThryToggle(_VERTEX_DEFORMATION)] _Vertex_Deformation_Enabled("Enable", Float) = 0 + [ThryToggle(_VERTEX_DEFORMATION_FRAGMENT_NORMALS)] _Vertex_Deformation_Fragment_Normals_Enabled("Fragment normals", Float) = 0 + [ThryToggle(_VERTEX_DEFORMATION_TESSELLATION)] _Vertex_Deformation_Tessellation_Enabled("Tesellation support", Float) = 1 + + //ifex _Vertex_Deformation_Tubes_Enabled==0 + [HideInInspector] m_start_Vertex_Deformation_Tubes("Tubes", Float) = 0 + [ThryToggle(_VERTEX_DEFORMATION_TUBES)] _Vertex_Deformation_Tubes_Enabled("Enable", Float) = 0 + + //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 // 0.999... limit prevents NaNs which show up at 1.0 - _Custom31_XZ_Tube_t("t", Range(-1,1)) = 0 - [HideInInspector] m_end_Custom31_XZ_Tube("XZ Tube", Float) = 0 + _Vertex_Deformation_XZ_Tube_t("t", Range(-1,1)) = 0 + [HideInInspector] m_end_Vertex_Deformation_XZ_Tube("XZ Tube", Float) = 0 //endex - //ifex _Custom31_YZ_Tube_Enabled==0 - [HideInInspector] m_start_Custom31_YZ_Tube("YZ Tube", Float) = 0 - [ThryToggle(_CUSTOM31_YZ_TUBE)] _Custom31_YZ_Tube_Enabled("Enable", Float) = 0 - _Custom31_YZ_Tube_t("t", Range(-1,1)) = 0 - [HideInInspector] m_end_Custom31_YZ_Tube("YZ Tube", Float) = 0 + //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_t("t", Range(-1,1)) = 0 + [HideInInspector] m_end_Vertex_Deformation_YZ_Tube("YZ Tube", Float) = 0 //endex - //ifex _Custom31_XY_Tube_Enabled==0 - [HideInInspector] m_start_Custom31_XY_Tube("XY Tube", Float) = 0 - [ThryToggle(_CUSTOM31_XY_TUBE)] _Custom31_XY_Tube_Enabled("Enable", Float) = 0 - _Custom31_XY_Tube_t("t", Range(-1,1)) = 0 - [HideInInspector] m_end_Custom31_XY_Tube("XY Tube", Float) = 0 + //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_t("t", Range(-1,1)) = 0 + [HideInInspector] m_end_Vertex_Deformation_XY_Tube("XY Tube", Float) = 0 //endex - [HideInInspector] m_end_Custom31_Tubes("Tubes", Float) = 0 + [HideInInspector] m_end_Vertex_Deformation_Tubes("Tubes", Float) = 0 //endex - //ifex _UV_Scroll_Enabled==0 - [HideInInspector] m_start_UV_Scroll("UV Scroll", Float) = 0 - [ThryToggle(_UV_SCROLL)] _UV_Scroll_Enabled("Enable", Float) = 0 - _UV_Scroll_Speed("Speed (u, v, 0, 0)", Vector) = (0, -1, 0, 0) - [HideInInspector] m_end_UV_Scroll("UV Scroll", Float) = 0 + //ifex _Vertex_Deformation_Seal_Enabled==0 + [HideInInspector] m_start_Vertex_Deformation_Seal("Seal", Float) = 0 + [ThryToggle(_VERTEX_DEFORMATION_SEAL)] _Vertex_Deformation_Seal_Enabled("Enable", Float) = 0 + _Vertex_Deformation_Seal_A("A", Range(0,1)) = 0.1 + _Vertex_Deformation_Seal_k("k", Range(0,3)) = 1 + _Vertex_Deformation_Seal_t("t", Range(0,1)) = 0.1 + [HideInInspector] m_end_Vertex_Deformation_Seal("Seal", Float) = 0 //endex - //ifex _Marble_Enabled==0 - [HideInInspector] m_start_Marble("Marble", Float) = 0 - [ThryToggle(_MARBLE)] _Marble_Enabled("Enable", Float) = 0 - [Gradient] _Marble_U_Ramp("U Ramp", 2D) = "white" {} - [Gradient] _Marble_V_Ramp("V Ramp", 2D) = "white" {} - [Gradient] _Marble_W_Ramp("W Ramp", 2D) = "white" {} - _Marble_Scale("Scale", Vector) = (1, 1, 1, 0) - _Marble_Strength("Strength", Float) = 1 - _Marble_Octaves("Octaves", Range(1, 10)) = 3 - [HideInInspector] m_end_Marble("Marble", Float) = 0 - //endex + [HideInInspector] m_end_Vertex_Deformation("Vertex Deformation", Float) = 0 + + //ifex _UV_Scroll_Enabled==0 + [HideInInspector] m_start_UV_Scroll("UV Scroll", Float) = 0 + [ThryToggle(_UV_SCROLL)] _UV_Scroll_Enabled("Enable", Float) = 0 + _UV_Scroll_Speed("Speed (u, v, 0, 0)", Vector) = (0, -1, 0, 0) + [HideInInspector] m_end_UV_Scroll("UV Scroll", Float) = 0 + //endex + + //ifex _Marble_Enabled==0 + [HideInInspector] m_start_Marble("Marble", Float) = 0 + [ThryToggle(_MARBLE)] _Marble_Enabled("Enable", Float) = 0 + [Gradient] _Marble_U_Ramp("U Ramp", 2D) = "white" {} + [Gradient] _Marble_V_Ramp("V Ramp", 2D) = "white" {} + [Gradient] _Marble_W_Ramp("W Ramp", 2D) = "white" {} + _Marble_Scale("Scale", Vector) = (1, 1, 1, 0) + _Marble_Strength("Strength", Float) = 1 + _Marble_Octaves("Octaves", Range(1, 10)) = 3 + [HideInInspector] m_end_Marble("Marble", Float) = 0 + //endex - [HideInInspector] m_end_Custom31("Custom31", Float) = 0 //endex [HideInInspector] m_end_Gimmicks("Gimmicks", Float) = 0 diff --git a/brdf.cginc b/brdf.cginc index d89558c..8352c08 100644 --- a/brdf.cginc +++ b/brdf.cginc @@ -138,7 +138,7 @@ float4 brdf(Pbr pbr, LightData data) { // Direct { - float remainder = 1.0f; + float3 remainder = 1.0f; #if defined(_CLEARCOAT) float cc_f0 = 0.04f; @@ -149,7 +149,7 @@ float4 brdf(Pbr pbr, LightData data) { float3 direct_specular_cc = DFGcc * data.direct.color * data.direct.NoL_cc * pbr.cc_strength; direct_specular_cc = max(0, direct_specular_cc); specular += direct_specular_cc; - remainder -= Fcc * pbr.cc_strength; + remainder = saturate(remainder - direct_specular_cc); #endif #if defined(_CLOTH_SHEEN) @@ -173,7 +173,7 @@ float4 brdf(Pbr pbr, LightData data) { float3 direct_specular = FDG * remainder * data.direct.color * data.direct.NoL * lerp(1.0f, pbr.albedo.xyz, pbr.metallic); direct_specular = max(0, direct_specular); specular += direct_specular; - remainder -= F; + remainder = saturate(remainder - direct_specular); float Fd = Fd_OrenNayar(pbr.roughness, data.common.NoV, data.direct.NoL, data.direct.LoV) / PI; float3 direct_diffuse = Fd * remainder * (1.0f - pbr.metallic) * pbr.albedo.xyz * data.direct.color; @@ -184,7 +184,7 @@ float4 brdf(Pbr pbr, LightData data) { // Indirect #if defined(FORWARD_BASE_PASS) { - float remainder = 1.0f; + float3 remainder = 1.0f; float2 dfg_uv = float2(pbr.roughness, data.common.NoV); #if defined(_CLEARCOAT) @@ -192,7 +192,7 @@ float4 brdf(Pbr pbr, LightData data) { float Fcc = F_Schlick(data.common.NoV, cc_f0, 1.0f); float3 indirect_specular_cc = Fcc * data.indirect.specular_cc * pbr.cc_strength; specular += indirect_specular_cc; - remainder -= Fcc * pbr.cc_strength; + remainder = saturate(remainder - indirect_specular_cc); #endif #if defined(_CLOTH_SHEEN) diff --git a/custom31.slang b/custom31.slang deleted file mode 100644 index 441daeb..0000000 --- a/custom31.slang +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef __CUSTOM31_INC -#define __CUSTOM31_INC - -#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 dp_x = diffPair(xyz, float3(1, 0, 0)); \ - DifferentialPair dp_y = diffPair(xyz, float3(0, 1, 0)); \ - DifferentialPair dp_z = diffPair(xyz, float3(0, 0, 1)) - -#define R3R3_AUTODIFF_BASIS_VECTORS(fun, ...) \ - DifferentialPair dp_x_out = fwd_diff(fun)(dp_x, __VA_ARGS__); \ - DifferentialPair dp_y_out = fwd_diff(fun)(dp_y, __VA_ARGS__); \ - DifferentialPair 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, - 0,1,0, - 0,0,1); - } - - float invDet = 1.0f / det; - float3x3 inv; - - inv._11 = (m._22 * m._33 - m._23 * m._32) * invDet; - inv._12 = (m._13 * m._32 - m._12 * m._33) * invDet; - inv._13 = (m._12 * m._23 - m._13 * m._22) * invDet; - inv._21 = (m._23 * m._31 - m._21 * m._33) * invDet; - inv._22 = (m._11 * m._33 - m._13 * m._31) * invDet; - inv._23 = (m._13 * m._21 - m._11 * m._23) * invDet; - inv._31 = (m._21 * m._32 - m._22 * m._31) * invDet; - inv._32 = (m._31 * m._12 - m._11 * m._32) * invDet; - inv._33 = (m._11 * m._22 - m._12 * m._21) * invDet; - - return inv; -} - -// 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))) * sign(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/features.cginc b/features.cginc index ce8d07d..5ab9cb6 100644 --- a/features.cginc +++ b/features.cginc @@ -23,16 +23,21 @@ #pragma shader_feature_local _CLOTH_SHEEN //endex -//ifex _Custom31_Enabled==0 -#pragma shader_feature_local _CUSTOM31 -#pragma shader_feature_local _CUSTOM31_FRAGMENT_NORMALS +//ifex _Vertex_Deformation_Enabled==0 +#pragma shader_feature_local _VERTEX_DEFORMATION +#pragma shader_feature_local _VERTEX_DEFORMATION_FRAGMENT_NORMALS +#pragma shader_feature_local _VERTEX_DEFORMATION_TESSELLATION //endex -//ifex _Custom31_Tubes_Enabled==0 -#pragma shader_feature_local _CUSTOM31_TUBES -#pragma shader_feature_local _CUSTOM31_XZ_TUBE -#pragma shader_feature_local _CUSTOM31_YZ_TUBE -#pragma shader_feature_local _CUSTOM31_XY_TUBE +//ifex _Vertex_Deformation_Tubes_Enabled==0 +#pragma shader_feature_local _VERTEX_DEFORMATION_TUBES +#pragma shader_feature_local _VERTEX_DEFORMATION_XZ_TUBE +#pragma shader_feature_local _VERTEX_DEFORMATION_YZ_TUBE +#pragma shader_feature_local _VERTEX_DEFORMATION_XY_TUBE +//endex + +//ifex _Vertex_Deformation_Seal_Enabled==0 +#pragma shader_feature_local _VERTEX_DEFORMATION_SEAL //endex //ifex _Unlit==0 diff --git a/globals.cginc b/globals.cginc index 3ba2e60..c460285 100644 --- a/globals.cginc +++ b/globals.cginc @@ -58,15 +58,21 @@ float3 _Cloth_Sheen_Color; texture2D _Cloth_Sheen_DFG_LUT; #endif // _CLOTH_SHEEN -#if defined(_CUSTOM31_XY_TUBE) -float _Custom31_XY_Tube_t; -#endif // _CUSTOM31_XY_TUBE -#if defined(_CUSTOM31_XZ_TUBE) -float _Custom31_XZ_Tube_t; -#endif // _CUSTOM31_XZ_TUBE -#if defined(_CUSTOM31_YZ_TUBE) -float _Custom31_YZ_Tube_t; -#endif // _CUSTOM31_YZ_TUBE +#if defined(_VERTEX_DEFORMATION_XY_TUBE) +float _Vertex_Deformation_XY_Tube_t; +#endif // _VERTEX_DEFORMATION_XY_TUBE +#if defined(_VERTEX_DEFORMATION_XZ_TUBE) +float _Vertex_Deformation_XZ_Tube_t; +#endif // _VERTEX_DEFORMATION_XZ_TUBE +#if defined(_VERTEX_DEFORMATION_YZ_TUBE) +float _Vertex_Deformation_YZ_Tube_t; +#endif // _VERTEX_DEFORMATION_YZ_TUBE + +#if defined(_VERTEX_DEFORMATION_SEAL) +float _Vertex_Deformation_Seal_A; +float _Vertex_Deformation_Seal_k; +float _Vertex_Deformation_Seal_t; +#endif // _VERTEX_DEFORMATION_SEAL #if defined(_UV_SCROLL) float2 _UV_Scroll_Speed; diff --git a/interpolators.cginc b/interpolators.cginc index f9f389c..842861a 100644 --- a/interpolators.cginc +++ b/interpolators.cginc @@ -25,7 +25,7 @@ struct v2f { float3 normal : TEXCOORD4; float4 tangent : TEXCOORD5; UNITY_LIGHTING_COORDS(6,7) -#if defined(_CUSTOM31_FRAGMENT_NORMALS) || defined(_CUSTOM31_TESSELLATION) +#if defined(_VERTEX_DEFORMATION_FRAGMENT_NORMALS) || defined(_VERTEX_DEFORMATION_TESSELLATION) float3 objPos_orig : TEXCOORD8; #endif diff --git a/vertex.cginc b/vertex.cginc index 58c5209..730adfe 100644 --- a/vertex.cginc +++ b/vertex.cginc @@ -1,51 +1,67 @@ #ifndef __VERTEX_INC #define __VERTEX_INC -#include "custom31.hlsl" +#include "vertex_deformation.hlsl" void deform(inout float3 objPos) { float t_eps = 1e-9; -#if defined(_CUSTOM31_XZ_TUBE) +#if defined(_VERTEX_DEFORMATION_XZ_TUBE) { - float t = clamp(_Custom31_XZ_Tube_t, -1+t_eps, 1-t_eps);; + float t = clamp(_Vertex_Deformation_XZ_Tube_t, -1+t_eps, 1-t_eps);; objPos = plane_to_tube(objPos.xyz, t); } -#endif // _CUSTOM31_XZ_TUBE -#if defined(_CUSTOM31_YZ_TUBE) +#endif // _VERTEX_DEFORMATION_XZ_TUBE +#if defined(_VERTEX_DEFORMATION_YZ_TUBE) { - float t = clamp(_Custom31_YZ_Tube_t, -1+t_eps, 1-t_eps); + float t = clamp(_Vertex_Deformation_YZ_Tube_t, -1+t_eps, 1-t_eps); objPos = plane_to_tube(objPos.yxz, t); objPos = objPos.yxz; } -#endif // _CUSTOM31_YZ_TUBE -#if defined(_CUSTOM31_XY_TUBE) +#endif // _VERTEX_DEFORMATION_YZ_TUBE +#if defined(_VERTEX_DEFORMATION_XY_TUBE) { - float t = clamp(_Custom31_XY_Tube_t, -1+t_eps, 1-t_eps); + float t = clamp(_Vertex_Deformation_XY_Tube_t, -1+t_eps, 1-t_eps); objPos = plane_to_tube(objPos.xzy, t); objPos = objPos.xzy; } -#endif // _CUSTOM31_XY_TUBE +#endif // _VERTEX_DEFORMATION_XY_TUBE +#if defined(_VERTEX_DEFORMATION_SEAL) + { + float A = _Vertex_Deformation_Seal_A; + float k = _Vertex_Deformation_Seal_k; + float t = _Time[3] * _Vertex_Deformation_Seal_t; + objPos = seal(objPos.xyz, A, k, t); + } +#endif // _VERTEX_DEFORMATION_SEAL } void deform_normal(float3 objPos, inout float3 objNorm, inout float3 objTan) { -#if defined(_CUSTOM31_XZ_TUBE) +#if defined(_VERTEX_DEFORMATION_XZ_TUBE) { - float t = _Custom31_XZ_Tube_t; + float t = _Vertex_Deformation_XZ_Tube_t; plane_to_tube_normal(objPos, objNorm, objTan, t); } -#endif // _CUSTOM31_XZ_TUBE -#if defined(_CUSTOM31_YZ_TUBE) +#endif // _VERTEX_DEFORMATION_XZ_TUBE +#if defined(_VERTEX_DEFORMATION_YZ_TUBE) { - float t = _Custom31_YZ_Tube_t; + float t = _Vertex_Deformation_YZ_Tube_t; plane_to_tube_normal(objPos.yxz, objNorm.yxz, objTan.yxz, t); } -#endif // _CUSTOM31_YZ_TUBE -#if defined(_CUSTOM31_XY_TUBE) +#endif // _VERTEX_DEFORMATION_YZ_TUBE +#if defined(_VERTEX_DEFORMATION_XY_TUBE) { - float t = _Custom31_XY_Tube_t; + float t = _Vertex_Deformation_XY_Tube_t; plane_to_tube_normal(objPos.xzy, objNorm.xzy, objTan.xzy, t); } -#endif // _CUSTOM31_XY_TUBE +#endif // _VERTEX_DEFORMATION_XY_TUBE +#if defined(_VERTEX_DEFORMATION_SEAL) + { + float A = _Vertex_Deformation_Seal_A; + float k = _Vertex_Deformation_Seal_k; + float t = _Time[0] * _Vertex_Deformation_Seal_t; + seal_normal(objPos, objNorm, objTan, A, k, t); + } +#endif // _VERTEX_DEFORMATION_SEAL } void propagateObjPos(inout v2f i) { diff --git a/vertex_deformation.slang b/vertex_deformation.slang new file mode 100644 index 0000000..63ce1a4 --- /dev/null +++ b/vertex_deformation.slang @@ -0,0 +1,116 @@ +#ifndef __CUSTOM31_INC +#define __CUSTOM31_INC + +#define PI 3.14159265f +#define PI_RCP 0.31830988f + +// Differentiable versions of common operators. +#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 dp_x = diffPair(xyz, float3(1, 0, 0)); \ + DifferentialPair dp_y = diffPair(xyz, float3(0, 1, 0)); \ + DifferentialPair dp_z = diffPair(xyz, float3(0, 0, 1)) + +#define R3R3_AUTODIFF_BASIS_VECTORS(fun, ...) \ + DifferentialPair dp_x_out = fwd_diff(fun)(dp_x, __VA_ARGS__); \ + DifferentialPair dp_y_out = fwd_diff(fun)(dp_y, __VA_ARGS__); \ + DifferentialPair 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 = mul(itjac, normal) * sign(jac_det); \ + tangent = 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-9) { + return float3x3( + 1,0,0, + 0,1,0, + 0,0,1); + } + + float invDet = 1.0f / det; + float3x3 inv; + + inv._11 = (m._22 * m._33 - m._23 * m._32) * invDet; + inv._12 = (m._13 * m._32 - m._12 * m._33) * invDet; + inv._13 = (m._12 * m._23 - m._13 * m._22) * invDet; + inv._21 = (m._23 * m._31 - m._21 * m._33) * invDet; + inv._22 = (m._11 * m._33 - m._13 * m._31) * invDet; + inv._23 = (m._13 * m._21 - m._11 * m._23) * invDet; + inv._31 = (m._21 * m._32 - m._22 * m._31) * invDet; + inv._32 = (m._31 * m._12 - m._11 * m._32) * invDet; + inv._33 = (m._11 * m._22 - m._12 * m._21) * invDet; + + return inv; +} + +// 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 = ((1.0f - z0) / (t * t + 1e-3)) * sign(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); +} + +[Differentiable] +public float3 seal(float3 xyz, no_diff float A, no_diff float k, no_diff float t) { + float x = xyz.x; + float y = xyz.y; + float z = xyz.z; + + float x0 = x + sin(y * k) * 0.1; + float y0 = y + sin(x * k * 2) * 0.5 + cos(z); + float z0 = (z + sin(x * y * k * PI + t) * A) * (1.0 + sin(y * k) * sin(x * k)); + + x0 += z0 * 0.1 * sin(z0 * PI + 1.5); + y0 += z0 * 0.1 * sin(z0 * PI + 1.5); + + x0 -= 0.0; + y0 -= 1.2; + + return float3( + x0, y0, z0 + ); +} + +// Deform a normal vector using the inverse transpose of the jacobian. +public void seal_normal(float3 xyz, inout float3 normal, + inout float3 tangent, float A, float k, float t) { + R3R3_NORMALS(normal, tangent, seal, A, k, t); +} + +#endif // __CUSTOM31_INC + -- cgit v1.2.3