Войти
ПрограммированиеФорумГрафика

Как получить данные из OpenGL Compute Shader? (2 стр)

Страницы: 1 2
#15
9:44, 16 июля 2020

nonamezerox
> Потому что наступление момента когда нужно поставить бряку - это для
> коммерческого проекта

расскажи это тем кто не хочет ловить bad_alloc


#16
(Правка: 13:57) 13:56, 1 авг. 2020

подскажите пожалуйста примером кода или ссылкой как в OpenGL ComputeShader загнать не однородный массив int

layout (std430, binding = 0) buffer indices {
    int j[];
} bit_reversed;

а более сложную структуру данных? Например что-то подобное

public struct DensityPrimitive
{
  public int type;
  public int csg;
  public Vector3 position;
  public Vector3 size;
}

наверное как-то как массив байтов? А как тогда в шейдере распарсить такой кусок байтов чтобы было понятно где int'ы, а где float'ы / Vector'ы?

В Unity видел крутую обертку - класс ComputeShader. Там можно просто

PrimMods = new ComputeBuffer(chunk.modCount, (sizeof(int) * 2) + (sizeof(float) * 6)); //set capacity
PrimMods.SetData(chunk.densityPrimitive); //set data DensityPrimitive densityPrimitive

и внутри шейдера юнити мы так и обращаемся к объекту

RWStructuredBuffer<DensityPrimitive> primitiveMods;

не видел ли кто-нибудь где-нибудь похожую обертку для OpenGL? Или может кто-нибудь кинет пару примеров как сделать подобное? Простые мыссивы int[] и float[] я уже научился закидывать в SSBO, теперь хочу понять как такое делать с более сложными типами данных...

#17
(Правка: 15:52) 15:49, 1 авг. 2020
struct Data
{
  float first;
  vec2 second;
};

layout (std430) buffer MyList {
    Data list[];
}
#18
(Правка: 19:56) 19:55, 2 авг. 2020

Большое спасибо! Получилось загонять сложные структуры в буфер (преобразованные в массив байтов) и вычитывать данные обратно из буфера (такой же массив байтов). Но изменение данных в шейдере или вообще не работает или работает по каким-то своим законам.

#version 430 core

layout (local_size_x = 9, local_size_y = 8, local_size_z = 8) in;

struct DensityPrimitive
{
    int type;
    int csg;
    vec3 position;
    vec3 size;
};

layout (std430, binding = 2) buffer primitivesLayout{
    DensityPrimitive element[]; // передается массив из 2-х элементов
};

uniform int N;  // всегда передается 1

void main(void)
{
    element[N].type = 3;
    element[N].csg = 3;
    element[N].position = vec3(0, 0, 0);
    element[N].size = vec3(0, 0, 0);

//    primitives.element[N].type = 3;
//    primitives.element[N].csg = 3;
//    primitives.element[N].position.x = 0;
//    primitives.element[N].position.y = 0;
//    primitives.element[N].position.z = 0;
//    primitives.element[N].size.x = 0;
//    primitives.element[N].size.y = 0;
//    primitives.element[N].size.z = 0;

}

При вычитке из SSBO
    element[N].type = 3;
    element[N].csg = 3;
еще иногда случается, но находится порой не в тех местах. А вот это не происходит никогда:
    element[N].position = vec3(0, 0, 0);
    element[N].size = vec3(0, 0, 0);

Закоментированный текст тоже не работает.

пожалуйста, поясните что не так?
https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf страницу 86 читал, но ничего не понял что нужно сделать чтобы произошло изменение векторов.

Пожалуйста, подскажите пару мыслей или примеров кода которые могли бы навести на разгадку?
В других ветках народ говорит что-то про выравнивание по сетке и про замену vec3 на vec4. Полная картина в голове не складывается.

#19
20:04, 2 авг. 2020

Proton
Может дело в том, что ты пытаешься изменить данные? А где-то стоит флаг только чтение/только запись.

#20
20:17, 2 авг. 2020

Proton
> struct DensityPrimitive
> {
>     int type;
>     int csg;
>     vec3 position;
>     vec3 size;
> };
В примерах опенжл я видал SoA а не AoS, может в этом дело?

#21
(Правка: 21:20) 21:19, 2 авг. 2020

Тогда бы данные вообще не менялись, но они частично меняются.

"В примерах опенжл я видал SoA а не AoS, может в этом дело?"

можно поподробнее что имеется ввиду?
не так
struct DensityPrimitive
{
    int type;
    int csg;
    vec3 position;
    vec3 size;
};

а так?
struct DensityPrimitive
{
    vec3 position;
    vec3 size;
    int type;
    int csg;
};

целых 2 дня застрял на этой ерунде, и так и сяк вертел...

#22
(Правка: 22:30) 22:18, 2 авг. 2020

Proton
SSBO корректно работает, только с выровненными структурами,
другими словами она должна быть вида:

struct Vertex
{
  glm::vec2 pos;
  glm::vec2 texcoord;
};
или
struct Vertex
{
  glm::vec4 pos;
  glm::vec4 normal;
};
Если данные разного типа, то в С++ коде структуру нужно выравнивать (на 16 байт):
struct alignas(16) Vertex
{
  glm::vec4 position;
  glm::vec3 normal;
  glm::vec2 texcoord;
};
#23
22:20, 2 авг. 2020

Funtik
> SSBO корректно работает, только с выровненными структурами,
> другими словами она должна быть вида
А я думал что лейаут пак заставляет видеокарту алигнить как в C++.

#24
(Правка: 22:24) 22:23, 2 авг. 2020

Proton
> можно поподробнее что имеется ввиду?

    element_type[N] = 3;
    element_csg[N] = 3;
    element_position[N] = vec3(0, 0, 0);
    element_size[N] = vec3(0, 0, 0);
https://www.google.com/search?q=AoS+SoA+programming&oq=AoS+SoA+pr… rome&ie=UTF-8
#25
22:35, 2 авг. 2020

samrrr
> А я думал что лейаут пак заставляет видеокарту алигнить как в C++.
Покажи пример, просто я так не делал...

#26
(Правка: 22:51) 22:50, 2 авг. 2020

Funtik
std430 на pack заменяешь и всё. Но я этим не пользуюсь, меня и SoA устраивает.

#27
(Правка: 0:26) 0:25, 3 авг. 2020

Пишут что это косяк разработчиков.
Пишут что не использовать vec3 а использовать только vec4.
https://stackoverflow.com/questions/38172696/should-i-ever-use-a-… rage-buffer-o

в таком вот варианте

struct DensityPrimitive
{
    vec4 position;
    vec4 size;
};
оно уже ведет себя не так похабно.

Страницы: 1 2
ПрограммированиеФорумГрафика