OpenGL의 렌더 버퍼에서 텍스처를 가져 오십니까?


13

FBO에 렌더 버퍼 (DepthStencil)가 있으며 텍스처를 가져와야합니다. FBO에 DepthComponent 텍스처와 DepthStencil 렌더 버퍼를 둘 다 가질 수 없으므로 파이프 라인에서 나중에 사용하기 위해 렌더 버퍼를 DepthComponent 텍스처로 변환하는 방법이 필요합니다.

몇 주 동안 렌더 버퍼에서 깊이 구성 요소를 가져 오기 위해 많은 기술을 시도했지만 항상 쓰레기가 나옵니다. 마지막에 원하는 것은 렌더 버퍼를 사용하지 않은 경우 FBO에서 얻을 수있는 것과 동일한 텍스처입니다. 누구나 간단 해 보이는 간단한 작업을 다루는 포괄적 인 지침이나 코드를 게시 할 수 있습니까?

편집하다:

코드 http://dl.dropbox.com/u/9279501/fbo.cs 의 추출 버전에 연결

피사계 심도 효과 + FBO-깊이 없음 (!) http://i.stack.imgur.com/Hj9Oe.jpg

피사계 심도 효과가없는 Screeny + FBO-심도 정밀 작업 http://i.stack.imgur.com/boOm1.jpg

답변:


2

또는 렌더 버퍼 기반에서 텍스쳐 기반으로 한 FBO에서 다른 FBO로 블리 팅 할 수 있습니다. 나는 이것을 이렇게한다 :

glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_renderBufferSurface->m_fbo);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_textureSurface->m_fbo);
glBlitFramebufferEXT(0, 0, m_renderBufferSurface->m_width, m_renderBufferSurface->m_height, 0, 0, m_textureSurface->m_width, m_textureSurface->m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);

(깊이 버퍼를 원하는 경우 GL_COLOR_BUFFER_BIT 대신 GL_DEPTH_BUFFER_BIT를 사용할 수 있습니다)

텍스처 기반 렌더 버퍼로 블리 팅 한 후에는 텍스처를 정상적으로 사용할 수 있습니다. 유니폼이나 원하는대로 쉐이더에 전달하십시오.


1

아니요, 불가능합니다. 최대 glReadPix는 데이터를 CPU에 고정하고 텍스처를 생성 할 수 있지만 번거롭고 느립니다. 렌더 버퍼는 그 기능을위한 것이 아니며, 그 기능은 텍스처에 의해서만 제공됩니다.


그것을 감안할 때 대안은 무엇입니까? 드로우 버퍼에서 깊이를 어떻게 유지하고 깊이 구성 요소를 텍스처로 얻을 수 있습니까?
Rushyo

@Rushyo : 스텐실 버퍼를 제거하고 (가능한 경우) 깊이 렌더 버퍼를 깊이 텍스처로 만드는 대안이 될 수 있습니다. 왜 스텐실을 사용하고 있습니까?
Calvin1602

기본적으로 깊이 텍스처를 얻을 때마다 깊이 테스트가 중단됩니다. FBO에 깊이 첨부 파일을 첨부하면 FBO는 다른 곳에 깊이 정보를 쓰지 않습니다. 따라서 컬러 첨부 파일을 검색하려고 할 때 깊이 테스트가 없습니다 (일반적으로 깊이 첨부 파일이없는 경우) ). 위에서 언급 한 '거대한 및 느린'방법을 포함하여 생각할 수있는 모든 조합을 시도했습니다. 내가 무엇을하든 한 텍스처에서 내 장면의 '일반적인'렌더링과 다른 텍스처의 깊이를 모두 얻을 수는 없습니다.
Rushyo

@ Calvin1602 렌더 버퍼로 손을 대면 스텐실 부착없이 깊이 부착을 사용하면 원하지 않는 결과가 발생한다는 것을 알았습니다.
Rushyo

@Rushyo 난 당신이 텍스처를 올바르게 설정하지 않은 내기, 코드를 게시하면 도움이 될 것입니다 :)
Matias Valdenegro

1

당신이 요구하는 것은 OpenGL 3.2에서 가능합니다. FBO는 렌더 버퍼가 필요하지 않고 확산 색상을 색상 질감, 다른 색상 질감에 수직, 깊이 질감에 뱉어 내고 있습니다. 실제로 렌더 버퍼는 문제가되지 않습니다. 샘플링 할 수 없기 때문에 glReadPixels(...)GPU 메모리에 모든 것을 유지하는 대신 RBO에서 CPU의 텍스처로 데이터 를 사용 하거나 다른 방식으로 복사해야합니다. 그래서...

실제로 원한다면 첫 번째 패스 쉐이더에 코드를 작성하여 깊이와 같은 것을 수동으로 FBO의 별도 색상 텍스처 첨부 파일로 출력 할 수 있습니다. 즉 사용할 수 있도록 할 것입니다 당신이 게시물 패스 쉐이더한다. 들어 는 OpenGL의 내부 깊이 테스트에 사용, 당신은 추가하거나 당신의 FBO의 GL_DEPTH_ATTACHMENT로 RBO 또는 질감 세트가 필요합니다. 하지만 둘 다 제공하기 위해 단일 텍스처를 설정할 수 있습니다 있습니다.보다 효율적이고 사용하기 쉽습니다.

내 깊이 텍스처 설정 코드는 다음과 같습니다 (자바, ByteBuffer를 무시하고 ...이 개념은 실제로 Java에 잘 맞지 않기 때문에 정수 핸들 / 포인터를 참조하기 위해 "id"를 사용합니다).

        gBufferDepthTexture = new Texture();
        gBufferDepthTexture.id = glGenTextures();
        gBufferDepthTexture.unit = 2;
        gBufferDepthTexture.width = Display.getWidth();
        gBufferDepthTexture.height = Display.getHeight();
        gBufferDepthTexture.bytes = ByteBuffer.allocateDirect(Display.getWidth()*Display.getHeight() * 4);
        glActiveTexture(gBufferDepthTexture.unit + GL_TEXTURE0); //eg. 0 + 33984 = GL_TEXTURE0, while 31 + 33984 = GL_TEXTURE31.
        glBindTexture(GL_TEXTURE_2D, gBufferDepthTexture.id);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, gBufferDepthTexture.width, gBufferDepthTexture.height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, gBufferDepthTexture.bytes);
        //...GL_UNSIGNED_INT or GL_UNSIGNED_BYTE may work better for you, instead... YMMV.

        //glPixelStorei(GL_PACK_ALIGNMENT, 4);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

그리고 나중에 :

        glBindFrameBuffer(GL_DRAW_FRAMEBUFFER, fbo.id);
        //your existing glFramebufferTexture2D(...) calls here
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gBufferDepthTexture.id, 0);

이제 gBufferDepthTexture두 번째, 세 번째 패스 프래그먼트 셰이더에 유니폼으로 전달할 수 있습니다 . 스텐실 버퍼로 정확히 똑같은 일을 할 수 있다고 가정 할 수 있다고 생각합니다.


0

GL_DEPTH_STENCIL 형식을 사용하여 렌더 버퍼 대신 텍스처를 만들 수 있어야합니다. 셰이더 프로그램에서 이러한 텍스처의 깊이를 사용하는 정확한 프로세스는 확실하지 않지만 (FBO를 사용하고 있기 때문에 사용한다고 가정합니다) OpenGL 사양은 어떤 색상 채널이 어떤 값을 얻을지 지정해야합니다 ( 내 생각에 R, G 및 B는 모두 깊이로 설정되고 A는 스텐실로 설정됩니다.

요즘 OpenGL 3.2를 대상으로하므로 텍스처 형식이 적합한 지 확인해야 할 수도 있습니다. 어떤 버전이 다른 기능을 도입하는지 기억할 수 없습니다.


문제는 텍스처에서 GL_DEPTH_STENCIL 컴포넌트를 캡처하지 않지만, 그렇게 할 때마다 FBO에서 모든 깊이 정보가 손실된다는 사실입니다. FBO는 장면을 드로우 버퍼로 렌더링하는 데 쓸모 없게됩니다. 따라서이 문제를 우회하기 위해 렌더 버퍼를 사용하고있었습니다. . 지금은 깊이를 잡아 + 개별적으로 정보를 그리는 두 개의 패스를 만들 수있는 옵션 만 = (비싼 것과 같이 지옥 나는 주위에 방법을 찾을 수있을 때까지이 없다에 대한 생각
Rushyo

@Rushyo이 고대 질문에 대한 답변을 게시했습니다.
엔지니어

@NickWiggill 내가 원한다! 무언가를 퍼지하고 내 인생으로 나아 갔다. 이 프로토 타입에서 사용한 자산을 다시 만들 때까지 실제로는 답변을 테스트 할 수 없습니다. 어느 시점에서 그 문제를
해결할 수 있습니다
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.