【发布时间】:2017-08-01 14:44:02
【问题描述】:
Mesh(vertexBuffer和indexBuffer):
几个 2D 三角形相互重叠。每个顶点的顶点颜色为R:1, G:0, B:0, A:0.005(透明红色)。 三角形组合成一个网格。
渲染代码:(C#代码,其他语言应该一样)
GL.Enable(GL.GL_BLEND);
GL.BlendEquation(GL.GL_FUNC_ADD_EXT);
GL.BlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
GL.Disable(GL.GL_CULL_FACE);
GL.Disable(GL.GL_DEPTH_TEST);
GL.Disable(GL.GL_ALPHA_TEST);
GL.DepthFunc(GL.GL_NEVER);
GL.Enable(GL.GL_SCISSOR_TEST);
GL.ClearColor(1, 1, 1, 1);
GL.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
GL.Viewport(0, 0, width, height);
GLM.mat4 ortho_projection = GLM.glm.ortho(0.0f, width, height, 0.0f, -5.0f, 5.0f);
material.program.Bind();
material.program.SetUniformMatrix4("ProjMtx", ortho_projection.to_array());
GL.BindVertexArray(material.vaoHandle);
GL.BindBuffer(GL.GL_ARRAY_BUFFER, material.VboHandle);
GL.BufferData(GL.GL_ARRAY_BUFFER, vertexBuffer.Count*sizeof_Vertex, vertexBuffer.Pointer, GL.GL_STREAM_DRAW);
GL.BindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, material.elementsHandle);
GL.BufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indexBuffer.Count *sizeof_Index, indexBuffer.Pointer, GL.GL_STREAM_DRAW);
GL.DrawElements(GL.GL_TRIANGLES, elemCount, GL.GL_UNSIGNED_INT, IntPtr.Zero);
顶点着色器
#version 330
uniform mat4 ProjMtx;
in vec2 Position;
in vec2 UV;
in vec4 Color;
out vec2 Frag_UV;
out vec4 Frag_Color;
void main()
{
Frag_UV = UV;
Frag_Color = Color;
gl_Position = ProjMtx * vec4(Position.xy,0,1);
}
片段着色器
#version 330
in vec2 Frag_UV;
in vec4 Frag_Color;
out vec4 Out_Color;
void main()
{
Out_Color = Frag_Color;
}
我以为重叠的三角形会这样渲染:
但实际渲染结果是:
每次绘制和SwapBuffer调用后,渲染多边形的红色值越来越强。
为什么?那些透明的三角形不应该只混合一次吗?我的意思是,随着时间的推移,渲染的结果应该是静态的,而不是动画的。
请注意,我希望将重叠的像素渲染为更强烈的红色。但我不希望整个网格(重叠的三角形)逐帧呈现更红的颜色。由于当前绑定的帧缓冲区被清除,那么混合工作正常,渲染结果不应该是越来越红的IMO。
【问题讨论】:
-
我正在研究一个可重现的示例,请稍等。
-
我刚刚用 C++ 重写了一个最小的测试示例,但是它(奇怪的动画)没有发生......我现在正在检查 C# 代码。
-
我认为这是一个可能的原因。当我从中删除
glClear调用时,C++ 程序的行为与 C# 程序相同。我正在检查 C# 代码。它不会调用SwapBuffers两次,我也不会使用额外的帧缓冲区。 -
(赏金将奖励给Rabbid76的答案。)为什么要投反对票?
标签: opengl alphablending blending