I'm trying to port some code from OpenGL to DirectX - in OpenGL it is possible to disable a certain vertex attribute and set it to a constant value.
const GLfloat data[] = { 1.0f, 0.0f, 0.0f, 1.0f };
GLuint location = glGetAttribLocation(program, name);
glDisableVertexAttribArray(location);
glVertexAttrib4fv(location, data);
This is pretty useful, i.e. if the shader expects a vertex attribute for the color I can just pass a constant value this way instead of putting the same color duplicated per vertex in the vertexbuffer.
In DirectX one needs to create a ID3D11InputLayout
which matches to the shader, like:
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);
But if the InputLayout does not cover all the vertex attributes which the shader expects there will be a runtime exception.
Basically I want to leave out a certain vertex attribute in the input layout and set the attribute value in the shader to a constant value. I can only see the following solutions currently (each with big drawbacks):
- create separate shaders for i.e. constant color (coming from a constant buffer/uniform instead of an attribute) → but this will result in additional shader objects & additional shader code to maintain
- duplicating same color vertex attribute for every vertex → but this will waste a lot of memory
Is there any other solution? What is the best practice in DirectX to handle such cases?