2011-08-14 4 views
0

조각 쉐이더를 통해 내 자신의 사용자 지정 glBlendFunc를 수행하려고하지만 정확한 혼합 기능을 수행 할 때도 내 솔루션이 기본 glBlendFunc보다 훨씬 느립니다.사용자 지정 glBlendFunc 훨씬 네이티브보다 느림

누구든지보다 효율적인 방법으로이 작업을 수행하는 방법에 대한 제안이 있는지 궁금합니다. '혼합 작업은 GPU 하드웨어에 직접 내장되어 있기 때문에 아마 당신은 때로 믿을 수 있도록이 훨씬 더 효율적입니다

void draw(fbo fbos[2], render_item item) 
{ 
    // fbos[0] is the render target 
    // fbos[1] is the previous render target used to read "background" to blend against in shader 
    // Both fbos have exactly the same content, however they need to be different since we can't both read and write to the same texture. The texture we render to needs to have the entire content since we might not draw geometry everywhere. 

    fbos[0]->attach(); // Attach fbo 
    fbos[1]->bind(1); // Bind as texture 1 

    render(item); 

    glCopyTexSubImage2D(...); // copy from fbos[0] to fbos[1], fbos[1] == fbos[0] 
} 

fragment.glsl

vec4 blend_color(vec4 fore) 
{ 
    vec4 back = texture2D(background, gl_TexCoord[1].st); // background is read from texture "1" 
    return vec4(mix(back.rgb, fore.rgb, fore.a), back.a + fore.a); 
} 

답변

3

FBO 기반 블렌딩의 성능을 향상시키는 가장 좋은 방법은 NV_texture_barrier입니다. 이름에도 불구하고, AMD는 그것을 또한 실행 했으므로 Radeon HD 급 카드를 사용하면 사용할 수 있습니다.

기본적으로 FBO 바인딩 또는 텍스처 첨부 작업과 같은 중량 작업없이 탁구를 할 수 있습니다. 사양에는 일반 알고리즘을 보여주는 아래쪽 부분이 있습니다.

또 다른 대안은 EXT_shader_image_load_store입니다. 이를 위해서는 DX11/GL 4.x 클래스 하드웨어가 필요합니다. OpenGL 4.2는 최근에 ARB_shader_image_load_store으로 이것을 핵심으로 승격했습니다.

Darcy가 말했듯이, 당신은 규칙적인 블렌딩을 결코 이길 수 없을 것입니다. 셰이더가 액세스 할 수없는 특별한 하드웨어 구조를 사용합니다 (셰이더가 실행 된 이후에 발생하기 때문에). 다른 방법으로는 절대 달성 할 수없는 효과가있는 경우에만 프로그래밍 방식으로 혼합해야합니다.

+0

NV_texture_barrier를 사용하면 동일한 텍스처를 동시에 렌더링하고 읽을 수 있습니다. – ronag

+0

@ronag : 일종의. 확장 스펙을 읽는 것이 가장 좋지만, 일반적인 개념은 _same 장소에서 그렇게하지 않는 한 동일한 텍스처를 읽고 쓸 수 있다는 것입니다. 그리고 당신은 장벽을 적절히 사용합니다. –

2

:

내 솔루션은 다음과 같이 작동 속도를 위해 이길 수있을 것입니다. 그런데 깊이 테스트, 뒷면면 제거, 하드웨어 블렌딩 및 기타 불필요한 작업을 해제했는지 확인하십시오. 나는 그것이 큰 차이를 만들 것이라고 말할 수는 없지만, 어떤 것을 만들 수도 있습니다.