diff options
| author | yum <yum.food.vr@gmail.com> | 2024-07-26 15:14:29 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2024-07-26 15:14:29 -0700 |
| commit | aa932e9df0691f1de27fb44e06e8d786400c3d2a (patch) | |
| tree | b7193b584ab4341354965ab3489ffa3f8a1a88aa | |
| parent | 50699410bf33f143531eae080e1e0e068da504cd (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.cs | 34 | ||||
| -rw-r--r-- | feature_macros.cginc | 1 | ||||
| -rw-r--r-- | globals.cginc | 8 | ||||
| -rw-r--r-- | tooner.shader | 6 | ||||
| -rw-r--r-- | tooner_lighting.cginc | 49 |
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) |
