Тип GLSL uint_fast64_t

Как я могу получить входные данные для вершинного шейдера типа 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 но та же проблема

Glsl без расширений не имеет 64-битных целочисленных типов.

BDL 19.11.2022 00:43

Вы пробовали заменить uint_fast64_t на ivec2 или ivec4?

DraganS 19.11.2022 01:00

Кстати, вам действительно не следует использовать uint_fast64_t. Просто используйте uint64_t, как и все остальные. Количество реализаций, которые на самом деле используют другой тип для них, практически отсутствует.

Nicol Bolas 19.11.2022 03:00
Как настроить Tailwind CSS с React.js и Next.js?
Как настроить Tailwind CSS с React.js и Next.js?
Tailwind CSS - единственный фреймворк, который, как я убедился, масштабируется в больших командах. Он легко настраивается, адаптируется к любому...
LeetCode запись решения 2536. Увеличение подматриц на единицу
LeetCode запись решения 2536. Увеличение подматриц на единицу
Увеличение подматриц на единицу - LeetCode
Переключение светлых/темных тем
Переключение светлых/темных тем
В Microsoft Training - Guided Project - Build a simple website with web pages, CSS files and JavaScript files, мы объясняем, как CSS можно...
Отношения "многие ко многим" в Laravel с методами присоединения и отсоединения
Отношения "многие ко многим" в Laravel с методами присоединения и отсоединения
Отношения "многие ко многим" в Laravel могут быть немного сложными, но с помощью Eloquent ORM и его моделей мы можем сделать это с легкостью. В этой...
В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Карта дорог Беладжар PHP Laravel
Карта дорог Беладжар PHP Laravel
Laravel - это PHP-фреймворк, разработанный для облегчения разработки веб-приложений. Laravel предоставляет различные функции, упрощающие разработку...
0
3
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Unextended GLSL для OpenGL не имеет возможности напрямую использовать 64-битные целочисленные значения. И даже довольно широко поддерживаемое расширение ARB , которое позволяет использовать 64-битные целые числа в шейдерах, на самом деле не позволяет использовать их в качестве атрибутов вершинного шейдера. Для этого требуется расширение NVIDIA, поддерживаемое только... NVIDIA.

Однако вы можете отправлять 32-битные целые числа, а 64-битное целое число — это всего лишь два 32-битных целых числа. Вы можете поместить 64-битные целые числа в буфер и передать их как 2 32-битных целых числа без знака в формате атрибута вашей вершины:

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

Ваш шейдер получит их в качестве ввода uvec2:

layout(location = 0) in uvec2 vertexPosition_modelspace;

Компонент x вектора будет иметь первые 4 байта, а компонент y будет хранить вторые 4 байта. Но поскольку «первый» и «второй» определяются порядком байтов вашего ЦП, вам нужно знать, является ли ваш ЦП прямым порядком байтов или обратным порядком байтов, чтобы иметь возможность их использовать. Поскольку большинство настольных реализаций GL работают в паре с процессорами с прямым порядком байтов, мы предполагаем, что это так.

В этом случае vertexPosition_modelspace.x содержит младшие 4 байта 64-битного целого числа, а 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;

  ...
}

Uvec2 по умолчанию имеет плоскую заливку?

user253751 21.11.2022 18:20

@ user253751: Это не по теме, поскольку квалификаторы интерполяции не применяются к входным переменным вершинного шейдера. Но целые (и двойные) типы по умолчанию не имеют значения flat. Но они также не могут использовать ничего, кроме flat. Поэтому, если вы не укажете на них flat явно, вы получите ошибку компиляции.

Nicol Bolas 21.11.2022 19:16

Другие вопросы по теме