shaderdirectx-11vertex-attributes

InputLayout which binds vertex attributes to a constant value?


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):

Is there any other solution? What is the best practice in DirectX to handle such cases?


Solution

  • There is no equivalent in Direct3D - the way to solve the issue is to create multiple shader objects, and use each shader object, along with its associated input layout, to render the objects in your scene.

    Note, however, that the above refers to shader objects, not shader sources. Since the D3D shader compiler exists wholly separate from the graphics driver, you can use the HLSL preprocessor to change the shader source, and compile the shader as two different shader objects. In addition, the input layout only applies to the vertex shader, so if both your vertex shaders output the same information, your next shader (hull, geometry, or pixel) can remain the same while the vertex shader changes.