OpenGL GLSL 将颜色作为整数发送到着色器以分解为 vec4 RGBA
OpenGL GLSL Send color as integer to shader to be decomposed as vec4 RGBA
我可以将颜色作为 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 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' 的所有零。不知道怎么了。
我发现的最接近的东西:https://www.opengl.org/discussion_boards/showthread.php/198690-I-cannot-send-RGBA-color-as-unsigned-int .
同样在 VertexAttribIPointer 中,我将 0 作为一个跨步传递,因为我确实有 VertexBufferArray 并保持数据分离。因此,每个顶点的颜色都紧密打包为 32 位(每种颜色)。
当着色器中的输入是浮点数 (vec4) 时,您必须使用 VertexAttribPointer 而不是 VertexAttribIPointer。
将归一化参数设置为GL_TRUE。
规格说明:
glVertexAttribPointer, if normalized is set to GL_TRUE, it indicates that values stored in an integer format are to be mapped to the range [-1,1] (for signed values) or [0,1] (for unsigned values) when they are accessed and converted to floating point. Otherwise, values will be converted to floats directly without normalization.
好吧,这对我有用:
将托管数据作为 int[]
,其中它是紧密排列的数组 只有颜色 (其中 int
格式为:RGBA
意思是 0xAABBGGRR
),然后将顶点属性定义为:GL.VertexAttribPointer(index, 4, VertexAttribPointerType.UnsignedByte, true, sizeof(int), IntPtr.Zero)
并在着色器中将其用作:in vec4 in_color;
.
我可以将颜色作为 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 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' 的所有零。不知道怎么了。
我发现的最接近的东西:https://www.opengl.org/discussion_boards/showthread.php/198690-I-cannot-send-RGBA-color-as-unsigned-int .
同样在 VertexAttribIPointer 中,我将 0 作为一个跨步传递,因为我确实有 VertexBufferArray 并保持数据分离。因此,每个顶点的颜色都紧密打包为 32 位(每种颜色)。
当着色器中的输入是浮点数 (vec4) 时,您必须使用 VertexAttribPointer 而不是 VertexAttribIPointer。
将归一化参数设置为GL_TRUE。
规格说明:
glVertexAttribPointer, if normalized is set to GL_TRUE, it indicates that values stored in an integer format are to be mapped to the range [-1,1] (for signed values) or [0,1] (for unsigned values) when they are accessed and converted to floating point. Otherwise, values will be converted to floats directly without normalization.
好吧,这对我有用:
将托管数据作为 int[]
,其中它是紧密排列的数组 只有颜色 (其中 int
格式为:RGBA
意思是 0xAABBGGRR
),然后将顶点属性定义为:GL.VertexAttribPointer(index, 4, VertexAttribPointerType.UnsignedByte, true, sizeof(int), IntPtr.Zero)
并在着色器中将其用作:in vec4 in_color;
.