Пытаюсь портировать какой-то код из OpenGL в DirectX - в OpenGL можно отключить определенный атрибут вершины и установить для него постоянное значение.
const GLfloat data[] = { 1.0f, 0.0f, 0.0f, 1.0f };
GLuint location = glGetAttribLocation(program, name);
glDisableVertexAttribArray(location);
glVertexAttrib4fv(location, data);
Это довольно полезно, т. е. если шейдер ожидает атрибут вершины для цвета, я могу просто передать постоянное значение таким образом вместо того, чтобы дублировать один и тот же цвет для каждой вершины в вершинном буфере.
В DirectX нужно создать ID3D11InputLayout
, соответствующий шейдеру, например:
ID3D11InputLayout* layout = nullptr;
D3D11_INPUT_ELEMENT_DESC ied[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
device->CreateInputLayout(ied, 2, vertexShader.data(), vertexShader.size(), &layout);
Но если InputLayout не покрывает все атрибуты вершин, ожидаемые шейдером, возникнет исключение во время выполнения.
По сути, я хочу исключить определенный атрибут вершины во входном макете и установить значение атрибута в шейдере на постоянное значение. В настоящее время я вижу только следующие решения (каждое из которых имеет большие недостатки):
- создавать отдельные шейдеры, например, для постоянного цвета (исходя из постоянного буфера/униформы вместо атрибута) → но это приведет к дополнительным объектам шейдера и дополнительному коду шейдера для поддержки
- дублирование атрибута вершины одного цвета для каждой вершины → но это приведет к потере большого количества памяти
Есть ли другое решение? Какова наилучшая практика в DirectX для обработки таких случаев?