GLSL 音に反応する波紋エフェクト改良バージョン

2015/11/08 20:00

先ほど 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);
}


  このエントリーをはてなブックマークに追加    

<<「ソフトウェア開発」の記事一覧に戻る

関連記事