InputLayout, который связывает атрибуты вершины с постоянным значением? - PullRequest
0 голосов
/ 16 мая 2018

Я пытаюсь перенести некоторый код из 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 для обработки таких случаев?

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

В Direct3D нет эквивалента - способ решить эту проблему - создать несколько шейдерных объектов и использовать каждый шейдерный объект вместе с соответствующим входным макетом для рендеринга объектов в вашей сцене.

Обратите внимание, однако, что приведенное выше относится к шейдерным объектам , а не к шейдерным источникам. Поскольку шейдерный компилятор D3D существует полностью отдельно от графического драйвера, вы можете использовать препроцессор HLSL для изменения источника шейдера и скомпилировать шейдер как два разных объекта шейдера. Кроме того, входной макет применяется только к вершинному шейдеру, поэтому, если оба ваших вершинных шейдера выводят одну и ту же информацию, ваш следующий шейдер (оболочка, геометрия или пиксель) может оставаться неизменным при изменении вершинного шейдера.

0 голосов
/ 16 мая 2018

Рассмотрите возможность использования директивы препроцессора # if в шейдерах. Этот подход не исключает проблему наличия дополнительных шейдерных объектов. Тем не менее, это облегчает обслуживание кода, избегая копирования и вставки кода.

Пример:

struct VertexInputType
{
    float4 inPosition : POSITION;
#ifdef USE_COLOR
    float4 inColor : COLOR;
#endif
};

#ifndef USE_COLOR
static const float4 inColor = { 1.0, 0.0f, 0.0f, 1.0f };
#endif
...