GLSLフラグメントシェーダーでこの種のリップルを実装する方法は?


11

だから私はすでに反射部分を実装しました:

uniform sampler2D texture;
uniform vec2 resolution;
uniform vec3 overlayColor;

void main()
{
vec2 uv = gl_FragCoord.xy / resolution.xy;

if (uv.y > 0.3)// is air - no reflection or effect
{
    gl_FragColor = texture2D(texture, vec2(uv.x, uv.y));
}
else
{
    // Compute the mirror effect.
    vec4 color = texture2D(texture, vec2(uv.x, 0.6 - uv.y));
    // 
    vec4 finalColor = vec4(mix(color.rgb, overlayColor, 0.25), 1.0);
    gl_FragColor = finalColor;
}
}

ソース

今問題は、これらの波紋がどのように実装されているかです。


3
これは完全な答えではありませんが、一連のヒントです。エフェクトを「アニメーション化」するには、ユニフォーム、つまり時間のような変数が必要です。そのtime値を使用しuv.xyて、(sin(time),cos(time))オフセットベクトルでをシフトできます。もちろん、正弦オフセットと余弦オフセットの振幅を把握する必要があります。uv.y最初のオフセットから始めて、エフェクトをさらに調整する方法を確認します。
teodron、2015年

これらのヒントをどうもありがとうございました。@LeFauveの実装を試した後、これが必要なことがわかりました。
cepro 2015年

回答:


11

私はテオドロンが示唆したことを実装しようとしました:

void main()
{
    vec2 uv = gl_FragCoord.xy / resolution.xy;
    float sepoffset = 0.005*cos(iGlobalTime*3.0);
    if (uv.y > 0.3 + sepoffset)// is air - no reflection or effect
    {
        gl_FragColor = texture2D(texture, vec2(uv.x, -uv.y));
    }
    else
    {
        // Compute the mirror effect.
        float xoffset = 0.005*cos(iGlobalTime*3.0+200.0*uv.y);
        //float yoffset = 0.05*(1.0+cos(iGlobalTime*3.0+50.0*uv.y));
        float yoffset = ((0.3 - uv.y)/0.3) * 0.05*(1.0+cos(iGlobalTime*3.0+50.0*uv.y));
        vec4 color = texture2D(texture, vec2(uv.x+xoffset , -1.0*(0.6 - uv.y+ yoffset)));
        // 
        //vec4 finalColor = vec4(mix(color.rgb, overlayColor, 0.25), 1.0);
        gl_FragColor = color;
    }
}

見た目はかなり似ていますが(ベースイメージがないとわかりにくいです)、パラメータを微調整できます。

あなたはそこでそれを実際に見るかもしれません:https//www.shadertoy.com/view/Xll3R7

いくつかの備考:

  • 画像を上下逆さまにしていたので、y座標を反転する必要がありましたが、それは、resolution.xyに渡す内容によって異なる場合があります。結果が反転した場合は、uv.yの反転を解除します
  • Shadertoyで動作するように、ユニフォームの宣言を変更しました。これらの変更は無視できます。
  • ただし、時間を提供するユニフォームを追加し、iGlobalTime(秒単位の時間)の代わりに使用する必要があります。
  • 潮汐効果を追加したのは、例にあるように見えますが、わかりにくいためです(sepoffset変数を参照)。気に入らない場合は削除してください
  • 見栄えが悪いのでオーバーレイの色を削除しましたが、あなたの例にはありませんでした
  • 効果を好みに合わせて調整するには:
    • iGlobalTimeの係数を変更して、効果をスピードアップ/スローダウンします(必要に応じて、それぞれを個別に変更できます。たとえば、xの動きを加速し、yの動きを遅くします)。
    • cos()係数を変更して、効果を増幅/減衰します

編集:@ceproからの変更を含めるようにyoffsetを変更しました


1
大変な努力を!+1
teodron、2015年

3
ご協力ありがとうございました :)。これは本当にかなり近い結果をもたらします。しかし、私はそれが最後の一つの要素を欠いていると思います。写真では、これらの波紋がカメラ(画面の下部)に近いほど大きくなっています(垂直に引き伸ばされています)。それで、おそらくy。オフセットをuv.yでスケーリングする必要がありますか?float yoffset =((0.3-uv.y)/0.3)* 0.05 *(1.0 + cos(iGlobalTime * 3.0 + 50.0 * uv.y));。私はこれを試しました、そして私は結果がちょっと好きです。
cepro 2015年

近い波紋@ceproの良いキャッチ。見逃しました
LeFauve、2015年

IMO修正されたウェーブパターンに問題があります。私にとっては波が高まる一方で、奇妙な「ミラーリング」パターンが含まれています(最新のChromeのGTX 680)。
Mario
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.