summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Editor/tooner.cs10
-rw-r--r--clones.cginc92
-rw-r--r--fog.cginc2
-rw-r--r--gerstner.cginc4
-rw-r--r--globals.cginc3
-rw-r--r--tooner.shader7
-rw-r--r--tooner_lighting.cginc34
-rw-r--r--tooner_outline_pass.cginc31
8 files changed, 134 insertions, 49 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs
index deb2357..116fb4f 100644
--- a/Editor/tooner.cs
+++ b/Editor/tooner.cs
@@ -1136,9 +1136,13 @@ public class ToonerGUI : ShaderGUI {
bc,
"Number of clones");
bc = FindProperty("_Clones_dx");
- RangeProperty(
- bc,
- "x offset");
+ RangeProperty(bc, "x offset");
+ bc = FindProperty("_Clones_dy");
+ RangeProperty(bc, "y offset");
+ bc = FindProperty("_Clones_dz");
+ RangeProperty(bc, "z offset");
+ bc = FindProperty("_Clones_Scale");
+ VectorProperty(bc, "Scale");
}
EditorGUI.indentLevel -= 1;
show_ui.RemoveAt(show_ui.Count - 1);
diff --git a/clones.cginc b/clones.cginc
index 9b43b80..140e7d1 100644
--- a/clones.cginc
+++ b/clones.cginc
@@ -1,14 +1,70 @@
#include "interpolators.cginc"
#include "globals.cginc"
+#include "math.cginc"
#ifndef __CLONES_INC
#define __CLONES_INC
#if defined(_CLONES)
-void add_clones(in v2f clone_verts[3], inout TriangleStream<v2f> tri_out)
+void rotate_triangle(inout v2f tri_in[3], const float pid_rand, const float phase)
{
- if (_Clones_dx < 1E-6) {
+ if (phase < 1E-6) {
+ return;
+ }
+
+ float3 avg_pos = (tri_in[0].worldPos + tri_in[1].worldPos + tri_in[2].worldPos) * .33333333;
+ tri_in[0].worldPos -= avg_pos;
+ tri_in[1].worldPos -= avg_pos;
+ tri_in[2].worldPos -= avg_pos;
+
+ if (phase > 1E-6) {
+ float theta = phase * 3.14159 * 4 + phase * (sin(_Time[1] * (1 + pid_rand) * 0.5 + pid_rand) + cos(_Time[1] * (1 + pid_rand) * .16393442 + pid_rand) * 2) * pid_rand * 2;
+ float3 axis = normalize(float3(
+ rand((int) ((tri_in[0].uv0.x + tri_in[0].uv0.y + pid_rand) * 1E9)) * 2 - 1,
+ rand((int) ((tri_in[1].uv0.x + tri_in[1].uv0.y + pid_rand) * 1E9)) * 2 - 1,
+ rand((int) ((tri_in[2].uv0.x + tri_in[2].uv0.y + pid_rand) * 1E9)) * 2 - 1));
+ float4 quat = get_quaternion(axis, theta);
+ tri_in[0].worldPos = rotate_vector(tri_in[0].worldPos, quat);
+ tri_in[1].worldPos = rotate_vector(tri_in[1].worldPos, quat);
+ tri_in[2].worldPos = rotate_vector(tri_in[2].worldPos, quat);
+ }
+
+ tri_in[0].worldPos *= _Clones_Scale.xyz;
+ tri_in[1].worldPos *= _Clones_Scale.xyz;
+ tri_in[2].worldPos *= _Clones_Scale.xyz;
+
+ tri_in[0].worldPos += avg_pos;
+ tri_in[1].worldPos += avg_pos;
+ tri_in[2].worldPos += avg_pos;
+
+ float3 v0_objPos = mul(unity_WorldToObject, float4(tri_in[0].worldPos, 1));
+ float3 v1_objPos = mul(unity_WorldToObject, float4(tri_in[1].worldPos, 1));
+ float3 v2_objPos = mul(unity_WorldToObject, float4(tri_in[2].worldPos, 1));
+
+ // Perf hack: Normal gets normalized in fragment shader anyway xdd
+ // TODO add a toggle to normalize in fragment or not; and use it to gate this
+ // optimization.
+ float3 n = cross(tri_in[1].worldPos - tri_in[0].worldPos, tri_in[2].worldPos - tri_in[0].worldPos);
+ tri_in[0].normal = n;
+ tri_in[1].normal = n;
+ tri_in[2].normal = n;
+
+ tri_in[0].pos = UnityObjectToClipPos(v0_objPos);
+ tri_in[1].pos = UnityObjectToClipPos(v1_objPos);
+ tri_in[2].pos = UnityObjectToClipPos(v2_objPos);
+
+ tri_in[0].objPos = v0_objPos;
+ tri_in[1].objPos = v1_objPos;
+ tri_in[2].objPos = v2_objPos;
+}
+
+void add_clones(in v2f clone_verts[3], inout TriangleStream<v2f> tri_out,
+ float pid_rand, float explode_phase)
+{
+ if (_Clones_dx < 1E-6 &&
+ _Clones_dy < 1E-6 &&
+ _Clones_dz < 1E-6) {
return;
}
@@ -21,16 +77,32 @@ void add_clones(in v2f clone_verts[3], inout TriangleStream<v2f> tri_out)
uint n_clones = (uint) round(_Clones_Count);
for (uint i = 0; i < (uint) n_clones; i++) {
+ v2f mod_verts[3] = clone_verts;
+ float3 offset = i;
+ offset = ((offset % 2) * 2 - 1) * (((offset) * 0.5) + 1) *
+ float3(_Clones_dx, _Clones_dy, _Clones_dz);
for (uint j = 0; j < 3; j++) {
- v2f ii = clone_verts[j];
- float3 objPos = mul(unity_WorldToObject, float4(ii.worldPos, 1)).xyz;
- float offset = i;
- offset = ((offset % 2) * 2 - 1) * (((offset) / 2) + 1) * _Clones_dx;
- objPos.x += offset;
- ii.worldPos = mul(unity_ObjectToWorld, float4(objPos, 1)).xyz;
- ii.pos = UnityObjectToClipPos(objPos);
- tri_out.Append(ii);
+#if 0
+ float3 objPos = mul(unity_WorldToObject, float4(mod_verts[j].worldPos, 1)).xyz;
+ objPos += offset;
+ mod_verts[j].worldPos = mul(unity_ObjectToWorld, float4(objPos, 1)).xyz;
+#else
+ mod_verts[j].worldPos += offset;
+#endif
}
+#if 1
+ rotate_triangle(mod_verts, rand(pid_rand+i), /*phase=*/1);
+#else
+ mod_verts[0].objPos = mul(unity_WorldToObject, float4(mod_verts[0].worldPos, 1));
+ mod_verts[1].objPos = mul(unity_WorldToObject, float4(mod_verts[1].worldPos, 1));
+ mod_verts[2].objPos = mul(unity_WorldToObject, float4(mod_verts[2].worldPos, 1));
+ mod_verts[0].pos = UnityObjectToClipPos(mod_verts[0].objPos);
+ mod_verts[1].pos = UnityObjectToClipPos(mod_verts[1].objPos);
+ mod_verts[2].pos = UnityObjectToClipPos(mod_verts[2].objPos);
+#endif
+ tri_out.Append(mod_verts[0]);
+ tri_out.Append(mod_verts[1]);
+ tri_out.Append(mod_verts[2]);
tri_out.RestartStrip();
}
}
diff --git a/fog.cginc b/fog.cginc
index 223bedf..ee447db 100644
--- a/fog.cginc
+++ b/fog.cginc
@@ -33,7 +33,7 @@ float perlin_noise_3d_tex(float3 p)
}
float map(float3 p, float lod) {
- float3 t = _Time[1] * .5 * FOG_PERLIN_NOISE_SCALE;
+ float3 t = _Time[1] * _Gimmick_Fog_00_Noise_Scale * FOG_PERLIN_NOISE_SCALE;
#define RADIUS_TRANS_WIDTH 100
#define RADIUS_TRANS_WIDTH_RCP (1.0 / RADIUS_TRANS_WIDTH)
// Try to create a smooth transition without doing any length() or other
diff --git a/gerstner.cginc b/gerstner.cginc
index 47843a7..a5f7db2 100644
--- a/gerstner.cginc
+++ b/gerstner.cginc
@@ -148,9 +148,9 @@ GerstnerInternalResult compute_gerstner(float3 pp, GerstnerParams p)
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.
+ // If within cylindrical distance, apply damping.
// TODO parameterize this!
- dsaturate((length(raw_result_world.xz) - 20), 1) *
+ dsaturate((length(raw_result_world.xz) - 15), 1) *
// Only enable if mesh is on the wrong side of the damping vector.
// 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));
diff --git a/globals.cginc b/globals.cginc
index f1a7fc3..764b9f8 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -562,6 +562,9 @@ float _HSV1_Val_Shift;
float _Clones_Enabled;
float _Clones_Count;
float _Clones_dx;
+float _Clones_dy;
+float _Clones_dz;
+float3 _Clones_Scale;
float _Clones_Dist_Cutoff;
#endif
diff --git a/tooner.shader b/tooner.shader
index db54d6e..39f13ba 100644
--- a/tooner.shader
+++ b/tooner.shader
@@ -450,8 +450,11 @@ Shader "yum_food/tooner"
_Clones_Enabled("Enable clones", Float) = 0.0
_Clones_Count("Clones count", Range(0,16)) = 0.0
- _Clones_Dist_Cutoff("Clones distance cutoff", Float) = -1.0
- _Clones_dx("Clones dx", Range(0, 1)) = 1.0
+ _Clones_Dist_Cutoff("distance cutoff", Float) = -1.0
+ _Clones_dx("dx", Range(0, 10)) = 1.0
+ _Clones_dy("dy", Range(0, 10)) = 1.0
+ _Clones_dz("dz", Range(0, 10)) = 1.0
+ _Clones_Scale("scale", Vector) = (1, 1, 1, 1)
_UVScroll_Enabled("Enable UV scrolling", Float) = 0.0
_UVScroll_Mask("UV scroll mask", 2D) = "white"
diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc
index 1b306ce..6e4e2ac 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(15)]
+[maxvertexcount(21)]
#else
[maxvertexcount(3)]
#endif
@@ -235,6 +235,9 @@ void geom(triangle v2f tri_in[3],
float3 v1_objPos;
float3 v2_objPos;
+ const float pid_rand = rand((int) pid);
+
+ float explode_phase = 0;
#if defined(_EXPLODE)
float3 n = normalize(cross(v1.worldPos - v0.worldPos, v2.worldPos - v0.worldPos));
float3 avg_pos;
@@ -243,22 +246,21 @@ void geom(triangle v2f tri_in[3],
float3 n1 = v1.normal;
float3 n2 = v2.normal;
- float phase = _Explode_Phase;
- phase = smoothstep(0, 1, phase);
- phase *= phase;
- phase *= 4;
- const float pid_rand = rand((int) pid);
+ explode_phase = _Explode_Phase;
+ explode_phase = smoothstep(0, 1, explode_phase);
+ explode_phase *= explode_phase;
+ explode_phase *= 4;
- if (phase > 1E-6) {
+ if (explode_phase > 1E-6) {
float3 axis = normalize(float3(
rand((int) ((v0.uv0.x + v0.uv0.y) * 1E9)) * 2 - 1,
rand((int) ((v1.uv0.x + v1.uv0.y) * 1E9)) * 2 - 1,
rand((int) ((v2.uv0.x + v2.uv0.y) * 1E9)) * 2 - 1));
- float3 np = BlendNormals(n, axis * phase);
+ float3 np = BlendNormals(n, axis * explode_phase);
- v0.worldPos += np * phase * pid_rand;
- v1.worldPos += np * phase * pid_rand;
- v2.worldPos += np * phase * pid_rand;
+ v0.worldPos += np * explode_phase * pid_rand;
+ v1.worldPos += np * explode_phase * pid_rand;
+ v2.worldPos += np * explode_phase * pid_rand;
v0_objPos = mul(unity_WorldToObject, float4(v0.worldPos, 1));
v1_objPos = mul(unity_WorldToObject, float4(v1.worldPos, 1));
@@ -270,16 +272,16 @@ void geom(triangle v2f tri_in[3],
chrono = (AudioLinkDecodeDataAsUInt( ALPASS_CHRONOTENSITY + uint2( 2, 1 ) ) % 1000000) / 1000000.0;
}
#endif
- v0.worldPos += n * phase * sin(_Time[2] + length(v0_objPos)*6 + chrono) * .01 + chrono * n * phase * .2;
- v1.worldPos += n * phase * sin(_Time[2] + length(v1_objPos)*6 + chrono) * .01 + chrono * n * phase * .2;
- v2.worldPos += n * phase * sin(_Time[2] + length(v2_objPos)*6 + chrono) * .01 + chrono * n * phase * .2;
+ v0.worldPos += n * explode_phase * sin(_Time[2] + length(v0_objPos)*6 + chrono) * .01 + chrono * n * explode_phase * .2;
+ v1.worldPos += n * explode_phase * sin(_Time[2] + length(v1_objPos)*6 + chrono) * .01 + chrono * n * explode_phase * .2;
+ v2.worldPos += n * explode_phase * sin(_Time[2] + length(v2_objPos)*6 + chrono) * .01 + chrono * n * explode_phase * .2;
avg_pos = (v0.worldPos + v1.worldPos + v2.worldPos) / 3;
v0.worldPos -= avg_pos;
v1.worldPos -= avg_pos;
v2.worldPos -= avg_pos;
- float theta = phase * 3.14159 * 4 + phase * (sin(_Time[1] * (1 + pid_rand) / 2.0 + pid_rand) + cos(_Time[1] * (1 + pid_rand) / 6.1 + pid_rand) * 2) * pid_rand * 2;
+ float theta = explode_phase * 3.14159 * 4 + explode_phase * (sin(_Time[1] * (1 + pid_rand) / 2.0 + pid_rand) + cos(_Time[1] * (1 + pid_rand) / 6.1 + pid_rand) * 2) * pid_rand * 2;
float4 quat = get_quaternion(axis, theta);
v0.worldPos = rotate_vector(v0.worldPos, quat);
v1.worldPos = rotate_vector(v1.worldPos, quat);
@@ -369,7 +371,7 @@ void geom(triangle v2f tri_in[3],
#endif
#if defined(_CLONES)
v2f clone_verts[3] = {v0, v1, v2};
- add_clones(clone_verts, tri_out);
+ add_clones(clone_verts, tri_out, pid_rand, explode_phase);
#endif // _CLONES
// Output transformed geometry.
diff --git a/tooner_outline_pass.cginc b/tooner_outline_pass.cginc
index 46a03f0..c68c57b 100644
--- a/tooner_outline_pass.cginc
+++ b/tooner_outline_pass.cginc
@@ -127,6 +127,8 @@ void geom(triangle v2f tri_in[3],
float3 v1_objPos;
float3 v2_objPos;
+ const float pid_rand = rand((int) pid);
+ float explode_phase = 0;
#if defined(_EXPLODE)
float3 n = normalize(cross(v1.worldPos - v0.worldPos, v2.worldPos - v0.worldPos));
float3 avg_pos;
@@ -135,22 +137,21 @@ void geom(triangle v2f tri_in[3],
float3 n1 = v1.normal;
float3 n2 = v2.normal;
- float phase = _Explode_Phase;
- phase = smoothstep(0, 1, phase);
- phase *= phase;
- phase *= 4;
- const float pid_rand = rand((int) pid);
+ explode_phase = _Explode_Phase;
+ explode_phase = smoothstep(0, 1, explode_phase);
+ explode_phase *= explode_phase;
+ explode_phase *= 4;
- if (phase > 1E-6) {
+ if (explode_phase > 1E-6) {
float3 axis = normalize(float3(
rand((int) ((v0.uv0.x + v0.uv0.y) * 1E9)) * 2 - 1,
rand((int) ((v1.uv0.x + v1.uv0.y) * 1E9)) * 2 - 1,
rand((int) ((v2.uv0.x + v2.uv0.y) * 1E9)) * 2 - 1));
- float3 np = BlendNormals(n, axis * phase);
+ float3 np = BlendNormals(n, axis * explode_phase);
- v0.worldPos += np * phase * pid_rand;
- v1.worldPos += np * phase * pid_rand;
- v2.worldPos += np * phase * pid_rand;
+ v0.worldPos += np * explode_phase * pid_rand;
+ v1.worldPos += np * explode_phase * pid_rand;
+ v2.worldPos += np * explode_phase * pid_rand;
v0_objPos = mul(unity_WorldToObject, float4(v0.worldPos, 1));
v1_objPos = mul(unity_WorldToObject, float4(v1.worldPos, 1));
@@ -162,16 +163,16 @@ void geom(triangle v2f tri_in[3],
chrono = (AudioLinkDecodeDataAsUInt( ALPASS_CHRONOTENSITY + uint2( 2, 1 ) ) % 1000000) / 1000000.0;
}
#endif
- v0.worldPos += n * phase * sin(_Time[2] + length(v0_objPos)*6 + chrono) * .01 + chrono * n * phase * .2;
- v1.worldPos += n * phase * sin(_Time[2] + length(v1_objPos)*6 + chrono) * .01 + chrono * n * phase * .2;
- v2.worldPos += n * phase * sin(_Time[2] + length(v2_objPos)*6 + chrono) * .01 + chrono * n * phase * .2;
+ v0.worldPos += n * explode_phase * sin(_Time[2] + length(v0_objPos)*6 + chrono) * .01 + chrono * n * explode_phase * .2;
+ v1.worldPos += n * explode_phase * sin(_Time[2] + length(v1_objPos)*6 + chrono) * .01 + chrono * n * explode_phase * .2;
+ v2.worldPos += n * explode_phase * sin(_Time[2] + length(v2_objPos)*6 + chrono) * .01 + chrono * n * explode_phase * .2;
avg_pos = (v0.worldPos + v1.worldPos + v2.worldPos) / 3;
v0.worldPos -= avg_pos;
v1.worldPos -= avg_pos;
v2.worldPos -= avg_pos;
- float theta = phase * 3.14159 * 4 + phase * (sin(_Time[1] * (1 + pid_rand) / 2.0 + pid_rand) + cos(_Time[1] * (1 + pid_rand) / 6.1 + pid_rand) * 2) * pid_rand * 2;
+ float theta = explode_phase * 3.14159 * 4 + explode_phase * (sin(_Time[1] * (1 + pid_rand) / 2.0 + pid_rand) + cos(_Time[1] * (1 + pid_rand) / 6.1 + pid_rand) * 2) * pid_rand * 2;
float4 quat = get_quaternion(axis, theta);
v0.worldPos = rotate_vector(v0.worldPos, quat);
v1.worldPos = rotate_vector(v1.worldPos, quat);
@@ -261,7 +262,7 @@ void geom(triangle v2f tri_in[3],
#endif
#if defined(_CLONES)
v2f clone_verts[3] = {v0, v1, v2};
- add_clones(clone_verts, tri_out);
+ add_clones(clone_verts, tri_out, pid_rand, explode_phase);
#endif // _CLONES
// Output transformed geometry.