GLSL 将 uint 转换为 float 以获取颜色

Posted

技术标签:

【中文标题】GLSL 将 uint 转换为 float 以获取颜色【英文标题】:GLSL converting uint to float for color 【发布时间】:2018-09-25 04:45:18 【问题描述】:

对于我的程序,我想将数据作为无符号字节传递到顶点着色器,然后将字节转换为浮点值(介于 0.0 和 1.0 之间)以在顶点着色器中使用如下所示的颜色:

#version 330 core
layout (location = 0) in uvec3 aPos;
layout (location = 1) in uvec4 aColor;

out VS_OUT 
    vec4 color;
 vs_out;

void main()

    vs_out.color = vec4(float(aColor.r) / 255.0f, float(aColor.g) / 255.0f, float(aColor.b) / 255.0f, 1.0f); //alpha set to 1 temporarily
    gl_Position = vec4(aPos, 1.0);

但是,无论我如何执行构造函数或操作,当输入的字节值是 0 以外的任何值(零导致 0.0)时,它似乎总是会转换为 1.0。如何解决此问题,以便获得介于 0.0 和 1.0 之间的正确颜色值? (或者这是 openGL 3.3 的一个错误?)

传入数据的代码:

unsigned char test[] = 
        0, 0, 0, 255, 1, 10, 255, 0, 255 //first 3 is position and next 4 is color but still outputs white
    ;
    unsigned int VBO, VAO;
    glGenBuffers(1, &VBO);
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(test), &test, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_UNSIGNED_BYTE, GL_FALSE, 9*sizeof(byte), 0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_FALSE, 9 * sizeof(byte), (void*)(3 * sizeof(BYTE)));
    glBindVertexArray(0);
...
// draw points
        ourShader.use();// use pre-defined shaders
        glBindVertexArray(VAO);
        glDrawArrays(GL_POINTS, 0, 1);

【问题讨论】:

向着色器发送顶点数据的代码在哪里? 代码现在在问题中。谢谢你,尼科尔。 【参考方案1】:

我想通了。我可以将 in 值作为 vec4 而不是 uvec4 放入着色器中,并将顶点属性设置为规范化,程序将自动转换它:

顶点着色器:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec4 aColor;

out VS_OUT 
    vec4 color;
 vs_out;

void main()

    vs_out.color = aColor;
    gl_Position = vec4(aPos, 1.0); 

程序代码:

byte test[] = //unsigned char
        0, 0, 0, 25, 100, 136, 255, 0, 255 // ouputs teal color (index 3-6)
    ;
...

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, (9 * sizeof(byte)), (void*)(3 * sizeof(BYTE)));

【讨论】:

【参考方案2】:

如果您想在着色器中读取整数,请使用 glVertexAttribIPointer 而不是 glVertexAttribPointer(注意“I”)

顺便说一句,您的缓冲区有 9 个值,但当前只使用了 7 个。如果您打算交错更多值(pos、color、pos、color 等),请查看“stride”参数;它应该是 7 而不是 9。好吧,我认为您不想浪费 2 x numOfVert 未使用的字节来保持 stride=9。

【讨论】:

感谢您的提示,但就我的研究而言,无论如何他们都应该做同样的事情。我也打算稍后使用这些值,但我还没有实现它们。

以上是关于GLSL 将 uint 转换为 float 以获取颜色的主要内容,如果未能解决你的问题,请参考以下文章

Swift:如何将Bytes转换为float /获得更精确的数字?

在 GoLang 中将字节切片“[]uint8”转换为 float64

将 float64 类型的 np.array 转换为 uint8 类型的缩放值

unsigned int 向量的差异,解释为有符号并转换为未正确呈现的浮点向量

将 uint 属性传递给 GLSL

无法获取在GLSL 1.5中工作的整数顶点属性