OpenGL GLSL将颜色作为整数发送到着色器,以将其分解为vec4 RGBA
我可以将颜色作为4个浮点数发送到着色器-没问题。然而,我想将其作为整数(或无符号整数,并不重要,重要的是32位)发送,并在着色器上的vec4中分解 我使用OpenTK作为OpenGL的C#包装器(尽管它应该只是一个直接包装器)OpenGL GLSL将颜色作为整数发送到着色器,以将其分解为vec4 RGBA,opengl,glsl,vertex-buffer,vertex-attributes,Opengl,Glsl,Vertex Buffer,Vertex Attributes,我可以将颜色作为4个浮点数发送到着色器-没问题。然而,我想将其作为整数(或无符号整数,并不重要,重要的是32位)发送,并在着色器上的vec4中分解 我使用OpenTK作为OpenGL的C#包装器(尽管它应该只是一个直接包装器) 让我们考虑一个包含顶点位置(XYZ)和颜色(RGBA)的最简单的着色器。 顶点着色器: #version 150 core in vec3 in_position; in vec4 in_color; out vec4 pass_color; uniform mat4
让我们考虑一个包含顶点位置(XYZ)和颜色(RGBA)的最简单的着色器。
顶点着色器:#version 150 core
in vec3 in_position;
in vec4 in_color;
out vec4 pass_color;
uniform mat4 u_WorldViewProj;
void main()
{
gl_Position = vec4(in_position, 1.0f) * u_WorldViewProj;
pass_color = in_color;
}
片段着色器:
#version 150 core
in vec4 pass_color;
out vec4 out_color;
void main()
{
out_color = pass_color;
}
让我们创建顶点缓冲区:
public static int CreateVertexBufferColor(int attributeIndex, int[] rawData)
{
var bufferIndex = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ArrayBuffer, bufferIndex);
GL.BufferData(BufferTarget.ArrayBuffer, sizeof(int) * rawData.Length, rawData, BufferUsageHint.StaticDraw);
GL.VertexAttribIPointer(attributeIndex, 4, VertexAttribIntegerType.UnsignedByte, 0, rawData);
GL.EnableVertexAttribArray(attributeIndex);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
return bufferIndex;
}
我在顶点着色器中得到vec4“in_color”的所有零。不知道怎么了
最接近我发现的东西:
同样在VertexAttributePointer中,我将0作为一个跨步传递,因为我有VertexBufferArray并保持数据分离。因此,每个顶点的颜色紧密地压缩为32位(每种颜色)。当着色器中的输入为浮动(vec4)时,必须使用VertexAttribute指针,而不是VertexAttribute指针 将规格化参数设置为GL_TRUE 说明书上说: glVertexAttribPointer,如果将“规格化”设置为GL_TRUE,则表示以整数格式存储的值在被访问并转换为浮点时将映射到范围[-1,1](对于有符号值)或[0,1](对于无符号值)。否则,值将直接转换为浮点值,而不进行规范化
唉,这就是我的工作:
将数据管理为
int[]
,其中数据是仅颜色的紧凑数组(其中int
格式为:RGBA
意思是0xAABBGGRR
),然后将顶点属性定义为:GL.vertexattributepointer(索引,4,vertexattributepointertype.UnsignedByte,true,sizeof(int),IntPtr.Zero)
并在着色器中使用它作为:在vec4中以_颜色使用代码>这是GLSL而不是HLSL。对于整型数据类型,类型必须是ivec4
。我认为整型属性不是您想要的。您只需要UNORM,因此在vec4中结合使用glvertexattributepointer
。不glvertexattributepointer
。这样做似乎合乎逻辑,但这不起作用:GL.vertexattributepointer(attributeIndex,4,vertexattributepointerType.UnsignedByte,true,0,rawData)代码>(rawData
是int[]
其中整数包含4个通道RGBA或ARGB或任意通道的所有32位)。我仍然在顶点着色器中得到vec4(0,0,0,0),有什么想法吗?如果您试图将所有4个通道打包成一个整数,则需要设置GL.VertexAttributeInter(attributeIndex,1,VertexAttributeIntegerType.UnsignedByte,0,rawData)代码>并在着色器中仅接收单个uint而不是vec4。然后您可以使用vec4解包unpunorm4x8(uint p)从uint解包到vec4代码>。还要确保它是uint而不是int.Aight,所以我的着色器看起来像这样:\version 400 core in vec3 in\u位置;以彩色显示;输出vec4通过颜色;统一mat4 u__WorldViewProj;void main()代码>您提到了“VertexAttributeIntegerType.UnsignedByte”,我认为它应该是“unsignedIt”,但是它们都不起作用,我在着色器中仍然得到零。是的,应该是unsignedIt。您是否检查了rawData是否确实包含任何值?您确定attributeIndex是正确的吗?您可以尝试使用:GL.vertexattributeinter(1,1,vertexattributeintegertype.UnsignedInt,0,rawData)对其进行明确设置代码>和uint中的着色器布局(位置=1)中的颜色代码>。rawData是int还是uint?应该是uint,我还是被卡住了。根本无法让它发挥作用。但是,如果我只构建一个顶点缓冲区,将所有属性按步长顺序放置(而不是为属性构建不同的缓冲区),则效果很好:例如,将位置设置为3个浮点,将颜色设置为int:GL.VertexAttributePointer(Shader.in_position,3,VertexAttributePointerType.Float,false,vertexSize,IntPtr.Zero)代码>+GL.VertexAttribute指针(Shader.in_color,4,VertexAttribute指针类型.UnsignedByte,true,vertexSize,新IntPtr(12))代码>