summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-10-17 20:51:32 -0700
committeryum <yum.food.vr@gmail.com>2025-10-17 20:51:32 -0700
commit98e115ebfc40e72a8ee1c6453735d8f6076f7890 (patch)
tree70910197508a860adc505ef545d8d8825d48b98b
parent5bfbb660c7213cdd14c9bde2349b3a09ccdaff4e (diff)
tessellate in screen space, and add sine wave deformation effect
-rw-r--r--3ner.cginc51
-rw-r--r--3ner.shader11
-rw-r--r--features.cginc4
-rw-r--r--globals.cginc7
-rw-r--r--vertex.cginc31
-rw-r--r--vertex_deformation.slang46
6 files changed, 106 insertions, 44 deletions
diff --git a/3ner.cginc b/3ner.cginc
index 4aa4184..08bb7cd 100644
--- a/3ner.cginc
+++ b/3ner.cginc
@@ -79,27 +79,31 @@ tess_factors patch_constant(InputPatch<v2f, 3> patch) {
#if defined(_TESSELLATION)
float edgeLength = _Tessellation_Factor;
- float3 p0_world = mul(unity_ObjectToWorld, float4(patch[0].objPos, 1));
- float3 p1_world = mul(unity_ObjectToWorld, float4(patch[1].objPos, 1));
- float3 p2_world = mul(unity_ObjectToWorld, float4(patch[2].objPos, 1));
-
- float3 v0 = p0_world - _WorldSpaceCameraPos;
- float3 v1 = p1_world - _WorldSpaceCameraPos;
- float3 v2 = p2_world - _WorldSpaceCameraPos;
-
- // Angular size drops with inverse distance
- float s0 = rsqrt(dot(v0, v0));
- float s1 = rsqrt(dot(v1, v1));
- float s2 = rsqrt(dot(v2, v2));
-
- float s01 = (s0 + s1) * 0.5f;
- float s12 = (s1 + s2) * 0.5f;
- float s20 = (s2 + s0) * 0.5f;
-
+ // Transform object-space positions to clip space
+ float4 p0_clip = UnityObjectToClipPos(float4(patch[0].objPos, 1));
+ float4 p1_clip = UnityObjectToClipPos(float4(patch[1].objPos, 1));
+ float4 p2_clip = UnityObjectToClipPos(float4(patch[2].objPos, 1));
+
+ // Convert to normalized device coordinates (NDC)
+ float3 p0_ndc = p0_clip.xyz / p0_clip.w;
+ float3 p1_ndc = p1_clip.xyz / p1_clip.w;
+ float3 p2_ndc = p2_clip.xyz / p2_clip.w;
+
+ // Convert to screen space (scale by screen dimensions)
+ float2 p0_screen = p0_ndc.xy * _ScreenParams.xy * 0.5f;
+ float2 p1_screen = p1_ndc.xy * _ScreenParams.xy * 0.5f;
+ float2 p2_screen = p2_ndc.xy * _ScreenParams.xy * 0.5f;
+
+ // Calculate screen-space edge lengths in pixels
+ float edge01 = length(p1_screen - p0_screen);
+ float edge12 = length(p2_screen - p1_screen);
+ float edge20 = length(p0_screen - p2_screen);
+
+ // Scale tessellation by screen-space edge length and falloff factor
float k = _Tessellation_Falloff_Factor;
- f.edge[2] = min(_Tessellation_Factor, k * _Tessellation_Factor * s01);
- f.edge[0] = min(_Tessellation_Factor, k * _Tessellation_Factor * s12);
- f.edge[1] = min(_Tessellation_Factor, k * _Tessellation_Factor * s20);
+ 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.inside = (f.edge[0] + f.edge[1] + f.edge[2]) * 0.333333f;
@@ -115,7 +119,7 @@ tess_factors patch_constant(InputPatch<v2f, 3> patch) {
f.inside = 1;
#endif
-#if defined(_TESSELLATION) && defined(_TESSELLATION_HEIGHTMAPS)
+#if defined(_TESSELLATION)
{
float4 p0 = patch[0].pos;
float4 p1 = patch[1].pos;
@@ -251,6 +255,11 @@ float4 frag(v2f i, uint facing : SV_IsFrontFace) : SV_Target {
LightData light_data;
GetLighting(i, pbr, light_data);
+
+#if 0
+ float c = light_data.direct.NoL;
+ return float4(c,c,c,1);
+#endif
return brdf(pbr, light_data);
}
diff --git a/3ner.shader b/3ner.shader
index 5fca9e9..396dc86 100644
--- a/3ner.shader
+++ b/3ner.shader
@@ -86,7 +86,6 @@ Shader "yum_food/3ner"
_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_Vertex_Deformation_Tubes("Tubes", Float) = 0
//endex
@@ -99,6 +98,16 @@ Shader "yum_food/3ner"
[HideInInspector] m_end_Vertex_Deformation_Seal("Seal", Float) = 0
//endex
+ //ifex _Vertex_Deformation_Sine_Waves_Enabled==0
+ [HideInInspector] m_start_Vertex_Deformation_Sine_Waves("Sine Waves", Float) = 0
+ [ThryToggle(_VERTEX_DEFORMATION_SINE_WAVES)] _Vertex_Deformation_Sine_Waves_Enabled("Enable", Float) = 0
+ _Vertex_Deformation_Sine_Waves_Amplitude("Amplitude (4 waves)", Vector) = (0.1, 0, 0, 0)
+ _Vertex_Deformation_Sine_Waves_Direction("Direction", Vector) = (1, 0, 0, 0)
+ _Vertex_Deformation_Sine_Waves_k("Spatial frequency k", Vector) = (6.28, 0, 0)
+ _Vertex_Deformation_Sine_Waves_omega("Temporal frequency omega", Vector) = (6.28, 0, 0)
+ [HideInInspector] m_end_Vertex_Deformation_Sine_Waves("Sine Waves", Float) = 0
+ //endex
+
[HideInInspector] m_end_Vertex_Deformation("Vertex Deformation", Float) = 0
//ifex _UV_Scroll_Enabled==0
diff --git a/features.cginc b/features.cginc
index 3788d6d..c76bb9a 100644
--- a/features.cginc
+++ b/features.cginc
@@ -40,6 +40,10 @@
#pragma shader_feature_local _VERTEX_DEFORMATION_SEAL
//endex
+//ifex _Vertex_Deformation_Sine_Waves_Enabled==0
+#pragma shader_feature_local _VERTEX_DEFORMATION_SINE_WAVES
+//endex
+
//ifex _Unlit==0
#pragma shader_feature_local _UNLIT
//endex
diff --git a/globals.cginc b/globals.cginc
index c460285..2a4410f 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -74,6 +74,13 @@ float _Vertex_Deformation_Seal_k;
float _Vertex_Deformation_Seal_t;
#endif // _VERTEX_DEFORMATION_SEAL
+#if defined(_VERTEX_DEFORMATION_SINE_WAVES)
+float4 _Vertex_Deformation_Sine_Waves_Amplitude;
+float3 _Vertex_Deformation_Sine_Waves_Direction;
+float4 _Vertex_Deformation_Sine_Waves_k;
+float4 _Vertex_Deformation_Sine_Waves_omega;
+#endif // _VERTEX_DEFORMATION_SINE_WAVES
+
#if defined(_UV_SCROLL)
float2 _UV_Scroll_Speed;
#endif // _UV_SCROLL
diff --git a/vertex.cginc b/vertex.cginc
index 730adfe..a18215a 100644
--- a/vertex.cginc
+++ b/vertex.cginc
@@ -3,24 +3,25 @@
#include "vertex_deformation.hlsl"
+#define FOO(x) (x)
+
void deform(inout float3 objPos) {
- float t_eps = 1e-9;
#if defined(_VERTEX_DEFORMATION_XZ_TUBE)
{
- float t = clamp(_Vertex_Deformation_XZ_Tube_t, -1+t_eps, 1-t_eps);;
+ float t = _Vertex_Deformation_XZ_Tube_t;
objPos = plane_to_tube(objPos.xyz, t);
}
#endif // _VERTEX_DEFORMATION_XZ_TUBE
#if defined(_VERTEX_DEFORMATION_YZ_TUBE)
{
- float t = clamp(_Vertex_Deformation_YZ_Tube_t, -1+t_eps, 1-t_eps);
+ float t = _Vertex_Deformation_YZ_Tube_t;
objPos = plane_to_tube(objPos.yxz, t);
objPos = objPos.yxz;
}
#endif // _VERTEX_DEFORMATION_YZ_TUBE
#if defined(_VERTEX_DEFORMATION_XY_TUBE)
{
- float t = clamp(_Vertex_Deformation_XY_Tube_t, -1+t_eps, 1-t_eps);
+ float t = _Vertex_Deformation_XY_Tube_t;
objPos = plane_to_tube(objPos.xzy, t);
objPos = objPos.xzy;
}
@@ -33,6 +34,16 @@ void deform(inout float3 objPos) {
objPos = seal(objPos.xyz, A, k, t);
}
#endif // _VERTEX_DEFORMATION_SEAL
+#if defined(_VERTEX_DEFORMATION_SINE_WAVES)
+ {
+ float t = _Time[3];
+ float3 amplitude = _Vertex_Deformation_Sine_Waves_Amplitude;
+ float3 direction = _Vertex_Deformation_Sine_Waves_Direction;
+ float4 k = _Vertex_Deformation_Sine_Waves_k;
+ float4 omega = _Vertex_Deformation_Sine_Waves_omega;
+ objPos = sine_wave(objPos.xyz, amplitude, direction, k, omega, t);
+ }
+#endif // _VERTEX_DEFORMATION_SINE_WAVES
}
void deform_normal(float3 objPos, inout float3 objNorm, inout float3 objTan) {
@@ -58,10 +69,20 @@ void deform_normal(float3 objPos, inout float3 objNorm, inout float3 objTan) {
{
float A = _Vertex_Deformation_Seal_A;
float k = _Vertex_Deformation_Seal_k;
- float t = _Time[0] * _Vertex_Deformation_Seal_t;
+ float t = _Time[3] * _Vertex_Deformation_Seal_t;
seal_normal(objPos, objNorm, objTan, A, k, t);
}
#endif // _VERTEX_DEFORMATION_SEAL
+#if defined(_VERTEX_DEFORMATION_SINE_WAVES)
+ {
+ float t = _Time[3];
+ float4 amplitude = _Vertex_Deformation_Sine_Waves_Amplitude;
+ float3 direction = _Vertex_Deformation_Sine_Waves_Direction;
+ float4 k = _Vertex_Deformation_Sine_Waves_k;
+ float4 omega = _Vertex_Deformation_Sine_Waves_omega;
+ sine_wave_normal(objPos, objNorm, objTan, amplitude, direction, k, omega, t);
+ }
+#endif // _VERTEX_DEFORMATION_SINE_WAVES
}
void propagateObjPos(inout v2f i) {
diff --git a/vertex_deformation.slang b/vertex_deformation.slang
index 63ce1a4..f4d4132 100644
--- a/vertex_deformation.slang
+++ b/vertex_deformation.slang
@@ -3,15 +3,18 @@
#define PI 3.14159265f
#define PI_RCP 0.31830988f
+#define TAU (2.0f * PI)
+
+#define glsl_mod(x,y) (((x)-(y)*floor((x)/(y))))
// Differentiable versions of common operators.
-#define dabs(x) length(float2(x, 1e-6))
+#define dabs(x) sqrt((x) * (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 \
+#define R3R3_DECLARE_BASIS_VECTORS(xyz) \
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))
@@ -33,18 +36,13 @@
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__); \
+#define R3R3_NORMALS(xyz, normal, tangent, fun, ...) \
+ R3R3_DECLARE_BASIS_VECTORS(xyz); \
+ 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);
- }
+ det = max(1e-6 * abs(det), abs(det)) * sign(det);
float invDet = 1.0f / det;
float3x3 inv;
@@ -71,7 +69,7 @@ public float3 plane_to_tube(float3 xyz, no_diff float t) {
float z0 = xyz.z;
float theta = x0 * PI;
- float radius = ((1.0f - z0) / (t * t + 1e-3)) * sign(t);
+ float radius = ((1.0f - z0) / (dabs(t) + 1e-4f)) * sign(t);
float x = sin(theta / radius) * radius * PI_RCP;
// The z0 term here is required to make the jacobian invertible.
@@ -82,7 +80,7 @@ public float3 plane_to_tube(float3 xyz, no_diff float t) {
public void plane_to_tube_normal(float3 xyz, inout float3 normal,
inout float3 tangent, float t) {
- R3R3_NORMALS(normal, tangent, plane_to_tube, t);
+ R3R3_NORMALS(xyz, normal, tangent, plane_to_tube, t);
}
[Differentiable]
@@ -93,7 +91,7 @@ public float3 seal(float3 xyz, no_diff float A, no_diff float k, no_diff float t
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));
+ 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);
@@ -106,11 +104,25 @@ public float3 seal(float3 xyz, no_diff float A, no_diff float k, no_diff float t
);
}
-// 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);
+ R3R3_NORMALS(xyz, normal, tangent, seal, A, k, t);
}
-#endif // __CUSTOM31_INC
+[Differentiable]
+public float3 sine_wave(float3 xyz,
+ no_diff float3 amplitude,
+ no_diff float3 direction,
+ no_diff float3 k,
+ no_diff float3 omega,
+ no_diff float t) {
+ xyz += amplitude * sin(k * dot(xyz, direction) + omega * t);
+ return xyz;
+}
+public void sine_wave_normal(float3 xyz, inout float3 normal, inout float3 tangent,
+ float3 amplitude, float3 direction, float3 k, float3 omega, float t) {
+ R3R3_NORMALS(xyz, normal, tangent, sine_wave, amplitude, direction, k, omega, t);
+}
+
+#endif // __CUSTOM31_INC