先ほど GLSL で作った波紋エフェクトの改良バージョンです。
波紋の数を1個から64個に増やして、波紋の生成から消滅までのアニメーションをもう少し現実の波紋に近づけました。
加えて、波紋の生成位置を、入力された音の振幅、高さに関連付けました。
上下が音程に関連し、左右が音量に関連しています。
ごちゃごちゃしてきた上に相変わらず無駄が多いですが、参考までにフラグメントシェーダのコードも載せておきます。
const int kNumVorteces = 64;
uniform sampler2D u_texture;
uniform float u_ripple_strength[kNumVorteces];
uniform float u_ripple_offset[kNumVorteces];
uniform float u_ripple_frequency;
uniform vec2 u_ripple_centers[kNumVorteces];
uniform float u_ripple_sine_disappear_distance[kNumVorteces];
uniform float u_horizontal_sine_distortion_frequency;
uniform float u_horizontal_sine_distortion_width;
uniform float u_horizontal_sine_distortion_offset;
uniform float u_vertical_sine_distortion_frequency;
uniform float u_vertical_sine_distortion_width;
uniform float u_vertical_sine_distortion_offset;
in highp vec2 a_fragment_uv_coord;
out vec4 o_diffuse;
const float PI = 3.1415926;
vec2 GetRippleDistortedUv(
float ripple_strength,
float ripple_offset,
float sine_disappear_distance,
float distance_source_u,
float distance_source_v,
float distort_source_u,
float distort_source_v,
float distance_center_x,
float distance_center_y)
{
float distance_square = (distance_source_u - distance_center_x) * (distance_source_u - distance_center_x)
+ (distance_source_v - distance_center_y) * (distance_source_v - distance_center_y);
float distance = sqrt(distance_square);
float normalized_distance = clamp(distance, 0.0, sine_disappear_distance) / sine_disappear_distance;
float sine_strength = ripple_strength * (1.0 - normalized_distance) * (1.0 - normalized_distance);
float theta = sin(ripple_offset + distance * u_ripple_frequency) * sine_strength;
float u0 = distort_source_u - 0.5;
float v0 = distort_source_v - 0.5;
float u1 = u0 * cos(theta) - v0 * sin(theta);
float v1 = u0 * sin(theta) + v0 * cos(theta);
float u2 = u1 + 0.5;
float v2 = v1 + 0.5;
return vec2(u2, v2);
}
void main(void)
{
float u = a_fragment_uv_coord.x + sin(a_fragment_uv_coord.y * PI * u_vertical_sine_distortion_frequency
+ u_vertical_sine_distortion_offset) * u_vertical_sine_distortion_width;
float v = a_fragment_uv_coord.y + sin(a_fragment_uv_coord.x * PI * u_horizontal_sine_distortion_frequency
+ u_horizontal_sine_distortion_offset) * u_horizontal_sine_distortion_width;
vec2 disorted_uv = vec2(u, v);
for (int i = 0; i < kNumVorteces; ++i)
{
if (u_ripple_sine_disappear_distance[i] == 0.0)
{
continue;
}
disorted_uv = GetRippleDistortedUv(
u_ripple_strength[i],
u_ripple_offset[i],
u_ripple_sine_disappear_distance[i],
u, v,
disorted_uv.x, disorted_uv.y,
u_ripple_centers[i].x, u_ripple_centers[i].y);
}
o_diffuse = texture(u_texture, disorted_uv);
}