簡體   English   中英

OpenGL/GLSL 4.5 - 在默認 FBO 中使用 MRT

[英]OpenGL/GLSL 4.5 - using MRT in the default FBO

我正在使用 MRT 解決 OpenGL 4.5 中的 3D 揀貨問題。 (參考鏈接: http://ogldev.atspace.co.uk/www/tutorial29/tutorial29.html

根據我在網上查到的資料,我們在使用捷運時一般都會申請一個新的FBO。 如果是這樣,我應該在 3D 拾取期間對場景進行兩次 daw(3D 拾取的新 FBO,以及屏幕的默認 FBO),這將是浪費時間。

所以我想知道MRT是否可以在默認的FBO中使用,但我遇到了一些問題。

這是我的代碼。

// apply the texture buffer attached to GL_COLOR_ATTACHMENT1. (GL_COLOR_ATTACHMENT0 is reserved for the screen ?)
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &m_pickingColorTexture);
glBindTexture(GL_TEXTURE_2D, m_pickingColorTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, w, h, 0, GL_RGB, GL_FLOAT, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_pickingColorTexture, 0);
glDisable(GL_TEXTURE_2D);

// draw code. 
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, buffers);
glDrawElements(........);

// fragment shader, output two kinds of things: frag_color0 for screen display, frag_color1 for 3D picking
 .......
layout (location = 0) out vec4 frag_color0; 
layout (location = 1) out vec4 frag_color1; 
 
void main() {
     frag_color0 = vec4(...);
     frag_color1 = vec4(...);
}

// query the result
glReadBuffer(GL_COLOR_ATTACHMENT1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT, &pixelInfo);

當我最后查詢 GL_COLOR_ATTACHMENT1 時,結果似乎是 frag_color0 而不是 frag_color1。

如果有人可以幫助我解決問題,我將不勝感激,謝謝!

當我最后查詢GL_COLOR_ATTACHMENT1時,結果似乎是frag_color0而不是frag_color1

不,不是,唯一的原因是 FBO 0 沒有GL_COLOR_ATTACHMENT1 ,所以你不能查詢它。 FBO 0 指的是窗口系統提供的幀緩沖區(通過 windows 上的像素格式、X11/Unix 上的視覺或 fbconfig 以及其他特定於平台的方式指定)。

這個幀緩沖區可能有也可能沒有深度緩沖區,可能有也可能沒有模板緩沖區,可能有也可能沒有(舊的,已棄用的)累積緩沖區,並且可能有以下顏色緩沖區

  • GL_BACK_LEFT
  • GL_BACK_RIGHT
  • GL_FRONT_LEFT
  • GL_FRONT_RIGHT

這是你能得到的最多的,只有當你的 GPU 和驅動程序支持 3D 立體渲染的“quadbuffer stereo”模式時。 在典型情況下,您將只有兩個:

  • GL_BACK :繪制新幀的緩沖區
  • GL_FRONT :當前顯示在屏幕上的緩沖區。

您不能從 GL 中更改任何這些緩沖區配置(您只能在設置連接 GL 上下文的 window 時影響這一點),並且無法將 GL 對象(紋理、渲染緩沖區)與默認幀緩沖區混合

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_pickingColorTexture, 0);

如果在綁定 FBO 0 時調用它,這只會導致 GL 錯誤,否則會被忽略。 這些情況也是如此:

 GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; glDrawBuffers(2, buffers); [...] glReadBuffer(GL_COLOR_ATTACHMENT1);

因此,您要渲染的是 glDrawBuffer 的默認值,在典型情況下為GL_BACK ,您的第二個着色器 output 最終無處可去,而您正在讀回的是glReadBuffer的默認值,這也是GL_BACK在典型情況下。

根據我在網上查到的資料,我們在使用捷運時一般都會申請一個新的FBO。

您在網上查到的信息是正確的。 對於 OpenGL 中的 MRT,您需要設置自定義 FBO,並且不能與 FBO 0 中的緩沖區共享它。(從技術上講,這並不完全正確,您仍然可以使用 FBO 0 設置 MRT,並使用像{GL_FRONT, GL_BACK}或者如果你有一個支持立體聲的 GPU,你甚至可以(錯誤地)使用{GL_BACK_LEFT,GL_BACK_RIGHT} 。但這些的實際用例非常有限)。

如果是這樣,我應該在 3D 拾取期間繪制兩次場景(3D 拾取的新 FBO,以及屏幕的默認 FBO),這將是浪費時間。

不一定是這樣。 您仍然可以使用 MRT 將其渲染到一些自定義 FBO 中,然后只GL_BACK緩沖區

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM