我正在调试SSAO的问题,并尝试可视化我的深度缓冲区。结果如下:我将深度和法线存储在单个16位RGBA纹理中。这是我的深度传递着色器:
// Vertex shader
#version 150 core
#extension GL_ARB_explicit_attrib_location : enable
uniform mat4 _ViewMatrix;
uniform mat4 _ViewProjectionMatrix;
uniform mat4 modelMatrix;
layout (location = 0) in vec4 aPosition;
layout (location = 2) in vec3 aNormal;
out vec4 vPosition;
out vec3 vNormal;
void main()
{
gl_Position = _ViewProjectionMatrix * modelMatrix * aPosition;
mat4 modelViewMatrix = _ViewMatrix * modelMatrix;
vPosition = modelViewMatrix * aPosition;
vNormal = mat3( modelViewMatrix ) * aNormal;
}
// Fragment shader.
#version 150 core
// Calculated as 1.0 / (far - near)
uniform float uLinearDepthConstant;
in vec4 vPosition;
in vec3 vNormal;
out vec4 outDepthNormal;
void main()
{
float linearDepth = -vPosition.z * uLinearDepthConstant;
outDepthNormal = vec4( linearDepth, normalize( vNormal ) );
}
然后,我在渲染纹理的着色器中可视化深度(我已经硬编码了近平面和远平面的距离):
void main()
{
float depth = texture( depthNormalMap, vTexCoord ).r;
fragColor = vec4((2.0 * 1.0) / (200.0 + 1.0 - depth * (200.0 - 1.0)));
}
结果看起来应该平滑还是可能是问题所在?我正在创建这样的纹理:
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_HALF_FLOAT, 0 );
如果考虑到没有硬件实际提供16位浮点深度缓冲区的事实,这看起来是正确的。
某些控制台(例如Xbox 360)公开了24位浮点深度缓冲区,但是通常为便携起见,您必须使用32位深度缓冲区才能以浮点表示。如果您需要模板缓冲区和浮点深度缓冲区,则必须使用难看的64位压缩深度+模板格式,这是D3D和Xbox 360上ATI硬件提供24位浮点+的原因的一部分。 8位深度+模板格式,在OpenGL中不可用。如果GL有此名称,则将其称为GL_DEPTH24F_STENCIL8
。
现在,尽管16位浮点值不足以存储您的深度,但可能浪费空间/内存带宽来存储这种格式的法线。您应该尝试使用RGBA 10:10:10:2(定点)或RGB 11:11:10(浮点)之类的格式来存储法线(如果RGBA8实际上不够用),然后使用保存的空间您可以负担得起32位浮点深度缓冲区。
就目前而言,您实际上并没有真正使用浮点深度缓冲区。您正在尝试将深度打包到16位每分量颜色缓冲区的一个通道中。我建议您使用实际的深度附件并使用24位定点或32位深度图像格式(如果您当前的解决方案没有裁剪的话)。无论如何,您已经必须在正常渲染期间将某些内容输出到专用的深度缓冲区。
立即使用浮点格式存储深度,您将失去1位精度,因为它必须存储相当无意义的符号位(定点深度缓冲区不需要)。另外,由于深度值通常已经在0-1的范围内,所以实际上不适用浮点数的增强范围。通过以浮点格式存储深度,在16位时,您损失的比获得的更多。当您使用更少的位存储深度时,定点深度确实是最好的方法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句