我有以下GLSL顶点着色器:
attribute vec3 a_vTangent;
attribute vec3 a_vBinormal;
attribute vec2 a_vCustomParams;
varying vec3 i_vTangent;
varying vec3 i_vBinormal;
varying vec4 i_vColor;
varying vec2 i_vCustomParams;
void main()
{
i_vTangent = a_vTangent;
i_vBinormal = a_vBinormal;
i_vColor = gl_Color;
//i_vCustomParams = a_vCustomParams;
gl_Position = gl_Vertex;
}
如果我取消注释行i_vCustomParams = a_vCustomParams;
,则不再使用此着色器渲染的任何内容,没有GL错误,没有着色器编译或链接错误。这让我感到惊讶,因为几何着色器甚至还没有使用i_vCustomParams,而且,其他两个顶点属性(a_vTangent
和a_vBinormal
)工作得很好。
我知道这是正确的,但无论如何都提供了我的顶点设置
layout = new VertexLayout(new VertexElement[]
{
new VertexPosition(VertexPointerType.Short, 3),
new VertexAttribute(VertexAttribPointerType.UnsignedByte, 2, 3), //2 elements, location 3
new VertexColor(ColorPointerType.UnsignedByte, 4),
new VertexAttribute(VertexAttribPointerType.Byte, 4, 1), //4 elements location 1
new VertexAttribute(VertexAttribPointerType.Byte, 4, 2), //4 elements, location 2
});
这个顶点结构:
struct CubeVertex : IVertex
{
public ushort3 Position;
public byte2 Custom;
public byte4 Color;
public sbyte4 Tangent;
public sbyte4 Binormal;
}
为什么会发生这种情况?
答案 0 :(得分:4)
取消注释线时,顶点着色器开始认为需要自定义属性(因为它的输出取决于此属性),因此着色器程序将此属性视为已使用。因此,这可能会将输入属性的赋值更改为索引(如果您不是通过调用glBindAttribLocation强制它)。因此,您最终将数据传递到不正确的属性槽中,从而导致无用(或空)输出。
解决方案: 在传递数据之前,强制链接程序之前的属性位置或查询GL以获取自动分配的位置。