2011-01-02 3 views
16

나는 GLSL에서 레이디 얼 블러 쉐이더를 가지고 있는데, 텍스처를 취하여 방사형 블러를 적용하고 그 결과를 화면에 렌더링합니다. 지금까지 아주 잘 작동합니다.GLSL 셰이더를 사용하여 전체 장면에 방사형 흐림 효과를 적용하려면 어떻게해야합니까?

문제는 장면의 첫 번째 텍스처에 방사형 흐림을 적용한다는 것입니다. 하지만 실제로하고 싶은 것은 장면에이 흐림 효과를 적용하는 것입니다.

이 기능을 구현하는 가장 좋은 방법은 무엇입니까? 쉐이더만으로이 작업을 수행 할 수 있습니까? 아니면 먼저 씬을 텍스처로 렌더링 한 다음 (OpenGL에서)이 텍스처를 쉐이더에 전달하여 처리해야합니까?

// 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

답변

16

이 기본적으로 불린다 "후 처리"당신이 (여기 : 방사형 흐림) 효과 적용하고 있기 때문에 전체 장면 에를 후입니다 렌더링.

그래서 그래, 당신 말이 맞아 :

  • 가하는 FBO를 생성,
  • 을 화면 크기 NPOT 질감 (GL_TEXTURE_RECTANGLE를) 만들 수있는 텍스처를 첨부 : 후 처리를위한 좋은 방법입니다 이
  • 이 FBO를 활성으로 설정하고 장면을 렌더링합니다.
  • FBO를 비활성화하고 FBO의 텍스처로 전체 화면 쿼드를 그립니다. 로서는

은 "왜"이유는 간단하다 : 씬 (프래그먼트 쉐이더 많은 화소에 독립적으로 실행된다) 병렬로 렌더링된다. 픽셀 (x, y)에 방사형 흐림 효과를 적용하려면 먼저 주변 픽셀의 미리 흐림 효과 픽셀 값을 알아야합니다. 그 동안에는 렌더링 중이기 때문에 첫 번째 패스에서는 사용할 수 없습니다.

따라서 전체 장면이 렌더링되고 조각 (x, y)에 대한 조각 쉐이더가 장면의 모든 픽셀을 읽을 수 있어야 방사형 흐림 효과를 적용해야합니다. 이것이 렌더링 단계가 2 번 필요한 이유입니다.

+0

정말 고맙습니다. 정말 도움이되었습니다. –

관련 문제