簡體   English   中英

glsl fragmenthader渲染objectID

[英]glsl fragmentshader render objectID

如何將對象的整數ID正確呈現為整數紋理緩沖區?

假設我有一個帶有內部格式GL_LUMINANCE16的texture2D,我將它作為顏色附件附加到我的FBO。

渲染對象時,我將整數ID傳遞給着色器,並希望將此id渲染為整數紋理。

片段着色器輸出的類型為vec4。 如何正確地將我的ID轉換為四個組件浮點數並避免轉換不准確,以便最終整數紋理目標中的整數值對應於我想要渲染的整數ID?

我仍然認為這里沒有明確的答案。 所以這就是我通過2D紋理使其工作的方式:

// First, create a frame buffer:
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

// Then generate your texture and define an unsigned int array:
glGenTextures(1, &textureid);
glBindTexture(GL_TEXTURE_2D, textureid);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, w, h, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

// Attach it to the frame buffer object:
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, textureid, 0);

// Before rendering    
glBindFramebuffer(GL_FRAMEBUFFER, fbo);    
GLuint buffers[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; // this assumes that there is another     texture that is for the render buffer. Color attachment1 is preserved for the element ids.
glDrawBuffers(2, buffers);

// Clear and render here
glFlush(); // Flush after just in case
glBindFramebuffer(GL_FRAMEBUFFER, 0);

在GLSL端,片段着色器應具有(此處為4.3核心配置文件代碼):

layout(location = 0) out vec4 colorOut; // The first element in 'buffers' so location 0    
layout(location = 1) out uvec4 elementID; // The second element in 'buffers' so location 1. unsigned int vector as color

// ...
void main()
{
//...

elementID = uvec4( elementid, 0, 0, 0 ); // Write the element id as integer to the red channel.

}

您可以在主機端讀取值:

unsigned int* ids = new unsigned int[ w*h ];
glBindTexture(GL_TEXTURE_2D, textureid);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, ids);

你的問題有幾個問題。

首先, GL_LUMINANCE16 不是 “整數紋理”。 它是一個包含規范化無符號整數值的紋理。 它使用整數來表示范圍[0,1]上的浮點數。 如果要存儲實際整數,則必須使用實際的整數圖像格式

其次,你無法渲染到亮度紋理; 它們不是顏色可渲染的格式。 如果您確實要渲染到單通道紋理,則必須創建單通道圖像格式。 因此,而不是GL_LUMINANCE16 ,您使用GL_R16UI ,這是一個16位單通道無符號整數圖像格式。

現在你已經正確設置了它,這非常簡單。 定義uint片段着色器輸出並讓片段着色器將uint值寫入其中。 這個uint可能來自頂點着色器或來自制服; 但是你想要這樣做。

顯然你還需要將你的紋理或渲染緩沖器附加到FBO,但我很確定你知道這一點。

最后一件事:不要使用短語“紋理緩沖區”,除非你的意思是其中之一 否則,它會讓人感到困惑。

我想你的整數ID是一組基元的標識符; 實際上它可以定義為着色器制服:

uniform int vertedObjectId;

渲染后,您希望將片段處理存儲為整數紋理 請注意,整數紋理應使用整數采樣器( isampler2D )進行采樣, 整數采樣器返回整數向量(即ivec3 )。

此紋理可以附加到幀緩沖對象(請注意幀緩沖完整性 )。 幀緩沖附件可以綁定到整數輸出變量:

out int fragmentObjectId;

void main() {
    fragmentObjectId = vertedObjectId;
}

您需要一些擴展支持,或高級OpenGL版本(3.2?)。

暫無
暫無

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

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