2014-11-19 12 views
1

OpenGL부터 ​​시작해서 톤 매핑 알고리즘을 만들고 싶습니다.텍스처의 최대/최소 휘도 얻기 OpenGL

내 첫 번째 단계는 HDR 이미지의 최대/최소 광도 값을 얻는 것입니다.

FBO의 텍스처에 이미지가 있고 시작하는 방법이 확실하지 않습니다.

나는 최선의 방법은 텍셀 코드를 조각 셰이더에 전달한 다음 모든 픽셀을 통과하고 작은 텍스처를 생성하는 것이라고 생각합니다.

그러나 1x1 텍스처가있을 때까지 수동으로 다운 샘플링을 수행하는 방법을 알지 못합니다. FBO가 많이 있어야합니까? 어디에서 각각 새로운 텍스처를 만듭니 까?

많은 정보를 검색했지만 아직 명확한 정보가 거의 없습니다.

나 자신을 위치시키고 시작하는 데 도움이 될만한 도움을 주시면 감사하겠습니다.

편집 1. 여기 내 쉐이더를, 그리고 내가 버텍스 쉐이더에 텍스처 좌표를 전달 방법 :

void drawQuad(Shaders* shad){ 
    // coords: vertex (3) + texture (2) 
    std::vector<GLfloat> quadVerts = { 
    -1, 1, 0, 0, 0, 
    -1, -1, 0, 0, 1, 
    1, 1, 0, 1, 0, 
    1, -1, 0, 1, 1}; 

    GLuint quadVbo; 
    glGenBuffers(1, &quadVbo); 
    glBindBuffer(GL_ARRAY_BUFFER, quadVbo); 
    glBufferData(GL_ARRAY_BUFFER, 4 * 5 * sizeof(GLfloat), &quadVerts[0], GL_STATIC_DRAW); 
    // Shader attributes 
    GLuint vVertex = shad->getLocation("vVertex"); 
    GLuint vUV = shad->getLocation("vUV"); 

    glEnableClientState(GL_VERTEX_ARRAY); 
    glVertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), NULL); 
    // Set attribs 
    glEnableVertexAttribArray(vVertex); 
    glVertexAttribPointer(vVertex, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, 0); 
    glEnableVertexAttribArray(vUV); 
    glVertexAttribPointer(vUV, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (void*)(3 * sizeof(GLfloat))); 

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Draw 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glDisableVertexAttribArray(vVertex); 
    glDisableVertexAttribArray(vUV); 
} 

정점 :

텍스처 좌표와 정점의 위치를 ​​전달하기 위해, 나는 VBO를 사용하여 쿼드을 그립니다 쉐이더 :

#version 420 

in vec2 vUV; 
in vec4 vVertex; 
smooth out vec2 vTexCoord; 

uniform mat4 MVP; 
void main() 
{ 
    vTexCoord = vec2(vUV.x * 1024,vUV.y * 512); 
    gl_Position = MVP * vVertex; 
} 

그리고 조각 쉐이더 :

#version 420 

smooth in vec2 vTexCoord; 
layout(binding=0) uniform sampler2D texHDR; // Tex image unit binding 
layout(location=0) out vec4 color; //Frag data output location 
vec4[4] col; 
void main(void) 
{ 
    for(int i=0;i<=1;++i){ 
     for(int j=0;j<=1;++j){ 
      col[(2*i+j)] = texelFetch(texHDR, ivec2(2*vTexCoord.x+i,2*vTexCoord.y+j),0); 
     } 
    } 
    color = (col[0]+col[1]+col[2]+col[3])/4;  
} 

이 테스트 코드에서 크기가 1024 * 512 인 텍스처가 있습니다. 내 생각은 FBO (layout(location=0))에 GL_ATTACHMENT_0에 연결된 텍스처로 렌더링하고이 쉐이더와 에 바인드 된 텍스처는 이미지 (layout(binding=0))를 사용하여 렌더링합니다. 내 목표는 FBO 텍스처의 이미지를 texHDR으로 설정하여 크기를 2 줄이는 것입니다.

답변

1

다운 샘플링의 경우 프래그먼트 셰이더에서 수행해야하는 작업은 여러 텍스처 조회이며 출력 조각을 위해 결합해야합니다. 예를 들어 2x2 조회를 수행 할 수 있으므로 각 패스는 x 및 y의 해상도를 2로 줄입니다.

1024x1024 이미지를 축소한다고 가정 해 봅시다. 그런 다음 쿼드를 512x512 이미지로 렌더링합니다. 정점 쉐이더가 0과 511 사이의 x와 y에 대한 값을 간단하게 생성하도록 설정합니다. 조각 쉐이더는 texelFetch(tex, ivec2(2*x+i,2*y+j))을 호출합니다. 여기에서 i와 j는 0에서 1까지 반복됩니다. 네 개의 값을 출력하고 텍스처에서 최소 및 최대 출력을 캐시합니다.

+0

답변 해 주셔서 감사합니다. VBOX에서 버텍스 쉐이더에 texcoords를 넘길 때 값은'[0,1]'이므로 내 텍스처 (1024 x 512)에서이 라인을 다음과 같이 수정했습니다 :'' texelFetch (tex, ivec2 ((2 * x + i)/1024, (2 * y + j)/512)) '하지만 디스플레이에 빈 텍스처가 표시됩니다. – MikeFadeCrew

+0

무슨 뜻인지 이해가 안됩니다. 'texelFetch'는 [0, width], [0, height] 범위의 텍셀 좌표를 취합니다. 따라서 인자 2로 줄이면 코드가 실제로 이해가되지 않습니다. 코드를 게시하려면 질문을 편집하십시오 . –

+0

내가 편집 한 코드를 버텍스 쉐이더에 곱함으로써 ('texelFetch (tex, ivec2 (2 * x + i, 2 * y + j)') ]) 텍스쳐 크기에 따라. – MikeFadeCrew