当涉及几何着色器时,是否有关于渲染到FBO的特殊规则?
上下文: 我正在尝试在场景中实现阴影贴图,其中包括以不同方式呈现的不同类型的对象: 网格,通过VBO和着色器以标准方式呈现 使用顶点和片段着色器渲染的点精灵粒子 四维粒子,以点的形式发送,但在几何着色器中扩展为四边形
我正在以标准方式进行阴影贴图,这涉及创建深度FBO并从灯光的角度渲染对象的深度。网格和点精灵工作正常,但几何着色器四边形粒子的深度不会渲染到FBO。
Here是标准(非FBO)深度缓冲区。注意前景中的大圆形颗粒。
Here向FBO呈现的视图相同。请注意,仅绘制网格和点精灵粒子的深度。
我的FBO设置如下(它基于OpenGL 4着色语言手册第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运行它,它根本无法检测到任何错误。我已经尝试告诉片段着色器实际绘制的东西,但这也没有区别(noe确实尝试将不同的值写入gl_FragDepth)。
点精灵粒子和四元粒子之间的唯一区别是使用几何着色器。我正在同时渲染两个并使用相同的统一值(相同的转换矩阵),并且我运行gDebugger以确保。
我在带有驱动程序版本8.17.13.142的nVidia GTX 560 Ti计算机上进行了测试(我相信,在撰写本文时是最新版本),另一台使用Radeon Mobility HD 5650进行了测试。我得到了相同的结果在两者上。
我是否犯了任何明显的错误,或者我应该知道一些具体的事情?