Bu tür dalgalanmalar bir GLSL parça gölgelendirici ile nasıl uygulanır?


11

Bu yüzden yansıma kısmını zaten uyguladım:

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;
}
}

kaynak

Şimdi soru şu, bu dalgalanmalar nasıl uygulanır?


3
Bu tam bir cevap değil, bir dizi ipucu: Efekti "canlandırmak" için bir üniformaya ihtiyacınız var - yani zamana benzer bir değişken. Bu timedeğeri kullanarak ,uv.xy(sin(time),cos(time)) ofset vektörü ile kaydırabilirsiniz. Tabii ki, sinüs ve kosinüs ofsetlerinin genliklerini bulmalısınız. Sadece uv.yilkini dengelemekle başlayacağım ve efekti nasıl daha fazla ayarlayabileceğimi göreceğim.
teodron

Bu ipuçları için çok teşekkürler. @ LeFauve uygulamasını denedikten sonra ihtiyacım olan şey bu oldu.
cepro

Yanıtlar:


11

Teodron'un önerdiklerini uygulamaya çalıştım:

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;
    }
}

Oldukça yakın görünüyor (temel görüntü olmadan söylemek zor), ancak parametreleri değiştirebilirsiniz.

Orada çalışırken görebilirsiniz: https://www.shadertoy.com/view/Xll3R7

Bazı açıklamalar:

  • Görüntüyü baş aşağı çektiğimden beri y koordinatını tersine çevirmek zorunda kaldım, ancak çözünürlük.xy'ye ilettiğiniz şeylere bağlı olabilir; sonuç sizin için ters çevrilmişse, uv.y
  • Düzgün beyanlarınızı değiştirdim, böylece shadertoy ile çalışır. Bu değişiklikleri göz ardı edebilirsiniz.
  • Bununla birlikte, zamanı sağlayan bir üniforma eklemeniz ve iGlobalTime yerine kullanmanız gerekir (bu, saniye cinsinden zamandır)
  • Örneğinizde bir tane var gibi göründüğü için bir gelgit efekti ekledim ama söylemek zor (bkz. Sepoffset değişkeni). Beğenmediyseniz kaldırabilirsiniz
  • İyi görünmediği için kaplama rengini kaldırdım ve örneğinizde bir tane yoktu
  • Etkinizi zevkinize göre ayarlamak için:
    • efekti hızlandırmak / yavaşlatmak için iGlobalTime faktörünü değiştirin (isterseniz her birini ayrı ayrı değiştirebilirsiniz, diyelim ki x hareketini hızlandırın ve y hareketini yavaşlatın)
    • efekti artırmak / azaltmak için cos () faktörünü değiştirme

EDIT: Ben yoffset @cepro değişiklik içerecek şekilde değiştirdim


1
Büyük çaba! +1
teodron

3
Yardımın için teşekkürler :). Bu gerçekten çok yakın bir sonuç veriyor. Ama bence son bir malzemeyi özlüyor. Resimde, bu dalgaların kameraya ne kadar yakın olduğuna (ekranın alt kısmına) daha büyük olduklarına (dikey olarak gerilmiş) dikkat edin. Öyleyse belki de y ofsetini uv.y ile ölçeklendirmemiz gerekir? şamandıra yoffset = ((0.3 - uv.y) /0.3) * 0.05 * (1.0 + cos (iGlobalTime * 3.0 + 50.0 * uv.y)); Bunu denedim ve sonucu beğendim.
cepro

@Cepro yakın dalgalanmalar için iyi yakalamak. Ben cevapsız
LeFauve

IMO modifiye dalga petterninde bir sorun var. Dalgalar benim için artarken, içlerinde o garip "aynalı" desen var (en son Chrome'da GTX 680).
Mario
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.