2016-03-23 21 views
5

Tôi muốn thực hiện một hiệu ứng sóng dọc như thế này:Làm thế nào để tạo hiệu ứng sóng dọc trong đổ bóng?

wave1

Nhưng tôi chỉ có thể tạo ra sóng sin bình thường.

Đây là shader mảnh của tôi:

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

và kết quả là:

wave2

Vì vậy, câu hỏi là làm thế nào để warp sóng trên một hướng đi cụ thể?

cảm ơn.

đây là kết cấu nguồn gốc: origin texture


update: Tôi bóp méo trục x khi tính toán y, nhưng kết quả dường như không đúng.

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. bạn cũng nên thêm kết cấu đầu vào chưa phân loại để thử nghiệm. 2. bạn cần phải bóp méo cũng 'x' trục bạn đang tính toán' y = sin (w * p.x + t) * A; 'do đó cố gắng bóp méo cũng' x' như 'x = sin (w * p.y + t) * A; 'và có thể chơi một chút với hằng số (có hằng số riêng biệt cho' x' và 'y'). – Spektre

+0

cảm ơn bạn đã trả lời, tôi cố gắng bóp méo x asix và áp dụng v_texCoord.y làm yếu tố. nhưng kết quả có vẻ không đúng. – thrillerist

Trả lời

8

OK tôi đã cố gắng để tái tạo hiệu ứng của bạn vì vậy tôi sử dụng điều này như kết cấu:

texture

tôi lấy hình ảnh của bạn và thay đổi kích thước 512x512 vì thế nó là sức mạnh của 2 điền vào đường viền với màu đen. Vì bạn không chia sẻ Vertex shader tôi đã tạo của riêng mình. GL hiển thị quad đơn <-1,+1> mà không có tọa độ kết cấu hoặc ma trận chỉ glVertex2f() với kết cấu 2D được gắn với đơn vị 0. Tôi hơi viết lại đoạn của bạn để phù hợp với đầu ra. Ngoài ra tôi thêm tx,ty đồng phục để dễ dàng làm động tác với vị trí chuột <0,1> Dưới đây là các vertex shader đầu tiên:

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

Và sau đó đoạn:

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

Đây là đầu ra cho tx=0.3477,ty=0.7812 mà trực quan hơn hoặc trận đấu ít ví dụ của bạn:

output

Như bạn có thể thấy tôi thêm vài thuật ngữ vào các sóng tội lỗi để nó cũng bị bóp méo.

Nếu bạn có v_texCoord đã có trong phạm vi <0,1> sau đó bỏ qua

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

hoặc viết lại nó để (vì vậy co và hệ số ở lại như nên)

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

Nếu bạn sử dụng kết cấu khác nhau (không phải của tôi) thì bạn cần phải rescale tất cả các hệ số.

[edit1] hệ số nghĩa

đầu tiên tôi bắt đầu với bạn:

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

Các 0.15 là sóng biên độ mà có vẻ là quá lớn vì vậy tôi hạ thấp nó để 0.05. Sau đó, 10.0 là tần số số càng lớn thì càng có nhiều sóng dọc theo trục. Bằng thử nghiệm thuần túy & lỗi Tôi xác định chúng phải là 30.0 cho trục y và 25.0 cho trục x sao cho số lượng wave phù hợp với đầu ra mong muốn của bạn.

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

Sau này tôi phát hiện rằng những con sóng nên được một chút lệch vì vậy tôi thêm sự phụ thuộc vào các trục khác nữa sau khi một số tinh chỉnh phát hiện ra phương trình này:

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; 

nơi cả hai hệ số đều giống nhau ở giữa các trục (kỳ lạ nhưng làm việc tôi đã mong đợi tôi sẽ cần phải có hệ số khác nhau giữa các trục). Sau đây là chỉ là vấn đề của việc tìm kiếm các giai đoạn chính xác cho mỗi trục vì vậy tôi thêm giai đoạn chuyển đổi điều khiển bởi vị trí chuột (tx,ty) <0.0,1.0> vì vậy tôi có trận chung kết:

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; 

Sau đó, tôi chơi với con chuột (in vị trí của nó) cho đến khi tôi nhận được đủ gần để phù hợp với sản lượng mong muốn của bạn khi là tx=0.3477,ty=0.7812 để bạn có thể mã cứng

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

có vẻ khá tốt! bạn có thể giải thích một số toán về thuật toán? lý do tại sao sử dụng các coeffients – thrillerist

+0

@thrillerist thêm ** [edit1] ** với desription – Spektre

+0

nhờ sự giúp đỡ :) bằng cách này, những gì khuôn khổ để bạn sử dụng, bạn có thể kiểm soát các hệ số trong thời gian thực? – thrillerist

Các vấn đề liên quan