使用GLSL渲染立方体,使用纯白色材质,使用网格作为参考地板。出于某种原因,有时(约10次),立方体的透明度约为50%。我最初认为它是深度缓冲区问题(例如禁用深度缓冲区),但我找不到任何关于它的信息。代码中只有一个位置触及深度缓冲区,并且它正在初始化它。 我甚至强迫GLSL着色器为Alpha设置固定值1,但仍然没有。
以下是我用来说明问题的截图:
以下是着色器代码:
Lighting.vs
#version 300 es
in vec3 VertexPosition;
uniform mat4 MVP;
in vec2 TexCoord;
out vec2 TexCoord0;
void main()
{
gl_Position = MVP * vec4(VertexPosition, 1.0);
TexCoord0 = TexCoord;
}
Lighting.fs
#version 300 es
precision lowp float;
in vec2 TexCoord0;
out vec4 FragColor;
uniform sampler2D TextureSampler;
uniform struct
{
bool Textured;
bool Litable;
}Flags;
uniform struct
{
vec4 Diffuse;
}Material;
uniform struct
{
vec3 Color;
float Intensity;
}AmbientLight;
vec4 ApplyTexturing ( vec4 Input )
{
Input *= texture(TextureSampler, TexCoord0);
return Input;
}
vec4 ApplyLighting ( vec4 Input )
{
Input *= vec4(AmbientLight.Color * AmbientLight.Intensity, 1.0f );
return Input;
}
void main()
{
vec4 TempFragColor = vec4 ( Material.Diffuse.xyz, 1.0f );
if ( Flags.Textured )
TempFragColor = ApplyTexturing( TempFragColor );
if ( Flags.Litable )
TempFragColor = ApplyLighting ( TempFragColor );
FragColor = vec4(TempFragColor.xyz, 1.0f);
}
这是代码中唯一接触深度缓冲区的地方:
glEnable ( GL_CULL_FACE );
glCullFace ( GL_BACK );
glFrontFace ( GL_CCW );
glEnable ( GL_DEPTH_TEST );
glDepthMask ( GL_TRUE );
glDepthFunc ( GL_LEQUAL );
glDepthRange ( 1, 100 );
现在,正如我写的那样,我想知道我是否应该使用glClearDepth()来设置默认值?我假设驱动程序会使用一个不错的默认值,所以我没有指定。
编辑:好的,所以我改变了代码以使用glClearDepth。没变。但这绝对看起来像透明度问题。看看这个镜头,带有纹理立方体。
bool CGLWindow::StartFrame ( void )
{
glfwMakeContextCurrent ( MyGLFWWindow );
glfwPollEvents();
glEnable ( GL_CULL_FACE );
glCullFace ( GL_BACK );
glFrontFace ( GL_CCW );
glEnable ( GL_DEPTH_TEST );
glDepthMask ( GL_TRUE );
glDepthFunc ( GL_LEQUAL );
glDepthRange ( 1, 100 );
glClearColor ( 0, 0, 0, 1.0f );
glClearDepth ( 1.0f );
Clear();
glfwGetCursorPos ( MyGLFWWindow, & ( MouseCursor.CursorPos.X ), & ( MouseCursor.CursorPos.Y ) );
return glfwWindowShouldClose ( MyGLFWWindow );
}
bool CGLWindow::Clear ( void )
{
glViewport ( 0, 0, Size.X, Size.Y );
glScissor ( 0, 0, Size.X, Size.Y );
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
return glCheckError();
}
编辑: 好的,有些突破。 我切换到一个简单的片段着色器:
#version 300 es
precision lowp float;
out vec4 FragColor;
in vec4 Color;
void main()
{
FragColor.r = FragColor.g = FragColor.b = FragColor.a = 1.0f;
}
这不是确定性的,但就像我说的,每隔一段时间,我就会得到一个透明的立方体。现在,它停止了这样做。现在一切都好。
所以,我开始减少片段着色器。这是我得到的最小值,因为它没有透明的立方体。
#version 300 es
precision lowp float;
in vec2 TexCoord0;
out vec4 FragColor;
uniform sampler2D TextureSampler;
uniform struct
{
vec4 Diffuse;
}Material;
void main()
{
vec4 TempFragColor = vec4 ( Material.Diffuse.xyz, 1.0f );
FragColor = vec4(TempFragColor.xyz, 1.0f);
}
我可能在这里做错了什么? 它似乎绝对是着色器。
答案 0 :(得分:4)
您的设置不会为您提供功能深度缓冲区。问题在于这个电话:
glDepthRange ( 1, 100 );
深度缓冲区的范围为0.0到1.0。这些值确定从NDC(标准化设备坐标)到深度缓冲区范围的映射。默认值对应于:
glDepthRange(0.0, 1.0);
表示NDC中的深度范围(从-1.0到1.0)映射到整个可用深度缓冲区范围。 glDepthRange()
只能减少 NDC范围映射到的深度值范围。您无法将深度缓冲区的范围扩展到其默认的完整范围之外。
因此,glDepthRange()
的两个参数都需要介于0.0和1.0之间。指定此范围之外的值不是错误。这些值被限制,如规范中所定义:
参数n和f被钳制到[0,1]范围,夹钳或夹钳类型的所有参数也是如此。
第二个参数100
被限制,您的通话相当于:
glDepthRange(1.0, 1.0);
这意味着所有内容都映射到深度值1.0,这就像没有深度缓冲区一样。
除非您有充分的理由要求不同的价值观,否则您很少需要致电glDepthRange()
。默认值适用于最常见的用例。
根据您使用的值,您可能希望它们是世界/眼睛坐标的深度范围。但是该范围由投影变换的近和远参数定义,其涉及将[近,远]范围映射到[-1,1] NDC范围。我们在这里使用glDepthRange()
参数查看的内容会在管道中稍后发生。