From 2d49d9db4712ae3cbd604ec7c9f8627e4f74bde6 Mon Sep 17 00:00:00 2001 From: yum Date: Tue, 25 Mar 2025 17:38:45 -0700 Subject: Add shatter wave gimmick --- 2ner.cginc | 14 +++++++++++++- 2ner.shader | 11 +++++++++++ features.cginc | 4 ++++ globals.cginc | 9 +++++++++ math.cginc | 20 ++++++++++++++++++++ shatter_wave.cginc | 30 ++++++++++++++++++++++++++++++ 6 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 shatter_wave.cginc diff --git a/2ner.cginc b/2ner.cginc index d9a5b4b..bc3813b 100644 --- a/2ner.cginc +++ b/2ner.cginc @@ -14,6 +14,7 @@ #include "letter_grid.cginc" #include "matcaps.cginc" #include "poi.cginc" +#include "shatter_wave.cginc" #include "ssfd.cginc" #include "yum_brdf.cginc" #include "yum_pbr.cginc" @@ -64,6 +65,10 @@ v2f vert(appdata v) { UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); +#if defined(_SHATTER_WAVE) + shatterWaveVert(v.vertex.xyz, v.normal, v.tangent); +#endif + #if defined(OUTLINE_PASS) [branch] if (!_Outlines_Enabled_Dynamic) { @@ -153,7 +158,7 @@ v2f vert(appdata v) { } float4 frag(v2f i -#if defined(_HARNACK_TRACING) +#if defined(_HARNACK_TRACING) || defined(_SHATTER_WAVE) , out float depth : SV_DepthLessEqual #endif ) : SV_Target { @@ -164,6 +169,13 @@ float4 frag(v2f i // Not necessarily normalized after interpolation i.normal = normalize(i.normal); +#if defined(_SHATTER_WAVE) + { + float4 clip_pos = mul(UNITY_MATRIX_VP, float4(i.worldPos, 1.0)); + depth = clip_pos.z / clip_pos.w; + } +#endif + #if defined(_EYE_EFFECT_00) EyeEffectOutput eye_effect_00 = EyeEffect_00(i); i.uv01.xy = eye_effect_00.uv; diff --git a/2ner.shader b/2ner.shader index 9ccb0b9..9c38983 100644 --- a/2ner.shader +++ b/2ner.shader @@ -503,6 +503,17 @@ Shader "yum_food/2ner" [HideInInspector] m_end_Letter_Grid("Letter grid", Float) = 0 //endex + //ifex _Shatter_Wave_Enabled==0 + [HideInInspector] m_start_Shatter_Wave("Shatter wave", Float) = 0 + [ThryToggle(_SHATTER_WAVE)] _Shatter_Wave_Enabled("Enable", Float) = 0 + _Shatter_Wave_Amplitude("Amplitude", Float) = 0.4 + _Shatter_Wave_Wavelength("Wavelength", Float) = 1 + _Shatter_Wave_Speed("Speed", Float) = 30 + _Shatter_Wave_Period("Period", Float) = 4 + _Shatter_Wave_Power("Power", Float) = 5 + _Shatter_Wave_Direction("Direction", Vector) = (0, 1, 0, 0) + [HideInInspector] m_end_Shatter_Wave("Shatter wave", Float) = 0 + //ifex _Mirror_UVs_In_Mirror==0 [HideInInspector] m_start_Mirror_UVs_In_Mirror("Mirror UVs in mirror", Float) = 0 [ThryToggle(_MIRROR_UVS_IN_MIRROR)] _Mirror_UVs_In_Mirror_Enabled("Enable", Float) = 0 diff --git a/features.cginc b/features.cginc index c22eb99..1b2b70a 100644 --- a/features.cginc +++ b/features.cginc @@ -196,6 +196,10 @@ #pragma shader_feature_local _LETTER_GRID //endex +//ifex _Shatter_Wave_Enabled==0 +#pragma shader_feature_local _SHATTER_WAVE +//endex + //ifex _Mirror_UVs_In_Mirror==0 #pragma shader_feature_local _MIRROR_UVS_IN_MIRROR //endex diff --git a/globals.cginc b/globals.cginc index 3ab4c53..d1fc5b6 100644 --- a/globals.cginc +++ b/globals.cginc @@ -415,4 +415,13 @@ float _Letter_Grid_Blurriness; float _Letter_Grid_Alpha_Threshold; #endif // _LETTER_GRID +#if defined(_SHATTER_WAVE) +float _Shatter_Wave_Amplitude; +float _Shatter_Wave_Wavelength; +float _Shatter_Wave_Speed; +float _Shatter_Wave_Period; +float _Shatter_Wave_Power; +float3 _Shatter_Wave_Direction; +#endif // _SHATTER_WAVE + #endif // __GLOBALS_INC diff --git a/math.cginc b/math.cginc index f44aa74..78b93ec 100644 --- a/math.cginc +++ b/math.cginc @@ -207,4 +207,24 @@ float median(float3 x) { return (x.r + x.g + x.b) - (x_min + x_max); } +// Quaternions +float4 qmul(float4 q1, float4 q2) +{ + return float4( + q2.xyz * q1.w + q1.xyz * q2.w + cross(q1.xyz, q2.xyz), + q1.w * q2.w - dot(q1.xyz, q2.xyz)); +} + +// Vector rotation with a quaternion +// http://mathworld.wolfram.com/Quaternion.html +float3 rotate_vector(float3 v, float4 r) +{ + float4 r_c = r * float4(-1, -1, -1, 1); + return qmul(r, qmul(float4(v, 0), r_c)).xyz; +} + +float4 get_quaternion(float3 axis_normal, float theta) { + return float4(axis_normal * sin(theta / 2), cos(theta / 2)); +} + #endif // __MATH_INC diff --git a/shatter_wave.cginc b/shatter_wave.cginc new file mode 100644 index 0000000..72f8097 --- /dev/null +++ b/shatter_wave.cginc @@ -0,0 +1,30 @@ +#ifndef __SHATTER_WAVE_INC +#define __SHATTER_WAVE_INC + +#include "globals.cginc" +#include "math.cginc" + +#if defined(_SHATTER_WAVE) + +void shatterWaveVert(inout float3 objPos, float3 objNormal, float3 objTangent) { + // Keyframes: + // 1. At rest + // 2. At peak, rotated PI radians along objTangent axis + // 3. At rest, rotated TAU radians along objTangent axis + float a = _Shatter_Wave_Amplitude; + float l = _Shatter_Wave_Wavelength; + float v = _Shatter_Wave_Speed; + float T = _Shatter_Wave_Period; + float3 wave_axis = normalize(_Shatter_Wave_Direction); + + // Imagine a wave propagating along `wave_axis`. + float wave_t = fmod(_Time[0] * _Shatter_Wave_Speed, _Shatter_Wave_Period) - _Shatter_Wave_Period * 0.5; + float wave_center = wave_t; + float3 objPos_proj = dot(objPos, wave_axis) * normalize(wave_axis); + float offset = exp(-length(objPos_proj - wave_center * wave_axis) * _Shatter_Wave_Power) * _Shatter_Wave_Amplitude; + objPos += objNormal * offset; +} + +#endif // _SHATTER_WAVE + +#endif // __SHATTER_WAVE_INC -- cgit v1.2.3