summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2024-10-24 18:45:29 -0700
committeryum <yum.food.vr@gmail.com>2024-10-24 18:45:29 -0700
commit1705cd25f5bcd796a560bcce22ef91d190a94900 (patch)
tree122c80d25228e2e7c83fa720982576535223ebab
parent09aa66c9c13965105133ca000da4d2c37d455877 (diff)
add water stuff
-rw-r--r--Editor/tooner.cs21
-rw-r--r--clones.cginc4
-rw-r--r--feature_macros.cginc1
-rw-r--r--gerstner.cginc88
-rw-r--r--globals.cginc9
-rw-r--r--math.cginc5
-rw-r--r--mochie_shadow_caster.cginc8
-rw-r--r--pbr.cginc2
-rw-r--r--tooner.shader5
-rw-r--r--tooner_lighting.cginc27
-rw-r--r--tooner_outline_pass.cginc5
11 files changed, 144 insertions, 31 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs
index 2a6d805..bd98d37 100644
--- a/Editor/tooner.cs
+++ b/Editor/tooner.cs
@@ -2136,6 +2136,27 @@ public class ToonerGUI : ShaderGUI {
int num_octaves = (int) Math.Floor((bc.floatValue-1)/4);
SetKeyword("_GIMMICK_GERSTNER_WATER_OCTAVE_1", num_octaves >= 1);
+ bc = FindProperty("_Gimmick_Gerstner_Water_Color_Ramp");
+ TexturePropertySingleLine(
+ MakeLabel(bc, "Color ramp"),
+ bc);
+ SetKeyword("_GIMMICK_GERSTNER_WATER_COLOR_RAMP", bc.textureValue);
+
+ if (bc.textureValue) {
+ EditorGUI.indentLevel += 1;
+
+ bc = FindProperty("_Gimmick_Gerstner_Water_Color_Ramp_Offset");
+ FloatProperty(bc, "Offset");
+ bc = FindProperty("_Gimmick_Gerstner_Water_Color_Ramp_Scale");
+ FloatProperty(bc, "Scale");
+ bc = FindProperty("_Gimmick_Gerstner_Water_Color_Ramp_Mask");
+ VectorProperty(bc, "Mask (octave 0)");
+ bc = FindProperty("_Gimmick_Gerstner_Water_Color_Ramp_Mask1");
+ VectorProperty(bc, "Mask (octave 1)");
+
+ EditorGUI.indentLevel -= 1;
+ }
+
{
LabelField("Octave 0", EditorStyles.boldLabel);
EditorGUI.indentLevel += 1;
diff --git a/clones.cginc b/clones.cginc
index 00612f3..9b43b80 100644
--- a/clones.cginc
+++ b/clones.cginc
@@ -12,10 +12,12 @@ void add_clones(in v2f clone_verts[3], inout TriangleStream<v2f> tri_out)
return;
}
+#if 0
float factor = _Tess_Factor;
if (_Clones_Dist_Cutoff > 0 && length(_WorldSpaceCameraPos - clone_verts[0].worldPos) > _Clones_Dist_Cutoff) {
factor = 1;
}
+#endif
uint n_clones = (uint) round(_Clones_Count);
for (uint i = 0; i < (uint) n_clones; i++) {
@@ -26,7 +28,7 @@ void add_clones(in v2f clone_verts[3], inout TriangleStream<v2f> tri_out)
offset = ((offset % 2) * 2 - 1) * (((offset) / 2) + 1) * _Clones_dx;
objPos.x += offset;
ii.worldPos = mul(unity_ObjectToWorld, float4(objPos, 1)).xyz;
- ii.clipPos = UnityObjectToClipPos(objPos);
+ ii.pos = UnityObjectToClipPos(objPos);
tri_out.Append(ii);
}
tri_out.RestartStrip();
diff --git a/feature_macros.cginc b/feature_macros.cginc
index 7c826aa..1cb3233 100644
--- a/feature_macros.cginc
+++ b/feature_macros.cginc
@@ -174,6 +174,7 @@
#pragma shader_feature_local _ _GIMMICK_AURORA
#pragma shader_feature_local _ _GIMMICK_GERSTNER_WATER
#pragma shader_feature_local _ _GIMMICK_GERSTNER_WATER_OCTAVE_1
+#pragma shader_feature_local _ _GIMMICK_GERSTNER_WATER_COLOR_RAMP
#endif // __FEATURE_MACROS_INC
diff --git a/gerstner.cginc b/gerstner.cginc
index e6ed3c2..47843a7 100644
--- a/gerstner.cginc
+++ b/gerstner.cginc
@@ -1,3 +1,5 @@
+#include "globals.cginc"
+#include "math.cginc"
#include "pema99.cginc"
#ifndef __GERSTNER_INC
@@ -17,12 +19,18 @@ struct GerstnerParams {
float4 k_y;
// time factor
float4 t_f;
+#if defined(_GIMMICK_GERSTNER_WATER_COLOR_RAMP)
+ float4 ramp_mask;
+#endif
#if defined(_GIMMICK_GERSTNER_WATER_OCTAVE_1)
float4 a1;
float4 p1;
float4 k_x1;
float4 k_y1;
float4 t_f1;
+#if defined(_GIMMICK_GERSTNER_WATER_COLOR_RAMP)
+ float4 ramp_mask1;
+#endif
#endif
// mean water depth
float h;
@@ -31,6 +39,14 @@ struct GerstnerParams {
float3 scale;
};
+struct GerstnerFragResult {
+ float4 tangent;
+ float3 normal;
+#if defined(_GIMMICK_GERSTNER_WATER_COLOR_RAMP)
+ float3 color;
+#endif
+};
+
GerstnerParams getGerstnerParams() {
GerstnerParams p;
p.M = _Gimmick_Gerstner_Water_M;
@@ -44,6 +60,9 @@ GerstnerParams getGerstnerParams() {
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_COLOR_RAMP)
+ p.ramp_mask = _Gimmick_Gerstner_Water_Color_Ramp_Mask;
+#endif
#if defined(_GIMMICK_GERSTNER_WATER_OCTAVE_1)
p.a1 = _Gimmick_Gerstner_Water_a1;
p.p1 = _Gimmick_Gerstner_Water_p1;
@@ -51,17 +70,26 @@ GerstnerParams getGerstnerParams() {
p.k_x1 += k_x_time_distortion;
p.k_y1 = _Gimmick_Gerstner_Water_k_y1;
p.t_f1 = _Gimmick_Gerstner_Water_t_f1;
+#if defined(_GIMMICK_GERSTNER_WATER_COLOR_RAMP)
+ p.ramp_mask1 = _Gimmick_Gerstner_Water_Color_Ramp_Mask1;
+#endif
#endif
return p;
}
-float3 compute_gerstner(float3 pp, GerstnerParams p)
+struct GerstnerInternalResult {
+ float3 world_pos;
+ float color_ramp_pos;
+};
+
+GerstnerInternalResult 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;
+ float g_zeta_color_ramp = 0;
for (uint i = 0; i < p.M; i++) {
uint i_mod_4 = glsl_mod(i, 4);
@@ -79,6 +107,9 @@ float3 compute_gerstner(float3 pp, GerstnerParams p)
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);
+#if defined(_GIMMICK_GERSTNER_WATER_COLOR_RAMP)
+ g_zeta_color_ramp += p.a[i] * cos(g_theta) * p.ramp_mask[i];
+#endif
break;
}
#if defined(_GIMMICK_GERSTNER_WATER_OCTAVE_1)
@@ -94,51 +125,72 @@ float3 compute_gerstner(float3 pp, GerstnerParams p)
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);
+#if defined(_GIMMICK_GERSTNER_WATER_COLOR_RAMP)
+ g_zeta_color_ramp += p.a1[i_mod_4] * cos(g_theta) * p.ramp_mask1[i_mod_4];
+#endif
break;
}
#endif
}
-
}
const float3 raw_result = float3(g_xi / p.scale.x, g_eta / p.scale.y, g_zeta * p.scale.z);
+ g_zeta_color_ramp *= p.scale.z;
const float3 raw_result_world = mul(unity_ObjectToWorld, float4(raw_result, 1)).xyz;
float3 result_world = raw_result_world;
if (_Gimmick_Gerstner_Water_Origin_Damping_Direction > 0) {
- result_world.y = max(_Gimmick_Gerstner_Water_Origin_Damping_Direction, result_world.y);
+ result_world.y = dmax(_Gimmick_Gerstner_Water_Origin_Damping_Direction, result_world.y, 1);
} else {
- result_world.y = min(_Gimmick_Gerstner_Water_Origin_Damping_Direction, result_world.y);
+ result_world.y = dmin(_Gimmick_Gerstner_Water_Origin_Damping_Direction, result_world.y, 1);
}
- result_world.y = lerp(result_world.y, raw_result_world.y,
- // If within 20m cylindrical distance, apply 100m wide damping.
+ float3 result_obj = mul(unity_WorldToObject, float4(result_world, 1)).xyz;
+
+ result_obj = lerp(result_obj, raw_result,
+ // If within 3m cylindrical distance, apply 100m wide damping.
// TODO parameterize this!
- saturate((length(raw_result_world.xz) - 20) * 0.01) *
+ dsaturate((length(raw_result_world.xz) - 20), 1) *
// Only enable if mesh is on the wrong side of the damping vector.
- (sign(raw_result_world.y - _Gimmick_Gerstner_Water_Origin_Damping_Direction) != sign(_Gimmick_Gerstner_Water_Origin_Damping_Direction)));
+ // TODO make this differentiable. As is, there's a visible seam.
+ dsaturate(-(raw_result_world.y - _Gimmick_Gerstner_Water_Origin_Damping_Direction) * sign(_Gimmick_Gerstner_Water_Origin_Damping_Direction), 1));
- float3 result = mul(unity_WorldToObject, float4(result_world, 1)).xyz;
- return result;
+ GerstnerInternalResult r;
+ r.world_pos = result_obj;
+ r.color_ramp_pos = g_zeta_color_ramp;
+ return r;
}
float3 gerstner_vert(float3 pp, GerstnerParams p)
{
- return compute_gerstner(pp, p);
+ return compute_gerstner(pp, p).world_pos;
}
-float3 gerstner_frag(float3 pp, GerstnerParams p)
+GerstnerFragResult gerstner_frag(float3 pp, GerstnerParams p)
{
- const float3 g0 = compute_gerstner(pp, p);
- const float3 e = float3(1E-8, 0, 0);
- const float3 g0_da = compute_gerstner(pp + e.xyz, p);
- const float3 g0_db = compute_gerstner(pp + e.yxz, p);
+ const GerstnerInternalResult r0 = compute_gerstner(pp, p);
+ const float3 g0 = r0.world_pos;
+ const float3 e = float3(1E-7, 0, 0);
+ const float3 g0_da = compute_gerstner(pp + e.xyz, p).world_pos;
+ const float3 g0_db = compute_gerstner(pp + e.yxz, p).world_pos;
const float3 ds_da = g0_da - g0;
const float3 ds_db = g0_db - g0;
- const float3 n = normalize(cross(
+ GerstnerFragResult r;
+ r.normal = normalize(cross(
ds_da, ds_db));
- return n;
+ r.tangent = float4(normalize(ds_da), 1);
+
+#if defined(_GIMMICK_GERSTNER_WATER_COLOR_RAMP)
+ float ramp_phase = r0.color_ramp_pos;
+ ramp_phase *= _Gimmick_Gerstner_Water_Color_Ramp_Scale;
+ ramp_phase += _Gimmick_Gerstner_Water_Color_Ramp_Offset;
+ float3 ramp_color = _Gimmick_Gerstner_Water_Color_Ramp.Sample(linear_clamp_s, float2(ramp_phase, 0.5));
+
+ r.color = ramp_color;
+#endif
+
+ return r;
}
#endif // _GIMMICK_GERSTNER_WATER
diff --git a/globals.cginc b/globals.cginc
index 6800b7b..3a9616b 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -753,6 +753,9 @@ float4 _Gimmick_Gerstner_Water_k_x;
float4 _Gimmick_Gerstner_Water_k_y;
float4 _Gimmick_Gerstner_Water_t_f;
float _Gimmick_Gerstner_Water_Origin_Damping_Direction;
+texture2D _Gimmick_Gerstner_Water_Color_Ramp;
+float _Gimmick_Gerstner_Water_Color_Ramp_Offset;
+float _Gimmick_Gerstner_Water_Color_Ramp_Scale;
#if defined(_GIMMICK_GERSTNER_WATER_OCTAVE_1)
float4 _Gimmick_Gerstner_Water_a1;
float4 _Gimmick_Gerstner_Water_p1;
@@ -760,6 +763,12 @@ float4 _Gimmick_Gerstner_Water_k_x1;
float4 _Gimmick_Gerstner_Water_k_y1;
float4 _Gimmick_Gerstner_Water_t_f1;
#endif
+#if defined(_GIMMICK_GERSTNER_WATER_COLOR_RAMP)
+float4 _Gimmick_Gerstner_Water_Color_Ramp_Mask;
+#if defined(_GIMMICK_GERSTNER_WATER_OCTAVE_1)
+float4 _Gimmick_Gerstner_Water_Color_Ramp_Mask1;
+#endif
+#endif
#endif
#endif
diff --git a/math.cginc b/math.cginc
index bfbe653..8aaa5ea 100644
--- a/math.cginc
+++ b/math.cginc
@@ -125,6 +125,11 @@ float dabs(float a, float k)
return log2(exp2(k * a) + exp2(-1.0 * k * a));
}
+float dsaturate(float x, float k)
+{
+ return dmin(dmax(x, 0, k), 1, k);
+}
+
float rand(uint seed) {
seed = seed * 747796405 + 2891336453;
uint result = ((seed >> ((seed >> 28) + 4)) ^ seed) * 277803737;
diff --git a/mochie_shadow_caster.cginc b/mochie_shadow_caster.cginc
index 9e8ee1e..028cc31 100644
--- a/mochie_shadow_caster.cginc
+++ b/mochie_shadow_caster.cginc
@@ -1,3 +1,5 @@
+#include "gerstner.cginc"
+
#ifndef __MOCHIE_SHADOW_CASTER_INC
#define __MOCHIE_SHADOW_CASTER_INC
@@ -55,6 +57,12 @@ v2f vert (appdata v){
return (v2f) (0.0 / 0.0);
}
#endif
+#if !defined(_SCROLL) && defined(_GIMMICK_GERSTNER_WATER)
+ {
+ GerstnerParams p = getGerstnerParams();
+ v.vertex.xyz = gerstner_vert(v.vertex.xyz, p);
+ }
+#endif
v2f o = (v2f)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
diff --git a/pbr.cginc b/pbr.cginc
index d575093..002c387 100644
--- a/pbr.cginc
+++ b/pbr.cginc
@@ -346,7 +346,7 @@ float4 getLitColor(
screenPos = float4(i.screenPos, 0, i.pos.w);
#endif
-#if 1
+#if 0
float reflection_strength = _ReflectionStrength;
#if defined(_REFLECTION_STRENGTH_TEX)
reflection_strength *= _ReflectionStrengthTex.SampleLevel(linear_repeat_s, i.uv0, 0);
diff --git a/tooner.shader b/tooner.shader
index f6beeee..55ec40c 100644
--- a/tooner.shader
+++ b/tooner.shader
@@ -663,17 +663,22 @@ Shader "yum_food/tooner"
_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_Color_Ramp_Mask("Color ramp mask", 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_Color_Ramp_Mask1("Color ramp mask", 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)
_Gimmick_Gerstner_Water_Origin_Damping_Direction("Origin damping direction", Float) = 1
+ _Gimmick_Gerstner_Water_Color_Ramp("Color ramp", 2D) = "white"
+ _Gimmick_Gerstner_Water_Color_Ramp_Offset("Color ramp offset", Float) = 0.5
+ _Gimmick_Gerstner_Water_Color_Ramp_Scale("Color ramp offset", Float) = 1
}
SubShader
{
diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc
index 87cf2e4..bcad86a 100644
--- a/tooner_lighting.cginc
+++ b/tooner_lighting.cginc
@@ -219,7 +219,7 @@ v2f vert(appdata v)
// maxvertexcount == the number of vertices we create
#if defined(_CLONES)
-[maxvertexcount(45)]
+[maxvertexcount(15)]
#else
[maxvertexcount(3)]
#endif
@@ -1296,15 +1296,6 @@ float4 effect(inout v2f i, out float depth)
i.objPos.xyz = trochoid_map(theta, r0, z);
}
#endif
-#if defined(_GIMMICK_GERSTNER_WATER)
-#if defined(_EXPLODE)
- if (_Explode_Phase < 1E-6)
-#endif
- {
- GerstnerParams p = getGerstnerParams();
- i.normal = UnityObjectToWorldNormal(gerstner_frag(i.objPos.xyz, p));
- }
-#endif
#if defined(_UVSCROLL)
float2 orig_uv = i.uv0;
@@ -1319,6 +1310,22 @@ float4 effect(inout v2f i, out float depth)
float4 albedo = _Color;
#endif // _BASECOLOR_MAP
+#if defined(_GIMMICK_GERSTNER_WATER)
+#if defined(_EXPLODE)
+ if (_Explode_Phase < 1E-6)
+#endif
+ {
+ GerstnerParams p = getGerstnerParams();
+ GerstnerFragResult r = gerstner_frag(i.objPos.xyz, p);
+ i.normal = UnityObjectToWorldNormal(r.normal);
+ i.tangent = float4(UnityObjectToWorldDir(r.tangent.xyz), r.tangent.w);
+#if defined(_GIMMICK_GERSTNER_WATER_COLOR_RAMP)
+ albedo.xyz *= r.color;
+ albedo.w = 1;
+#endif
+ }
+#endif
+
#if defined(_UVSCROLL)
if (uv_scroll_mask) {
float uv_scroll_alpha = _UVScroll_Alpha.SampleBias(linear_repeat_s, orig_uv, _Global_Sample_Bias);
diff --git a/tooner_outline_pass.cginc b/tooner_outline_pass.cginc
index 93ba73c..46a03f0 100644
--- a/tooner_outline_pass.cginc
+++ b/tooner_outline_pass.cginc
@@ -50,13 +50,16 @@ v2f vert(appdata v)
float4 objPos = v.vertex;
+#if defined(_OUTLINES)
#if !defined(_SCROLL) && defined(_GIMMICK_GERSTNER_WATER)
{
GerstnerParams p = getGerstnerParams();
objPos.xyz = gerstner_vert(objPos.xyz, p);
- v.normal = gerstner_frag(objPos.xyz, p);
+ GerstnerFragResult r = gerstner_frag(objPos.xyz, p);
+ v.normal = r.normal;
}
#endif
+#endif
#if defined(_OUTLINES)
float outline_mask = _Outline_Mask.SampleLevel(linear_repeat_s, v.uv0.xy, /*lod=*/0);