summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Editor/tooner.cs65
-rw-r--r--feature_macros.cginc2
-rw-r--r--filament_math.cginc4
-rw-r--r--gerstner.cginc133
-rw-r--r--globals.cginc19
-rw-r--r--math.cginc3
-rw-r--r--tooner.shader19
-rw-r--r--tooner_lighting.cginc17
-rw-r--r--tooner_outline_pass.cginc12
-rw-r--r--trochoid_math.cginc4
10 files changed, 266 insertions, 12 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs
index 7007f30..62d0032 100644
--- a/Editor/tooner.cs
+++ b/Editor/tooner.cs
@@ -1130,7 +1130,7 @@ public class ToonerGUI : ShaderGUI {
RangeProperty(
bc,
"Outline width");
- SetKeyword("_OUTLINES", bc.floatValue > 1E-6);
+ SetKeyword("_OUTLINES", bc.floatValue > 1E-9);
if (bc.floatValue > 1E-6) {
bc = FindProperty("_Outline_Color");
@@ -2115,6 +2115,68 @@ public class ToonerGUI : ShaderGUI {
EditorGUI.indentLevel -= 1;
}
+ void DoGimmickGerstnerWater() {
+ MaterialProperty bc;
+
+ bc = FindProperty("_Gimmick_Gerstner_Water_Enable_Static");
+ bool enabled = (bc.floatValue != 0.0);
+ EditorGUI.BeginChangeCheck();
+ enabled = Toggle("Water (gerstner)", enabled);
+ EditorGUI.EndChangeCheck();
+ bc.floatValue = enabled ? 1.0f : 0.0f;
+ SetKeyword("_GIMMICK_GERSTNER_WATER", enabled);
+
+ if (!enabled) {
+ return;
+ }
+ EditorGUI.indentLevel += 1;
+
+ bc = FindProperty("_Gimmick_Gerstner_Water_M");
+ FloatProperty(bc, "M");
+ int num_octaves = (int) Math.Floor((bc.floatValue-1)/4);
+ SetKeyword("_GIMMICK_GERSTNER_WATER_OCTAVE_1", num_octaves >= 1);
+
+ {
+ LabelField("Octave 0", EditorStyles.boldLabel);
+ EditorGUI.indentLevel += 1;
+ bc = FindProperty("_Gimmick_Gerstner_Water_a");
+ VectorProperty(bc, "a");
+ bc = FindProperty("_Gimmick_Gerstner_Water_p");
+ VectorProperty(bc, "p");
+ bc = FindProperty("_Gimmick_Gerstner_Water_k_x");
+ VectorProperty(bc, "k_x");
+ bc = FindProperty("_Gimmick_Gerstner_Water_k_y");
+ VectorProperty(bc, "k_y");
+ bc = FindProperty("_Gimmick_Gerstner_Water_t_f");
+ VectorProperty(bc, "Time speed");
+ EditorGUI.indentLevel -= 1;
+ }
+ if (num_octaves > 0) {
+ LabelField("Octave 1", EditorStyles.boldLabel);
+ EditorGUI.indentLevel += 1;
+ bc = FindProperty("_Gimmick_Gerstner_Water_a1");
+ VectorProperty(bc, "a");
+ bc = FindProperty("_Gimmick_Gerstner_Water_p1");
+ VectorProperty(bc, "p");
+ bc = FindProperty("_Gimmick_Gerstner_Water_k_x1");
+ VectorProperty(bc, "k_x");
+ bc = FindProperty("_Gimmick_Gerstner_Water_k_y1");
+ VectorProperty(bc, "k_y");
+ bc = FindProperty("_Gimmick_Gerstner_Water_t_f1");
+ VectorProperty(bc, "Time speed");
+ EditorGUI.indentLevel -= 1;
+ }
+
+ bc = FindProperty("_Gimmick_Gerstner_Water_h");
+ FloatProperty(bc, "h");
+ bc = FindProperty("_Gimmick_Gerstner_Water_g");
+ FloatProperty(bc, "g");
+ bc = FindProperty("_Gimmick_Gerstner_Water_Scale");
+ VectorProperty(bc, "Scale");
+
+ EditorGUI.indentLevel -= 1;
+ }
+
void DoGimmicks() {
show_ui.Add(AddCollapsibleMenu("Gimmicks", "_Gimmicks"));
EditorGUI.indentLevel += 1;
@@ -2136,6 +2198,7 @@ public class ToonerGUI : ShaderGUI {
DoGimmickAudiolinkChroma00();
DoGimmickFog0();
DoGimmickAurora();
+ DoGimmickGerstnerWater();
DoClones();
DoExplosion();
DoGeoScroll();
diff --git a/feature_macros.cginc b/feature_macros.cginc
index df65e71..7c826aa 100644
--- a/feature_macros.cginc
+++ b/feature_macros.cginc
@@ -172,6 +172,8 @@
#pragma shader_feature_local _ _GIMMICK_FOG_00_EMITTER_2
#pragma shader_feature_local _ _UNITY_FOG
#pragma shader_feature_local _ _GIMMICK_AURORA
+#pragma shader_feature_local _ _GIMMICK_GERSTNER_WATER
+#pragma shader_feature_local _ _GIMMICK_GERSTNER_WATER_OCTAVE_1
#endif // __FEATURE_MACROS_INC
diff --git a/filament_math.cginc b/filament_math.cginc
index 5d088ee..e9dcb70 100644
--- a/filament_math.cginc
+++ b/filament_math.cginc
@@ -1,8 +1,8 @@
+#include "math.cginc"
+
#ifndef __FILAMENT_MATH_INC
#define __FILAMENT_MATH_INC
-#define PI 3.1415926535897932384626433832795028841971
-
// THIS SOURCE CODE HAS BEEN MODIFIED!
// The only modifications are for compatibility with HLSL, for example:
// * Replacing normalizeMediump() with normalize()
diff --git a/gerstner.cginc b/gerstner.cginc
new file mode 100644
index 0000000..da7d2f5
--- /dev/null
+++ b/gerstner.cginc
@@ -0,0 +1,133 @@
+#include "pema99.cginc"
+
+#ifndef __GERSTNER_INC
+#define __GERSTNER_INC
+
+#if defined(_GIMMICK_GERSTNER_WATER)
+
+struct GerstnerParams {
+ // # of components considered
+ uint M;
+ // amplitudes
+ float4 a;
+ // phases
+ float4 p;
+ // wavenumbers
+ float4 k_x;
+ float4 k_y;
+ // time factor
+ float4 t_f;
+#if defined(_GIMMICK_GERSTNER_WATER_OCTAVE_1)
+ float4 a1;
+ float4 p1;
+ float4 k_x1;
+ float4 k_y1;
+ float4 t_f1;
+#endif
+ // mean water depth
+ float h;
+ // gravity
+ float g;
+ float3 scale;
+};
+
+GerstnerParams getGerstnerParams() {
+ GerstnerParams p;
+ p.M = _Gimmick_Gerstner_Water_M;
+ p.a = _Gimmick_Gerstner_Water_a;
+ p.p = _Gimmick_Gerstner_Water_p;
+ // Dumb artistic shit
+ float k_x_time_distortion = _SinTime[2] * .0002;
+ p.k_x = _Gimmick_Gerstner_Water_k_x + k_x_time_distortion;
+ p.k_y = _Gimmick_Gerstner_Water_k_y;
+ p.h = _Gimmick_Gerstner_Water_h;
+ p.g = _Gimmick_Gerstner_Water_g;
+ p.scale = _Gimmick_Gerstner_Water_Scale;
+ p.t_f = _Gimmick_Gerstner_Water_t_f;
+#if defined(_GIMMICK_GERSTNER_WATER_OCTAVE_1)
+ p.a1 = _Gimmick_Gerstner_Water_a1;
+ p.p1 = _Gimmick_Gerstner_Water_p1;
+ p.k_x1 = _Gimmick_Gerstner_Water_k_x1;
+ p.k_x1 += k_x_time_distortion;
+ p.k_y1 = _Gimmick_Gerstner_Water_k_y1;
+ p.t_f1 = _Gimmick_Gerstner_Water_t_f1;
+#endif
+ return p;
+}
+
+float3 compute_gerstner(float3 pp, GerstnerParams p)
+{
+ const float g_alpha = pp.x * p.scale.x;
+ const float g_beta = pp.y * p.scale.y;
+ float g_xi = g_alpha;
+ float g_eta = g_beta;
+ float g_zeta = 0;
+
+ for (uint i = 0; i < p.M; i++) {
+ uint i_mod_4 = glsl_mod(i, 4);
+ switch (floor(i/4)) {
+ case 0:
+ {
+ const float g_t = _Time[1] * p.t_f[i];
+ // wavenumber
+ const float g_k = length(float2(p.k_x[i], p.k_y[i]));
+ // angular frequency
+ const float g_w = sqrt(p.g * g_k * tanh(g_k * p.h));
+ // angular frequency
+ const float g_theta = p.k_x[i] * g_alpha + p.k_y[i] * g_beta - g_w * g_t - p.p[i];
+
+ g_xi -= (p.k_x[i] / g_k) * (p.a[i] / tanh(g_k * p.h)) * sin(g_theta);
+ g_eta -= (p.k_y[i] / g_k) * (p.a[i] / tanh(g_k * p.h)) * sin(g_theta);
+ g_zeta += p.a[i] * cos(g_theta);
+ break;
+ }
+#if defined(_GIMMICK_GERSTNER_WATER_OCTAVE_1)
+ case 1:
+ {
+ const float g_t = _Time[1] * p.t_f1[i_mod_4];
+ // wavenumber
+ const float g_k = length(float2(p.k_x1[i_mod_4], p.k_y1[i_mod_4]));
+ // angular frequency
+ const float g_w = sqrt(p.g * g_k * tanh(g_k * p.h));
+ const float g_theta = p.k_x1[i_mod_4] * g_alpha + p.k_y1[i_mod_4] * g_beta - g_w * g_t - p.p1[i_mod_4];
+
+ g_xi -= (p.k_x1[i_mod_4] / g_k) * (p.a1[i_mod_4] / tanh(g_k * p.h)) * sin(g_theta);
+ g_eta -= (p.k_y1[i_mod_4] / g_k) * (p.a1[i_mod_4] / tanh(g_k * p.h)) * sin(g_theta);
+ g_zeta += p.a1[i_mod_4] * cos(g_theta);
+ break;
+ }
+#endif
+ }
+
+ }
+
+ const float3 raw_result = float3(g_xi / p.scale.x, g_eta / p.scale.y, g_zeta * p.scale.z);
+ const float origin_damping_factor = 1 - pow(0.5, max(0, length(raw_result)*5000-2));
+
+ float3 result = raw_result;
+ result.z *= origin_damping_factor;
+ return result;
+}
+
+float3 gerstner_vert(float3 pp, GerstnerParams p)
+{
+ return compute_gerstner(pp, p);
+}
+
+float3 gerstner_frag(float3 pp, GerstnerParams p)
+{
+ const float3 g0 = compute_gerstner(pp, p);
+ const float3 e = float3(.001, 0, 0);
+ const float3 g0_da = compute_gerstner(pp + e.xyz, p);
+ const float3 g0_db = compute_gerstner(pp + e.yxz, p);
+ const float3 ds_da = g0_da - g0;
+ const float3 ds_db = g0_db - g0;
+
+ const float3 n = normalize(cross(
+ ds_da, ds_db));
+ return n;
+}
+
+#endif // _GIMMICK_GERSTNER_WATER
+#endif // __GERSTNER_INC
+
diff --git a/globals.cginc b/globals.cginc
index 7c76853..044d9fe 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -742,5 +742,24 @@ float _Gimmick_Fog_00_Emitter2_Scale_Y;
#endif
#endif
+#if defined(_GIMMICK_GERSTNER_WATER)
+float _Gimmick_Gerstner_Water_M;
+float _Gimmick_Gerstner_Water_h;
+float _Gimmick_Gerstner_Water_g;
+float3 _Gimmick_Gerstner_Water_Scale;
+float4 _Gimmick_Gerstner_Water_a;
+float4 _Gimmick_Gerstner_Water_p;
+float4 _Gimmick_Gerstner_Water_k_x;
+float4 _Gimmick_Gerstner_Water_k_y;
+float4 _Gimmick_Gerstner_Water_t_f;
+#if defined(_GIMMICK_GERSTNER_WATER_OCTAVE_1)
+float4 _Gimmick_Gerstner_Water_a1;
+float4 _Gimmick_Gerstner_Water_p1;
+float4 _Gimmick_Gerstner_Water_k_x1;
+float4 _Gimmick_Gerstner_Water_k_y1;
+float4 _Gimmick_Gerstner_Water_t_f1;
+#endif
+#endif
+
#endif
diff --git a/math.cginc b/math.cginc
index 968f888..bfbe653 100644
--- a/math.cginc
+++ b/math.cginc
@@ -3,6 +3,9 @@
#ifndef __MATH_INC
#define __MATH_INC
+#define PI 3.14159265
+#define TAU PI * 2.0
+
// Hacky parameterizable whiteout blending. Probably some big mistakes but it
// passes the eyeball test.
// At w=0.5, this looks kinda like whiteout blending.
diff --git a/tooner.shader b/tooner.shader
index a7ccba6..bb9a65a 100644
--- a/tooner.shader
+++ b/tooner.shader
@@ -654,6 +654,25 @@ Shader "yum_food/tooner"
_Gimmick_Fog_00_Emitter2_Scale_Y("fog", Float) = 1
_Gimmick_Aurora_Enable_Static("Enable aurora", Float) = 0
+
+ _Gimmick_Gerstner_Water_Enable_Static("Enable water (gerstner)", Float) = 0
+ _Gimmick_Gerstner_Water_M("# of components considered", Float) = 4
+
+ _Gimmick_Gerstner_Water_a("Amplitudes", Vector) = (.001, .0005, .00025, .000125)
+ _Gimmick_Gerstner_Water_p("Phases", Vector) = (0, 0, 0, 0)
+ _Gimmick_Gerstner_Water_k_x("Wavenumbers (x)", Vector) = (1, 1, 1, 1)
+ _Gimmick_Gerstner_Water_k_y("Wavenumbers (y)", Vector) = (1, 1, 1, 1)
+ _Gimmick_Gerstner_Water_t_f("Time factor", Vector) = (1, 1, 1, 1)
+
+ _Gimmick_Gerstner_Water_a1("Amplitudes", Vector) = (0, 0, 0, 0)
+ _Gimmick_Gerstner_Water_p1("Phases", Vector) = (0, 0, 0, 0)
+ _Gimmick_Gerstner_Water_k_x1("Wavenumbers (x)", Vector) = (1, 1, 1, 1)
+ _Gimmick_Gerstner_Water_k_y1("Wavenumbers (y)", Vector) = (1, 1, 1, 1)
+ _Gimmick_Gerstner_Water_t_f1("Time factor", Vector) = (1, 1, 1, 1)
+
+ _Gimmick_Gerstner_Water_h("Mean water depth", Float) = 10
+ _Gimmick_Gerstner_Water_g("Gravity", Float) = 9.8
+ _Gimmick_Gerstner_Water_Scale("Scale", Vector) = (1000, 1000, .1)
}
SubShader
{
diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc
index 63cd69d..5d055c0 100644
--- a/tooner_lighting.cginc
+++ b/tooner_lighting.cginc
@@ -9,6 +9,7 @@
#include "disinfo.cginc"
#include "eyes.cginc"
#include "fog.cginc"
+#include "gerstner.cginc"
#include "globals.cginc"
#include "halos.cginc"
#include "interpolators.cginc"
@@ -91,8 +92,6 @@ v2f vert(appdata v)
#if defined(_TROCHOID)
{
-#define PI 3.14159265
-#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);
@@ -159,6 +158,12 @@ v2f vert(appdata v)
v.vertex.xyz = p;
}
#endif
+#if defined(_GIMMICK_GERSTNER_WATER)
+ {
+ GerstnerParams p = getGerstnerParams();
+ v.vertex.xyz = gerstner_vert(v.vertex.xyz, p);
+ }
+#endif
o.pos = UnityObjectToClipPos(v.vertex);
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
@@ -1291,6 +1296,12 @@ float4 effect(inout v2f i, out float depth)
i.objPos.xyz = trochoid_map(theta, r0, z);
}
#endif
+#if defined(_GIMMICK_GERSTNER_WATER)
+ {
+ GerstnerParams p = getGerstnerParams();
+ i.normal = UnityObjectToWorldNormal(gerstner_frag(i.objPos.xyz, p));
+ }
+#endif
#if defined(_UVSCROLL)
float2 orig_uv = i.uv0;
@@ -1684,8 +1695,6 @@ float4 effect(inout v2f i, out float depth)
#if defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1) || defined(_RIM_LIGHTING2) || defined(_RIM_LIGHTING3)
{
-#define PI 3.14159265
-
#if defined(_RIM_LIGHTING0)
{
float3 rl_view_dir = VIEW_DIR(_Rim_Lighting0_Center_Eye_Fix);
diff --git a/tooner_outline_pass.cginc b/tooner_outline_pass.cginc
index 9c10999..93ba73c 100644
--- a/tooner_outline_pass.cginc
+++ b/tooner_outline_pass.cginc
@@ -5,6 +5,7 @@
#include "audiolink.cginc"
#include "clones.cginc"
#include "cnlohr.cginc"
+#include "gerstner.cginc"
#include "globals.cginc"
#include "interpolators.cginc"
#include "math.cginc"
@@ -35,7 +36,6 @@ v2f vert(appdata v)
#if defined(_TROCHOID)
{
-#define PI 3.14159265
#define TAU PI * 2.0
float theta = v.uv0.x * TAU;
float r0 = length(v.vertex.xyz);
@@ -50,9 +50,17 @@ v2f vert(appdata v)
float4 objPos = v.vertex;
+#if !defined(_SCROLL) && defined(_GIMMICK_GERSTNER_WATER)
+ {
+ GerstnerParams p = getGerstnerParams();
+ objPos.xyz = gerstner_vert(objPos.xyz, p);
+ v.normal = gerstner_frag(objPos.xyz, p);
+ }
+#endif
+
#if defined(_OUTLINES)
float outline_mask = _Outline_Mask.SampleLevel(linear_repeat_s, v.uv0.xy, /*lod=*/0);
- outline_mask = _Outline_Mask_Invert > 1E-6 ? 1 - outline_mask : outline_mask;
+ outline_mask = _Outline_Mask_Invert > 1E-9 ? 1 - outline_mask : outline_mask;
objPos.xyz += v.normal * _Outline_Width * outline_mask * _Outline_Width_Multiplier;
#endif
diff --git a/trochoid_math.cginc b/trochoid_math.cginc
index 334b14e..7a4e7e2 100644
--- a/trochoid_math.cginc
+++ b/trochoid_math.cginc
@@ -1,13 +1,11 @@
#include "globals.cginc"
+#include "math.cginc"
#ifndef __TROCHOID_MATH
#define __TROCHOID_MATH
#if defined(_TROCHOID)
-#define PI 3.14159265
-#define TAU PI * 2.0
-
float3 trochoid_map(float theta, float r0, float3 vert_z)
{
r0 *= r0;