c++ GLSL单元_快速64_t类型

x6yk4ghg  于 2022-11-19  发布在  其他
关注(0)|答案(1)|浏览(128)

我如何才能获得类型为uint_fast64_t的顶点着色器的输入?语言中没有此类类型可用,我如何以不同的方式传递它?
我代码是:

#version 330 core

#define CHUNK_SIZE 16

#define BLOCK_SIZE_X 0.1
#define BLOCK_SIZE_Y 0.1
#define BLOCK_SIZE_Z 0.1

// input vertex and UV coordinates, different for all executions of this shader
layout(location = 0) in uint_fast64_t vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;

// Output data ; will be interpolated for each fragment.
out vec2 UV;

// model view projection matrix 
uniform mat4 MVP;

int getAxis(uint_fast64_t p, int choice) { // axis: 0=x 1=y 2=z 3=index_x 4=index_z
    switch (choice) {
    case 0:
        return (int)((p>>59 ) & 0xF); //extract the x axis int but i only want 4bits
    case 1:
        return (int)((p>>23 ) & 0xFF);//extract the y axis int but i only want 8bits
    case 2:
        return (int)((p>>55 ) & 0xF);//extract the z axis int but i only want 4bits
    case 3:
        return (int)(p & 0x807FFFFF);//extract the index_x 24bits
    case 4:
        return (int)((p>>32) & 0x807FFFFF);//extract the index_z 24bits
    }
}

void main()
{
    // assign vertex position
    float x = (getAxis(vertexPosition_modelspace,0) + getAxis(vertexPosition_modelspace,3)*CHUNK_SIZE)*BLOCK_SIZE_X;
    float y = getAxis(vertexPosition_modelspace,1)*BLOCK_SIZE_Y;
    float z = (getAxis(vertexPosition_modelspace,2) + getAxis(vertexPosition_modelspace,3)*CHUNK_SIZE)*BLOCK_SIZE_Z;

    gl_Position = MVP * vec4(x,y,z, 1.0);

    // UV of the vertex. No special space for this one.
    UV = vertexUV;
}

我得到的错误消息是:

我尝试放置uint64_t,但同样的问题

kknvjkwl

kknvjkwl1#

OpenGL的未扩展GLSL不能直接使用64位整数值。即使the fairly widely supported ARB extension允许在着色器中使用64位整数,也不能将其用作顶点着色器属性。这需要an NVIDIA extension supported only by... NVIDIA
但是,您可以发送32位整数,而一个64位整数只是两个32位整数。您可以将64位整数放入缓冲区,并以顶点属性格式将其作为两个32位无符号整数传递:

glVertexAttribIFormat(0, 2, GL_UNSIGNED_INT, <byte_offset>);

着色器将它们作为uvec2输入进行检索:

layout(location = 0) in uvec2 vertexPosition_modelspace;

向量的x分量将存储前4个字节,y分量将存储后4个字节。但由于“first”和“second”由CPU的字节序决定,因此您需要知道CPU是little endian还是big endian才能使用它们。由于大多数桌面GL实现都与little endian CPU配对,因此我们假设是这种情况。
在这种情况下,vertexPosition_modelspace.x包含64位整数的低4字节,vertexPosition_modelspace.y包含高4字节。
因此,您的代码可以按如下方式进行调整(进行一些清理):

const vec3 BLOCK_SIZE(0.1, 0.1, 0.1);

//Get the three axes all at once.
uvec3 getAxes(in uvec2 p)
{
  return uvec3(
    (p.y >> 27) & 0xF),
    (p.x >> 23) & 0xFF),
    (p.y >> 23) & 0xF)
  );
}

//Get the indices
uvec2 getIndices(in uvec2 p)
{
  return p & 0x807FFFFF; //Performs component-wise bitwise &
}

void main()
{
  uvec3 iPos = getAxes(vertexPosition_modelspace);
  uvec2 indices = getIndices(vertexPosition_modelspace);

  vec3 pos = vec3(
    iPos.x + (indices.x * CHUNK_SIZE),
    iPos.y,
    iPos.z + (indices.x * CHUNK_SIZE) //You used index 3 in your code, so I used .x here, but I think you meant index 4.
  );

  pos *= BLOCK_SIZE;

  ...
}

相关问题