Basic Pipeline

Sahder を使う最小構成。

頂点バッファを省略することができるので2次元の GeometryShader から入る。 空の頂点バッファからダミーの Point Primitive を入力して、GeometryShader で 三角形を出力する。

頂点バッファを省略

何もしない頂点シェーダー。 point DummyInput input[1]: POSITION に対応して D3D11_PRIMITIVE_TOPOLOGY_POINTLIST を使う。

GeometryShader

../../assets/basic.hlsl
 1void vsMain() {}
 2
 3struct DummyInput {};
 4struct GS_OUTPUT {
 5  float4 position : SV_POSITION;
 6  float4 color : COLOR0;
 7};
 8
 9[maxvertexcount(3)] void gsMain(point DummyInput input[1]
10                                : POSITION,
11                                  inout TriangleStream<GS_OUTPUT> output) {
12  GS_OUTPUT element;
13
14  // d3d default. clock wise
15
16  // 0
17  element.position = float4(-1, -1, 0, 1);
18  element.color = float4(1, 0, 0, 1);
19  output.Append(element);
20  // 1
21  element.position = float4(-1, 1, 0, 1);
22  element.color = float4(0, 1, 0, 1);
23  output.Append(element);
24  // 2
25  element.position = float4(1, 1, 0, 1);
26  element.color = float4(0, 0, 1, 1);
27  output.Append(element);
28
29  output.RestartStrip();
30}
31
32float4 psMain(GS_OUTPUT V)
33    : SV_Target {
34  return V.color;
35}

空の頂点シェーダーをキックすることで、間接的に GeometryShader を始動する。

../../lib/gorilla/pipeline.cpp
1void Pipeline::create_cb(ShaderStage &stage, const ComPtr<ID3D11Device> &device,
2                         const ComPtr<ID3DBlob> &compiled) {
3  if (!stage.reflection.reflect(compiled)) {
4    assert(false);

ビューポート座標系

../_images/basic_pipeline.jpg

第1頂点が (-1, -1) かつ赤。 第2頂点が (+1, +1) かつ青。 第3頂点が (-1, +1) かつ緑。

ということから

3(-1, +1) 2(+1, +1)
     +---+
     |   |
     +---+
1(-1, -1)

という座標系であることがわかる。

D3D11_RASTERIZER_DESC::FrontCounterClockwise = true; なので 三角形は反時計回り。

試しに、反対周りにすると裏向きになって見えなくなる( D3D11_CULL_BACK される)。

ID3D11RasterizerState のデフォルト

D3D11_RASTERIZER_DESC::CullMode = D3D11_CULL_BACK;
D3D11_RASTERIZER_DESC::FrontCounterClockwise = false;