2011-01-02 21 views
16

Tôi có bộ đổ bóng mờ xuyên tâm trong GLSL, có kết cấu, áp dụng hiệu ứng làm mờ hình tròn cho nó và hiển thị kết quả cho màn hình. Điều này hoạt động rất tốt, cho đến nay.Tôi làm cách nào để sử dụng trình đổ bóng GLSL để áp dụng hiệu ứng nhòe hình tròn cho toàn cảnh?

Vấn đề là, điều này áp dụng hiệu ứng nhòe hình tròn cho kết cấu đầu tiên trong cảnh. Nhưng điều tôi thực sự muốn làm là áp dụng hiệu ứng nhòe này cho toàn cảnh toàn cảnh.

Cách tốt nhất để đạt được chức năng này là gì? Tôi có thể làm điều này với chỉ shaders, hoặc làm tôi phải render cảnh đến một kết cấu đầu tiên (trong OpenGL) và sau đó vượt qua kết cấu này để đổ bóng để tiếp tục xử lý?

// Vertex shader 

varying vec2 uv; 

void main(void) 
{ 
    gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0); 
    gl_Position = sign(gl_Position); 
    uv = (vec2(gl_Position.x, - gl_Position.y) + vec2(1.0))/vec2(2.0); 
} 


// Fragment shader 

uniform sampler2D tex; 
varying vec2 uv; 
const float sampleDist = 1.0; 
const float sampleStrength = 2.2; 

void main(void) 
{ 
    float samples[10]; 
    samples[0] = -0.08; 
    samples[1] = -0.05; 
    samples[2] = -0.03; 
    samples[3] = -0.02; 
    samples[4] = -0.01; 
    samples[5] = 0.01; 
    samples[6] = 0.02; 
    samples[7] = 0.03; 
    samples[8] = 0.05; 
    samples[9] = 0.08; 

    vec2 dir = 0.5 - uv; 
    float dist = sqrt(dir.x*dir.x + dir.y*dir.y); 
    dir = dir/dist; 

    vec4 color = texture2D(tex,uv); 
    vec4 sum = color; 

    for (int i = 0; i < 10; i++) 
     sum += texture2D(tex, uv + dir * samples[i] * sampleDist); 

    sum *= 1.0/11.0; 
    float t = dist * sampleStrength; 
    t = clamp(t ,0.0,1.0); 

    gl_FragColor = mix(color, sum, t); 
} 

alt text

Trả lời

16

này về cơ bản được gọi là "post-processing" vì bạn đang áp dụng một hiệu ứng (ở đây: Radial Blur) để toàn bộ cảnh sau nó kết xuất.

Vì vậy, có, bạn nói đúng: cách tốt cho post-processing là:

  • tạo ra một màn hình có kích thước NPOT texture (GL_TEXTURE_RECTANGLE),
  • tạo ra một FBO, đính kèm các kết cấu để nó
  • đặt FBO này thành hoạt động, hiển thị cảnh
  • vô hiệu hóa FBO, vẽ quad toàn màn hình với kết cấu FBO.

Đối với "tại sao", lý do rất đơn giản: các cảnh được thực hiện tại song song (đổ bóng đoạn được thực hiện một cách độc lập đối với nhiều pixel). Để làm mờ hình tròn cho pixel (x, y), trước tiên bạn cần phải biết giá trị pixel làm mờ trước của các pixel xung quanh. Và những thứ đó không có sẵn trong lần đầu tiên, bởi vì chúng chỉ được kết xuất trong thời gian chờ đợi.

Vì vậy, bạn phải áp dụng hiệu ứng nhòe hình tròn sau khi toàn bộ cảnh được hiển thị và đổ bóng phân mảnh cho đoạn (x, y) có thể đọc bất kỳ pixel nào từ cảnh. Đây là lý do tại sao bạn cần 2 giai đoạn dựng hình cho điều đó.

+0

cảm ơn bạn rất nhiều, điều đó thực sự đã giúp ích rất nhiều! –

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