summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2024-09-29 17:54:36 -0700
committeryum <yum.food.vr@gmail.com>2024-09-29 17:54:36 -0700
commit6e34fcb7d82a7c7480768a2eadaaa5b77400ed09 (patch)
tree40db2c22d08bb1ee4d229aa8076a0399bfcbf9b2
parent2e6a2df16dc5fa9758de06240e44b781b05e6f5a (diff)
Add new eye gimmick
-rw-r--r--Editor/tooner.cs72
-rw-r--r--eyes.cginc141
-rw-r--r--feature_macros.cginc1
-rw-r--r--globals.cginc19
-rw-r--r--math.cginc74
-rw-r--r--tooner.shader20
-rw-r--r--tooner_lighting.cginc17
7 files changed, 343 insertions, 1 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs
index 869d912..fb0cc7c 100644
--- a/Editor/tooner.cs
+++ b/Editor/tooner.cs
@@ -525,6 +525,9 @@ public class ToonerGUI : ShaderGUI {
bc = FindProperty("_Global_Emission_Factor");
editor.FloatProperty(bc, "Global emissions multiplier");
+ bc = FindProperty("_Global_Emission_Additive_Factor");
+ editor.FloatProperty(bc, "Global emissions additive factor");
+
EditorGUI.indentLevel -= 1;
}
@@ -1454,6 +1457,7 @@ public class ToonerGUI : ShaderGUI {
EditorGUI.indentLevel -= 1;
}
+
void DoGimmickEyes00() {
MaterialProperty bc;
bc = FindProperty("_Gimmick_Eyes00_Enable_Static");
@@ -1500,6 +1504,73 @@ public class ToonerGUI : ShaderGUI {
EditorGUI.indentLevel -= 1;
}
+ void DoGimmickEyes02() {
+ MaterialProperty bc;
+ bc = FindProperty("_Gimmick_Eyes02_Enable_Static");
+ bool enabled = (bc.floatValue != 0.0);
+ EditorGUI.BeginChangeCheck();
+ enabled = EditorGUILayout.Toggle("Eyes 02", enabled);
+ EditorGUI.EndChangeCheck();
+ bc.floatValue = enabled ? 1.0f : 0.0f;
+ SetKeyword("_GIMMICK_EYES_02", enabled);
+
+ if (!enabled) {
+ return;
+ }
+
+ EditorGUI.indentLevel += 1;
+
+ bc = FindProperty("_Gimmick_Eyes02_N");
+ editor.RangeProperty(bc, "n");
+ bc = FindProperty("_Gimmick_Eyes02_A0");
+ editor.RangeProperty(bc, "a0");
+ bc = FindProperty("_Gimmick_Eyes02_A1");
+ editor.RangeProperty(bc, "a1");
+ bc = FindProperty("_Gimmick_Eyes02_A2");
+ editor.RangeProperty(bc, "a2");
+ bc = FindProperty("_Gimmick_Eyes02_A3");
+ editor.RangeProperty(bc, "a3");
+ bc = FindProperty("_Gimmick_Eyes02_A4");
+ editor.RangeProperty(bc, "a4");
+
+ bc = FindProperty("_Gimmick_Eyes02_Animate");
+ enabled = (bc.floatValue != 0.0);
+ EditorGUI.BeginChangeCheck();
+ enabled = EditorGUILayout.Toggle("Animate", enabled);
+ EditorGUI.EndChangeCheck();
+ bc.floatValue = enabled ? 1.0f : 0.0f;
+ if (enabled) {
+ EditorGUI.indentLevel += 1;
+ bc = FindProperty("_Gimmick_Eyes02_Animate_Speed");
+ editor.FloatProperty(bc, "Speed");
+
+ bc = FindProperty("_Gimmick_Eyes02_Animate_Strength");
+ editor.FloatProperty(bc, "Strength");
+ EditorGUI.indentLevel -= 1;
+ }
+
+ bc = FindProperty("_Gimmick_Eyes02_UV_X_Symmetry");
+ enabled = (bc.floatValue != 0.0);
+ EditorGUI.BeginChangeCheck();
+ enabled = EditorGUILayout.Toggle("UV x symmetry", enabled);
+ EditorGUI.EndChangeCheck();
+ bc.floatValue = enabled ? 1.0f : 0.0f;
+
+ bc = FindProperty("_Gimmick_Eyes02_UV_Adjust");
+ editor.VectorProperty(bc, "UV scale & offset");
+
+ bc = FindProperty("_Gimmick_Eyes02_Albedo");
+ editor.ColorProperty(bc, "Albedo");
+ bc = FindProperty("_Gimmick_Eyes02_Metallic");
+ editor.FloatProperty(bc, "Metallic");
+ bc = FindProperty("_Gimmick_Eyes02_Roughness");
+ editor.FloatProperty(bc, "Roughness");
+ bc = FindProperty("_Gimmick_Eyes02_Emission");
+ editor.ColorProperty(bc, "Emission");
+
+ EditorGUI.indentLevel -= 1;
+ }
+
void DoGimmickHalo00() {
MaterialProperty bc;
bc = FindProperty("_Gimmick_Halo00_Enable_Static");
@@ -1803,6 +1874,7 @@ public class ToonerGUI : ShaderGUI {
DoGimmickSpherizeLocation();
DoGimmickEyes00();
DoGimmickEyes01();
+ DoGimmickEyes02();
DoGimmickHalo00();
DoGimmickPixellate();
DoGimmickTrochoid();
diff --git a/eyes.cginc b/eyes.cginc
index f993400..514f2d7 100644
--- a/eyes.cginc
+++ b/eyes.cginc
@@ -1,6 +1,7 @@
#include "globals.cginc"
#include "interpolators.cginc"
#include "iq_sdf.cginc"
+#include "math.cginc"
#ifndef __EYES_INC
#define __EYES_INC
@@ -185,5 +186,145 @@ Eyes01PBR eyes01_march(v2f i)
#endif // _GIMMICK_EYES_01
+#if defined(_GIMMICK_EYES_02)
+
+struct chaos_data
+{
+ uint n; // degrees of symmetry
+ int p;
+ float a0;
+ float a1;
+ float a2;
+ float a3;
+ float a4;
+ complex z;
+};
+
+void iterate0(inout struct chaos_data d)
+{
+ complex z_conj = cconjugate(d.z);
+ complex z_conj_n_1 = cpow(z_conj, d.n);
+ complex z_n = cpow(d.z, d.n);
+
+ complex next =
+ cmul((
+ complex(d.a0, 0) +
+ d.a1 * cmul(d.z, cconjugate(d.z)) +
+ complex(d.a2 * creal(z_n), 0) +
+ complex(0, d.a3)
+ ),
+ d.z) +
+ d.a4 * z_conj_n_1;
+
+ d.z = next;
+}
+
+void iterate1(inout struct chaos_data d)
+{
+ complex z_conj = cconjugate(d.z);
+ complex z_conj_n_1 = cpow(z_conj, d.n - 1);
+ complex z_n = cpow(d.z, d.n);
+
+ complex next =
+ (d.a0 +
+ d.a1 * (d.z.x * d.z.x - d.z.y * d.z.y) +
+ d.a2 * creal(z_n) +
+ d.a3 * creal(cmul(cpow((cdiv(d.z, abs(d.z))), d.n * d.p), abs(d.z)))) *
+ d.z +
+ d.a4 * (z_conj_n_1);
+
+ d.z = next;
+}
+
+// Return a number on (0, inf)
+float get_chaos(in float2 uv, inout chaos_data d)
+{
+ complex z = uv;
+ // Remap onto [-1, 1]
+ float scale = 2.0;
+ z = z * scale * 2 - scale;
+ d.z = z;
+
+ for (int i = 0; i < 6; i++) {
+ iterate0(d);
+ }
+
+ float l = d.z.x * d.z.x - d.z.y * d.z.y;
+ if (l < 1) {
+ float b = .1;
+ return b/l;
+ } else {
+ return 0;
+ }
+}
+
+float3 get_chaos_normal(in float2 uv, inout chaos_data d)
+{
+ float2 small_step = float2(.0001, 0);
+ float dx = get_chaos(uv + small_step.xy, d) - get_chaos(uv, d);
+ float dz = get_chaos(uv + small_step.yx, d) - get_chaos(uv, d);
+ float dy = small_step.x;
+
+ float3 normal = float3(dx, dy, dz);
+ return UnityObjectToWorldNormal(normalize(normal));
+}
+
+bool eyes02_march(float2 uv, inout float3 normal)
+{
+ float2 uv_scale = _Gimmick_Eyes02_UV_Adjust.xy;
+ float2 uv_center = _Gimmick_Eyes02_UV_Adjust.zw;
+ uv -= 0.5;
+
+ if (_Gimmick_Eyes02_UV_X_Symmetry) {
+ uv.x = abs(uv.x);
+ }
+
+ uv -= (uv_center - 0.5);
+ uv /= uv_scale;
+
+ uv += 0.5;
+
+ float t20 = _Time[0] * _Gimmick_Eyes02_Animate_Speed;
+ float t = _Time[1] * _Gimmick_Eyes02_Animate_Speed;
+
+ struct chaos_data d;
+ d.n = _Gimmick_Eyes02_N;
+ d.p = _Gimmick_Eyes02_N;
+ d.a0 = _Gimmick_Eyes02_A0;
+ d.a1 = _Gimmick_Eyes02_A1;
+ d.a2 = _Gimmick_Eyes02_A2;
+ d.a3 = _Gimmick_Eyes02_A3;
+ d.a4 = _Gimmick_Eyes02_A4;
+
+ if (_Gimmick_Eyes02_Animate) {
+ float effect = 1;
+ float e = _Gimmick_Eyes02_Animate_Strength;
+ if (round(effect) == 0) {
+ d.a0 += (sin(t * 1.1) * .01 + sin(t20 * 1.1) * .75) * e;
+ d.a1 += (sin(t * 1.3) * .01 + sin(t20 * 1.3) * .75) * e;
+ d.a2 += (sin(t * 1.7) * .01 + sin(t20 * 1.7) * 1) * e;
+ d.a3 += (sin(t * 1.9) * .01 + sin(t20 * 1.9) * .75) * e;
+ d.a4 += (sin(t * 2.3) * .02 + sin(t20 * 2.3) * .4) * e;
+ } else if (round(effect) == 1) {
+ d.a0 += (sin(t * 1.1) * .01 + sin(t20 * 1.1) * .75) * e;
+ d.a1 += (sin(t * 1.3) * .01 + sin(t20 * 1.3) * .75) * e;
+ d.a2 += (sin(t * 1.7) * .01 + sin(t20 * 1.7) * 1) * e;
+ d.a3 += (sin(t * 1.9) * .0005 + sin(t20 * 1.9) * .05) * e;
+ d.a4 += (sin(t * 2.3) * .02 + sin(t20 * 2.3) * 1) * e;
+ }
+ }
+
+ float c = get_chaos(uv, d);
+ c = exp(-c);
+
+ if (c < 1) {
+ normal = get_chaos_normal(uv, d);
+ }
+ bool is_ray_hit = (c < 1);
+ return is_ray_hit;
+}
+
+#endif // _GIMMICK_EYES_02
+
#endif // __EYES_INC
diff --git a/feature_macros.cginc b/feature_macros.cginc
index 40f2bc3..f53e904 100644
--- a/feature_macros.cginc
+++ b/feature_macros.cginc
@@ -141,6 +141,7 @@
#pragma shader_feature_local _ _GIMMICK_SPHERIZE_LOCATION
#pragma shader_feature_local _ _GIMMICK_EYES_00
#pragma shader_feature_local _ _GIMMICK_EYES_01
+#pragma shader_feature_local _ _GIMMICK_EYES_02
#pragma shader_feature_local _ _GIMMICK_HALO_00
#pragma shader_feature_local _ _PIXELLATE
#pragma shader_feature_local _ _TROCHOID
diff --git a/globals.cginc b/globals.cginc
index 832d2cd..63cf7fd 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -282,6 +282,7 @@ float _Emission1Multiplier;
float _Emission1_UV_Select;
#endif
float _Global_Emission_Factor;
+float _Global_Emission_Additive_Factor;
#if defined(_AMBIENT_OCCLUSION)
texture2D _Ambient_Occlusion;
@@ -597,6 +598,24 @@ texture2D _Gimmick_Eyes00_Effect_Mask;
float _Gimmick_Eyes01_Radius;
#endif
+#if defined(_GIMMICK_EYES_02)
+float _Gimmick_Eyes02_N;
+float _Gimmick_Eyes02_A0;
+float _Gimmick_Eyes02_A1;
+float _Gimmick_Eyes02_A2;
+float _Gimmick_Eyes02_A3;
+float _Gimmick_Eyes02_A4;
+float _Gimmick_Eyes02_Animate;
+float _Gimmick_Eyes02_Animate_Strength;
+float _Gimmick_Eyes02_Animate_Speed;
+float _Gimmick_Eyes02_UV_X_Symmetry;
+float4 _Gimmick_Eyes02_UV_Adjust;
+float4 _Gimmick_Eyes02_Albedo;
+float _Gimmick_Eyes02_Metallic;
+float _Gimmick_Eyes02_Roughness;
+float3 _Gimmick_Eyes02_Emission;
+#endif
+
#if defined(_PIXELLATE)
float _Gimmick_Pixellate_Enable_Static;
float _Gimmick_Pixellate_Resolution_U;
diff --git a/math.cginc b/math.cginc
index fd5dda0..c2903c8 100644
--- a/math.cginc
+++ b/math.cginc
@@ -3,6 +3,80 @@
#ifndef __MATH_INC
#define __MATH_INC
+// Complex numbers
+typedef float2 complex;
+
+float creal(complex z0)
+{
+ return z0.x;
+}
+
+float cimag(complex z0)
+{
+ return z0.y;
+}
+
+float cnorm2(complex z0)
+{
+ return z0.x * z0.x + z0.y * z0.y;
+}
+
+float cnorm(complex z0)
+{
+ return sqrt(cnorm2(z0));
+}
+
+complex cconjugate(complex z)
+{
+ return float2(z.x, -z.y);
+}
+
+complex cmul(complex z0, complex z1)
+{
+ return float2(z0.x * z1.x - z0.y * z1.y, z0.x * z1.y + z0.y * z1.x);
+}
+
+complex cdiv(complex z0, complex z1)
+{
+ float re = creal(z0) * creal(z1) + cimag(z0) * cimag(z1);
+ float im = cimag(z0) * cimag(z1) - creal(z0) * creal(z1);
+ float z1_norm2 = cnorm2(z1);
+ return float2(re, im) / z1_norm2;
+}
+
+// Evaluates z0**n.
+// Uses Euler's identity to support fractional values of `n`.
+// Expensive.
+complex cpow_fractional(complex z0, float n)
+{
+ float r = sqrt(z0.x * z0.x + z0.y * z0.y);
+ float t = atan(z0.y / z0.x);
+ return pow(r, n) * float2(cos(t * n), sin(t * n));
+}
+
+// Evaluates z0**n.
+// Utilizes recursive squaring to support high values of `n`.
+// Cheap.
+complex cpow(complex z0, uint n)
+{
+ if (n == 0) {
+ return 1;
+ }
+
+ complex z = z0;
+ while (n > 1) {
+ if (n % 2 == 0) {
+ z = cmul(z, z);
+ n /= 2;
+ } else {
+ z = cmul(z, z0);
+ n -= 1;
+ }
+ }
+ return z;
+}
+
+// Quaternions
float4 qmul(float4 q1, float4 q2)
{
return float4(
diff --git a/tooner.shader b/tooner.shader
index 335f050..2f1b87e 100644
--- a/tooner.shader
+++ b/tooner.shader
@@ -167,6 +167,7 @@ Shader "yum_food/tooner"
_Emission1Multiplier("Emission multiplier", Range(0, 2)) = 1
_Emission1_UV_Select("UV channel", Range(0,7)) = 0
_Global_Emission_Factor("Global emission factor", Float) = 1
+ _Global_Emission_Additive_Factor("Global emission additive factor", Float) = 0
[NoScaleOffset] _Tex_NormalStr("Normal texture strength", Range(0, 10)) = 1
@@ -485,6 +486,23 @@ Shader "yum_food/tooner"
_Gimmick_Eyes01_Enable_Static("Enable eyes 01", Float) = 0.0
_Gimmick_Eyes01_Radius("Radius (meters, obj space)", Float) = 1.0
+ _Gimmick_Eyes02_Enable_Static ("Enable (static)", Float) = 0
+ _Gimmick_Eyes02_N ("n", Range(2, 16)) = 5
+ _Gimmick_Eyes02_A0 ("a0", Range(-6, 6)) = 1.5
+ _Gimmick_Eyes02_A1 ("a1", Range(-6, 6)) = -1.75
+ _Gimmick_Eyes02_A2 ("a2", Range(-6, 6)) = .01
+ _Gimmick_Eyes02_A3 ("a3", Range(-2, 2)) = 0
+ _Gimmick_Eyes02_A4 ("a4", Range(-2, 2)) = .5
+ _Gimmick_Eyes02_Animate ("animate", Float) = 0.0
+ _Gimmick_Eyes02_Animate_Strength ("animation strength", Float) = 1.0
+ _Gimmick_Eyes02_Animate_Speed ("animation speed", Float) = 1.0
+ _Gimmick_Eyes02_UV_X_Symmetry ("UV x symmetry", Float) = 1.0
+ _Gimmick_Eyes02_UV_Adjust ("UV scale and center", Vector) = (0.9, 1.1, .753, .675)
+ _Gimmick_Eyes02_Albedo ("Albedo", Color) = (1, 1, 1, 1)
+ _Gimmick_Eyes02_Metallic ("Metallic", Range(0, 1)) = 0
+ _Gimmick_Eyes02_Roughness ("Roughness", Range(0, 1)) = 0.5
+ _Gimmick_Eyes02_Emission ("Emission", Color) = (0, 0, 0, 1)
+
_Gimmick_Halo00_Enable_Static("Enable halo", Float) = 0.0
_Gimmick_Pixellate_Enable_Static("Enable pixellation", Float) = 0.0
@@ -622,6 +640,7 @@ Shader "yum_food/tooner"
#include "tooner_lighting.cginc"
ENDCG
}
+ /*
Pass {
Tags {
"RenderType"="Opaque"
@@ -701,6 +720,7 @@ Shader "yum_food/tooner"
#include "mochie_shadow_caster.cginc"
ENDCG
}
+ */
}
CustomEditor "ToonerGUI"
}
diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc
index eec82af..c91598d 100644
--- a/tooner_lighting.cginc
+++ b/tooner_lighting.cginc
@@ -1430,6 +1430,18 @@ float4 effect(inout v2f i)
}
#endif
+
+#if defined(_GIMMICK_EYES_02)
+ float3 eyes02_normal = i.normal;
+ bool eyes02_hit = eyes02_march(i.uv0, eyes02_normal);
+ {
+ albedo.rgb += eyes02_hit * _Gimmick_Eyes02_Albedo.rgb;
+ normal = lerp(normal, eyes02_normal, eyes02_hit);
+ roughness = lerp(roughness, _Gimmick_Eyes02_Roughness, eyes02_hit);
+ metallic = lerp(metallic, _Gimmick_Eyes02_Metallic, eyes02_hit);
+ }
+#endif
+
#if defined(_MATCAP0) || defined(_MATCAP1) || defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1) || defined(_RIM_LIGHTING2) || defined(_RIM_LIGHTING3)
float3 matcap_emission = 0;
float2 matcap_uv;
@@ -2151,7 +2163,9 @@ float4 effect(inout v2f i)
#endif
albedo.a = 1;
#endif
- return float4(lit.rgb + _Gimmick_Flat_Color_Emission * _Global_Emission_Factor, albedo.a);
+ return float4(lit.rgb +
+ _Gimmick_Flat_Color_Emission * _Global_Emission_Factor,
+ albedo.a);
}
#endif
@@ -2207,6 +2221,7 @@ float4 effect(inout v2f i)
result.rgb *= result.a;
#endif
result.rgb += getOverlayEmission(ov, i) * _Global_Emission_Factor;
+ result.rgb += _Global_Emission_Additive_Factor * albedo.rgb;
return result;
}