summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2024-07-26 15:14:29 -0700
committeryum <yum.food.vr@gmail.com>2024-07-26 15:14:29 -0700
commitaa932e9df0691f1de27fb44e06e8d786400c3d2a (patch)
treeb7193b584ab4341354965ab3489ffa3f8a1a88aa
parent50699410bf33f143531eae080e1e0e068da504cd (diff)
Add facing quad gimmick
Gimmick makes the quad face the camera, pivoting around the world-space Y axis and the local coordinate system origin.
-rw-r--r--Editor/tooner.cs34
-rw-r--r--feature_macros.cginc1
-rw-r--r--globals.cginc8
-rw-r--r--tooner.shader6
-rw-r--r--tooner_lighting.cginc49
5 files changed, 93 insertions, 5 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs
index 7442ca5..189cfd0 100644
--- a/Editor/tooner.cs
+++ b/Editor/tooner.cs
@@ -1075,6 +1075,39 @@ public class ToonerGUI : ShaderGUI {
EditorGUI.indentLevel -= 1;
}
+ void DoGimmickFaceMeWorldY() {
+ MaterialProperty bc;
+ bc = FindProperty("_FaceMeWorldY_Enable_Static");
+ bool enabled = (bc.floatValue != 0.0);
+ EditorGUI.BeginChangeCheck();
+ enabled = EditorGUILayout.Toggle("FaceMeWorldY", enabled);
+ EditorGUI.EndChangeCheck();
+ bc.floatValue = enabled ? 1.0f : 0.0f;
+ SetKeyword("_FACE_ME_WORLD_Y", enabled);
+
+ if (!enabled) {
+ return;
+ }
+
+ EditorGUI.indentLevel += 1;
+
+ bc = FindProperty("_FaceMeWorldY_Enable_Dynamic");
+ enabled = (bc.floatValue != 0.0);
+ EditorGUI.BeginChangeCheck();
+ enabled = EditorGUILayout.Toggle("Enable (runtime switch)", enabled);
+ EditorGUI.EndChangeCheck();
+ bc.floatValue = enabled ? 1.0f : 0.0f;
+
+ bc = FindProperty("_FaceMeWorldY_Enable_X");
+ editor.FloatProperty(bc, "X");
+ bc = FindProperty("_FaceMeWorldY_Enable_Y");
+ editor.FloatProperty(bc, "Y");
+ bc = FindProperty("_FaceMeWorldY_Enable_Z");
+ editor.FloatProperty(bc, "Z");
+
+ EditorGUI.indentLevel -= 1;
+ }
+
void DoGimmicks() {
DoGimmickFlatColor();
@@ -1084,6 +1117,7 @@ public class ToonerGUI : ShaderGUI {
DoGimmickEyes00();
DoGimmickPixellate();
DoGimmickTrochoid();
+ DoGimmickFaceMeWorldY();
}
void DoMochieParams() {
diff --git a/feature_macros.cginc b/feature_macros.cginc
index af22501..ef53155 100644
--- a/feature_macros.cginc
+++ b/feature_macros.cginc
@@ -94,6 +94,7 @@
#pragma shader_feature_local _ _GIMMICK_EYES_00
#pragma shader_feature_local _ _PIXELLATE
#pragma shader_feature_local _ _TROCHOID
+#pragma shader_feature_local _ _FACE_ME_WORLD_Y
#pragma shader_feature_local _ _CLEARCOAT
#endif // __FEATURE_MACROS_INC
diff --git a/globals.cginc b/globals.cginc
index 607e98b..6e6a01f 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -390,5 +390,13 @@ float _Trochoid_r;
float _Trochoid_d;
#endif
+#if defined(_FACE_ME_WORLD_Y)
+float _FaceMeWorldY_Enable_Static;
+float _FaceMeWorldY_Enable_Dynamic;
+float _FaceMeWorldY_Enable_X;
+float _FaceMeWorldY_Enable_Y;
+float _FaceMeWorldY_Enable_Z;
+#endif
+
#endif
diff --git a/tooner.shader b/tooner.shader
index 926c3b4..c4280f7 100644
--- a/tooner.shader
+++ b/tooner.shader
@@ -291,6 +291,12 @@ Shader "yum_food/tooner"
_Trochoid_r("r", Float) = 3.0
_Trochoid_d("d", Float) = 5.0
+ _FaceMeWorldY_Enable_Static("Enable face me gimmick", Float) = 0.0
+ _FaceMeWorldY_Enable_Dynamic("Enable face me gimmick", Float) = 0.0
+ _FaceMeWorldY_Enable_X("x", Float) = 0
+ _FaceMeWorldY_Enable_Y("x", Float) = 1
+ _FaceMeWorldY_Enable_Z("x", Float) = 0
+
_Enable_SSR("Enable SSR", Float) = 0
_SSRStrength("SSR Strength", Float) = 1
_SSRHeight("SSR Height", Float) = 0.1
diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc
index f34f97b..cdc6e34 100644
--- a/tooner_lighting.cginc
+++ b/tooner_lighting.cginc
@@ -100,12 +100,45 @@ v2f vert(appdata v)
#define TAU PI * 2.0
float theta = v.uv0.x * TAU;
float r0 = length(v.vertex.xyz);
+ v.vertex.xyz = trochoid_map(theta, r0, v.vertex.z);
+ }
+#endif
+#if defined(_FACE_ME_WORLD_Y)
+ if (_FaceMeWorldY_Enable_Dynamic) {
+ // Undo object coordinate system rotation.
+ float3x3 rotation = float3x3(
+ normalize(unity_ObjectToWorld._m00_m10_m20),
+ normalize(unity_ObjectToWorld._m01_m11_m21),
+ normalize(unity_ObjectToWorld._m02_m12_m22));
+ rotation = transpose(rotation);
+ float3 unrotated = mul(transpose(rotation),
+ v.vertex.xyz);
+ float4 pos = mul(unity_ObjectToWorld,
+ float4(unrotated, v.vertex.w));
+ float3 unrotated_n = mul(transpose(rotation),
+ v.normal);
+ float3 n = UnityObjectToWorldNormal(unrotated_n);
+
+ float3 origin = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
+ float3 view_dir = _WorldSpaceCameraPos - origin;
+ // Project onto xz plane
+ n.y = 0;
+ view_dir.y = 0;
+ // Normalize
+ n = normalize(n);
+ view_dir = normalize(view_dir);
+ // Calculate angles and rotate
+ float ct = dot(view_dir, n);
+ float3 n_cross_v = cross(view_dir, n);
+ float st = length(n_cross_v);
+ st *= sign(n_cross_v.y);
+ float2x2 rot = float2x2(
+ ct, -st,
+ st, ct);
+ pos.xz = mul(rot, pos.xz - origin.xz) + origin.xz;
- float x = v.vertex.x;
- float y = v.vertex.y;
- float z = v.vertex.z;
-
- v.vertex.xyz = trochoid_map(theta, r0, z);
+ v.vertex = mul(unity_WorldToObject, pos);
+ o.normal = view_dir;
}
#endif
@@ -140,7 +173,13 @@ v2f vert(appdata v)
o.screenPos = ComputeGrabScreenPos(o.pos);
#endif
+#if defined(_FACE_ME_WORLD_Y)
+ if (!_FaceMeWorldY_Enable_Dynamic) {
+ o.normal = UnityObjectToWorldNormal(v.normal);
+ }
+#else
o.normal = UnityObjectToWorldNormal(v.normal);
+#endif
o.tangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
o.uv = v.uv0;
#if defined(LIGHTMAP_ON)