GLSL:修改片段着色器时制服消失
GLSL: Uniforms disappear when modifying the fragment shader
我想一次渲染大量点,所以我通过顶点缓冲对象 (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
程序是否已经过编译或 linked?在 GLSL 320 es
在没有 flat
限定符的情况下传递整数数据类型是一个错误(编译或 link 错误),因为无法对整数进行插值。我认为这就是为什么当您查询制服时会失败,因为着色器甚至还没有 linked。
错误代码是:
S0055: Vertex output with integral type must be declared as flat
S0056: Fragment input with integral type must be declared as flat
但我没有在 OpenGL 和 GLSL(核心)文档中找到任何与此问题相关的内容
我想一次渲染大量点,所以我通过顶点缓冲对象 (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
程序是否已经过编译或 linked?在 GLSL 320 es
在没有 flat
限定符的情况下传递整数数据类型是一个错误(编译或 link 错误),因为无法对整数进行插值。我认为这就是为什么当您查询制服时会失败,因为着色器甚至还没有 linked。
错误代码是:
S0055: Vertex output with integral type must be declared as flat
S0056: Fragment input with integral type must be declared as flat
但我没有在 OpenGL 和 GLSL(核心)文档中找到任何与此问题相关的内容