我想一次渲染大量的点,所以我通过顶点缓冲区对象(VBO)将所有点的数据传递给着色器程序。到目前为止,一切都很好。
缓冲区不仅包含位置信息,还包含一些整数,这些整数应该代表每个点的某些属性。
public struct DataVertex
{
public Vector3 position;
public int tileType;
public int terrainType;
public DataVertex(Vector3 position, int tileType, int terrainType)
{
this.position = position;
this.tileType = tileType;
this.terrainType = terrainType;
}
}
为了测试这一点,我想根据整数改变每个点的颜色。为此,我将整数数据从顶点着色器传递到几何体着色器,最后传递到片段着色器,我要在其中设置颜色。但是如果我想请求碎片着色器中的值(通过if语句),顶点着色器中的制服就消失了(优化了吗?)。问题出在哪里?
顶点明暗器:
# version 450 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in int aTileType;
layout (location = 2) in int aTerrainType;
out DATA
{
int tileType;
int terrainType;
mat4 projection;
} data_out;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = vec4(aPos, 1.0) * model;
data_out.tileType = aTileType;
data_out.terrainType = aTerrainType;
data_out.projection = view * projection;
}
几何体着色器:
# version 450 core
layout (points) in;
layout(points, max_vertices = 1) out;
in DATA
{
int tileType;
int terrainType;
mat4 projection;
} data_in[];
out int oTileType;
out int oTerrainType;
void main()
{
oTileType = data_in[0].tileType;
oTerrainType = data_in[0].terrainType;
gl_Position = gl_in[0].gl_Position * data_in[0].projection;
EmitVertex();
EndPrimitive();
}
片段着色器:
# version 450 core
out vec4 FragColor;
in int oTileType;
in int oTerrainType;
void main()
{
if (oTileType == 0)
FragColor = vec4(0.0f, 0.0f, 1.0f, 1.00f);
else if (oTileType == 1)
FragColor = vec4(0.0f, 1.0f, 0.0f, 1.00f);
else if (oTerrainType == 2)
FragColor = vec4(1.0f, 1.0f, 0.0f, 1.00f);
}
此版本的片段着色器可以工作:
# version 450 core
out vec4 FragColor;
in int oTileType;
in int oTerrainType;
void main()
{
FragColor = vec4(1.0f, 1.0f, 0.0f, 1.00f);
}
无论谁对完整的源代码感兴趣,请查看https://github.com/BanditBloodwyn/SimulateTheWorld
相关的类别包括:
SimulateTheWorld.Graphics.Rendering/Rendering/OpenGLRenderer.cs
SimulateTheWorld.Graphics.Data/OpenGL/ShaderProgram.cs
SimulateTheWorld.Graphics.Resources/Rendering/Shaders/
中的“点”着色器SimulateTheWorld.Graphics.Data.Components.PointCloud.cs
1条答案
按热度按时间n6lpvg4x1#
该程序是否已编译或链接?在GLSL 320 ES中,传递没有
flat
限定符的整型数据类型是错误的(编译或链接错误),因为整数不能内插。我认为这就是查询制服时失败的原因,因为着色器甚至没有链接。
错误代码为:
S0055:整型的Vertex输出必须声明为Flat
S0056:整型的片段输入必须声明为平面
但我在OpenGL和GLSL(核心)文档中没有找到任何与此问题相关的内容。