我正在编写一个小型 3D 应用程序,我想用彩色边缘突出显示选定的对象。我使用 FBO 将正常场景渲染成两种颜色的附件。第一个仅包含正常颜色输出,第二个存储场景中所有可见对象的拾取 ID(颜色拾取)。
现在我想将这两个纹理传递到我的片段着色器中,如果这个片段位于当前对象的边缘,则输出第一个纹理的正常颜色值或黄色。这就是我的着色器相关部分的样子:
uniform sampler2D picking_texture;
uniform sampler2D color_texture;
uniform float pickingID;
uniform float width;
uniform float height;
...
// texture coordinate delta
float dxtex = 1.0 / width; // texture width
float dytex = 1.0 / height; // texture height
// compare neighboring texels in the picking texture (edge detection)
float nLeft = texture2D(picking_texture, gl_TexCoord[1].st + vec2(-dxtex, 0.0)).r;
float nRight = texture2D(picking_texture, gl_TexCoord[1].st + vec2( dxtex, 0.0)).r;
float nTop = texture2D(picking_texture, gl_TexCoord[1].st + vec2( 0.0, dytex)).r;
float nBottom = texture2D(picking_texture, gl_TexCoord[1].st + vec2( 0.0,-dytex)).r;
float sum = nLeft+nRight+nTop+nBottom;
if(sum != 4.0 * pickingID)
{
finalColor = vec4(1.0, 1.0, 0.0, 0.0);
}
在我看来,这应该可行,但有两个问题:
- ID 为 0 的对象照常着色
- 其他所有东西都是完全黄色的
到目前为止,我认为 sum 始终为 0,这样所有 pickID 高于 0 的对象都被染成黄色。但这意味着pickup_texture 中的查找总是返回0。所以我的纹理(绑定、texCoords 等)可能有问题,但我不知道是什么。color_texture 按预期工作。
这就是我在程序的 CPU 部分所做的:
链接和绑定着色器后:
// set locations of the textures
texture_location0 = glGetUniformLocation(shaderProgram->programId(), "color_texture");
glUniform1i(texture_location0, 0);
texture_location1 = glGetUniformLocation(shaderProgram->programId(), "picking_texture");
glUniform1i(texture_location1, 1);
绘制场景之前:
// set textures
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, colorTex);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, pickingTex);
任何想法?