2016-03-23 18 views
5

Böyle bir dalga çözgü efekti yapmak istiyorum:Gölgelendiricide dalga çözgü efekti nasıl yapılır?

wave1

Ama sadece normal bir sinüs dalgası yaratabilir.

precision mediump float; 
varying vec2 v_texCoord; 
uniform sampler2D s_baseMap; 

vec2 SineWave(vec2 p){ 
    float pi = 3.14159; 
    float A = 0.15; 
    float w = 10.0 * pi; 
    float t = 30.0*pi/180.0; 
    float y = sin(w*p.x + t) * A; 
    return vec2(p.x, p.y+y);  
} 
void main(){ 
    vec2 p = v_texCoord; 
    vec2 uv = SineWave(p); 
    vec4 tcolor = texture2D(s_baseMap, uv); 
    gl_FragColor = tcolor; 
} 

ve sonucudur:

Yani soru belirli bir yöne dalga çarpıtmak için nasıl

wave2

İşte

benim parça gölgelendirici nedir?

Teşekkürler. Burada

kökenli doku geçerli: origin texture


güncelleme: hesaplama y ancak sonuç doğru değil gibi görünüyor zaman ben x eksenini bozar. böylece 2 gücüdür

texture

Ben senin imajını alıp 512x512 yeniden boyutlandırmak: Ben senin etkisini yeniden çalıştı

float x = p.x + p.y*tan(-0.5); 
float y = sin(w*x + t) * A; 
return vec2(p.x, p.y+y); 

distort x axis

+0

1. test için de bozulmamış giriş dokusunu eklemek gerekir zaman oldu istenen çıktıyı maç için yeterince yakın. 2. de 'x' eksenini deforme etmelisiniz ki hesaplıyorsunuz y = sin (w * p.x + t) * A; '' de 'x' gibi x'i de bozmaya çalışın x = sin (w * p.y + t) * A; ve sabitlerle (x için ayrı sabitlere ve y'ye) sahip olabilirler. – Spektre

+0

Cevabınız için teşekkürler, x asix'i deforme etmeye çalışıyorum ve v_texCoord.y'yi faktör olarak uygula. ama sonuç doğru değil gibi görünüyor. – thrillerist

cevap

8

Tamam yüzden doku olarak kullandı sınırı siyahla doldur. Vertex shader'ı paylaşmadığınız için kendimi yarattım. GL doku koordinatları veya matrisleri sadece glVertex2f() birimine 0 binded tek 2D doku ile olmaksızın tek dörtlü <-1,+1> render edilir. Parçanızı çıktısına uyacak şekilde hafifçe yeniden yazarım.

// Vertex 
varying vec2 v_texCoord; 
void main() 
    { 
    v_texCoord=gl_Vertex.xy; 
    gl_Position=gl_Vertex; 
    } 

Sonra fragman: Ayrıca kolayca ilk köşe Burada shaderlar olan fare pozisyon <0,1> etkisi ile animasyon tx,ty üniforma ilave

// Fragment 
varying vec2 v_texCoord;  // holds the Vertex position <-1,+1> !!! 
uniform sampler2D s_baseMap; // used texture unit 
uniform float tx,ty;   // x,y waves phase 

vec2 SineWave(vec2 p) 
    { 
    // convert Vertex position <-1,+1> to texture coordinate <0,1> and some shrinking so the effect dont overlap screen 
    p.x=(0.55*p.x)+0.5; 
    p.y=(-0.55*p.y)+0.5; 
    // wave distortion 
    float x = sin(25.0*p.y + 30.0*p.x + 6.28*tx) * 0.05; 
    float y = sin(25.0*p.y + 30.0*p.x + 6.28*ty) * 0.05; 
    return vec2(p.x+x, p.y+y); 
    } 

void main() 
    { 
    gl_FragColor = texture2D(s_baseMap,SineWave(v_texCoord)); 
    } 

Bu tx=0.3477,ty=0.7812 için çıktı olan görsel olarak daha fazla veya daha az stoktaki senin örnek:

output

As you can günah dalgalarına birkaç terim ekledim, bu yüzden çarpık çarpıklık da var.

Eğer (farklı doku kullanırsanız v_texCoord zaten

p.x=(1.1*p.x)-0.05; 
    p.y=(1.1*p.y)-0.05; 

aralığında <0,1> sonra

p.x=(0.55*p.x)+0.5; 
    p.y=(-0.55*p.y)+0.5; 

görmezden veya onu yeniden yazmak (böylece psikologa ve katsayıları gerektiği gibi kal) varsa benim değil) o zaman tüm katsayıları yeniden ölçeklendirmeniz gerekiyor.

ilk ben senin ile başladı anlam

[edit1] katsayıları:

float x = sin(10.0*p.y) * 0.15; 
float y = sin(10.0*p.x) * 0.15; 

çok büyük gibi görünüyor 0.15 olan dalga genliği yüzden 0.05 doğru indirin. Daha sonra 10.0 frekansı, sayı arttıkça eksen boyunca daha fazla dalga olacaktır. Saf deneme & hatası ile bunların, y ekseni için 30.0 ve x ekseni için 25.0 olması gerektiğini belirledim, böylece dalga sayısı istediğiniz çıkışla eşleşiyor.

float x = sin(25.0*p.y + 30.0*p.x) * 0.05; 
float y = sin(25.0*p.y + 30.0*p.x) * 0.05; 

hem katsayıları aynıdır:

float x = sin(25.0*p.y) * 0.05; 
float y = sin(30.0*p.x) * 0.05; 

Bundan sonra ben dalgalar biraz bu yüzden bazı ince ayarların Bu denklemi öğrendim de sonra diğer eksende bağımlılık ekleyin çarpık gerektiğini benekli eksenler arasında (garip ama çalışıyordum, eksenler arasında farklı katsayılar olmasını beklemekteydim). Bu ben fare pozisyonu ile kontrol faz kaymasını eklemek böylece her eksen için doğru faz bulma meselesi sonra (tx,ty) <0.0,1.0> yüzden got son: Ben oluncaya kadar

Sonra fare ile oynamak
float x = sin(25.0*p.y + 30.0*p.x + 6.28*tx) * 0.05; 
float y = sin(25.0*p.y + 30.0*p.x + 6.28*ty) * 0.05; 

(konumunu baskı) tx=0.3477,ty=0.7812 böylece koda

float x = sin(25.0*p.y + 30.0*p.x + 6.28*0.3477) * 0.05; 
float y = sin(25.0*p.y + 30.0*p.x + 6.28*0.7812) * 0.05; 
+0

oldukça iyi görünüyor! Algoritma hakkında biraz matematik açıklayabilir misiniz? Bu katsayıları neden kullanmalısınız – thrillerist

+0

@thrillerist ** [edit1] ** despiyonkasyon – Spektre

+0

ekledikten sonra yardım için teşekkürler :) Bu arada, hangi çerçeve kullanıyorsunuz, katsayıları gerçek zamanda kontrol edebilir misiniz? – thrillerist

İlgili konular