当涉及几何着色器时,是否有关于渲染到 FBO 的特殊规则?
上下文:我正在尝试在场景中实现阴影映射,其中包括以不同方式渲染的不同类型的对象:网格,通过 VBO 和着色器以标准方式渲染 Point sprite 粒子,使用顶点和片段着色器 Quad 粒子渲染,作为点发送,但在几何着色器中扩展为四边形
我正在以标准方式进行阴影映射,这涉及创建深度 FBO 并从灯光的角度向其渲染对象的深度。网格和点精灵工作正常,但几何着色器四边形粒子的深度没有被渲染到 FBO。
这是标准(非 FBO)深度缓冲区。注意前景中的大圆形颗粒。
这是呈现给 FBO 的相同视图。请注意,仅绘制了网格和点精灵粒子的深度。
我的 FBO 设置如下(它基于 OpenGL 4 Shading Language Cookbook 的第 7 章):
const bool Renderer::generateShadowMap(FBO & f, string & error) {
uint depthTexID;
uint width = f.getWidth();
uint height = f.getHeight();
glGenTextures(1, &depthTexID);
glBindTexture(GL_TEXTURE_2D, depthTexID);
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
width, height, 0,
GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
float border[] = {1.0, 0.0, 0.0, 0.0};
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, depthTexID);
uint fID;
glGenFramebuffers(1, &fID);
glBindFramebuffer(GL_FRAMEBUFFER, fID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
depthTexID, 0);
glDrawBuffer(GL_NONE);
if(!checkFBOstatus(error)) {
cerr << error << endl;
return false;
}
glClearDepth(1.0);
glClear(GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glActiveTexture(GL_TEXTURE0);
f.setFBOID(fID);
f.setTexID(depthTexID);
return true;
}
应该渲染四边形粒子深度的着色器是:
//VERTEX SHADER
#version 400
in vec3 aPosition;
in float aSize;
out float gSize;
uniform mat4 vWorldView;
void main() {
gSize = aSize;
vec4 v4Vertex = vec4(aPosition.xyz, 1.0);
vec4 transformedVertex = vWorldView * v4Vertex;
gl_Position = transformedVertex;
}
//GEOMETRY SHADER
#version 400
layout (points) in;
layout (triangle_strip, max_vertices = 4) out;
in float gSize[1];
uniform mat4 vgProjection;
void main() {
vec4 oPosition;
float halfSize = gSize[0] * 0.5;
oPosition = (vec4(-halfSize, -halfSize, 0.0, 0.0) + gl_in[0].gl_Position);
gl_Position = vgProjection * oPosition;
EmitVertex();
oPosition = (vec4(halfSize, -halfSize, 0.0, 0.0) + gl_in[0].gl_Position);
gl_Position = vgProjection * oPosition;
EmitVertex();
oPosition = (vec4(-halfSize, halfSize, 0.0, 0.0) + gl_in[0].gl_Position);
gl_Position = vgProjection * oPosition;
EmitVertex();
oPosition = (vec4(halfSize, halfSize, 0.0, 0.0) + gl_in[0].gl_Position);
gl_Position = vgProjection * oPosition;
EmitVertex();
EndPrimitive();
}
//FRAGMENT SHADER - empty as depth should be written automatically
#version 400
void main() {
}
当然,深度测试是启用的。我已经通过 gDebugger 运行它,它根本无法检测到任何错误。我已经尝试告诉片段着色器实际绘制东西,但这也没有什么区别(没有尝试将不同的值写入 gl_FragDepth)。
点精灵粒子和四边形粒子之间的唯一区别是几何着色器的使用。我正在同时渲染两者并使用相同的统一值(相同的转换矩阵),并且我已经运行 gDebugger 来确保。
我已经在一台装有驱动程序版本 8.17.13.142 的 nVidia GTX 560 Ti 和另一台装有 Radeon Mobility HD 5650 的计算机上对此进行了测试。我在两者上都得到了相同的结果。
我是否犯了任何明显的错误,或者我应该知道一些具体的事情?