いまさらDirect3D11入門

初めてグラフィックスAPIを触る人に向けて

ラスタライザステート

今パートではピクセルシェーダの前に実行されるラスタライザステージについて見ていきます。

ラスタライザステージでは前のステージで処理された点や三角形などを画面のピクセルに変換するステージになります。 (ちなみにこの事をラスタライズと呼んだりします。)

ドキュメント:
ラスタライザステージ (日本語) (英語)
グラフィック パイプライン (日本語) (英語)

ラスタライザステージはGPU側で処理を行うものになり、その制御はラスタライザステート(ID3D11RasterizerState)で行います。 ラスタライザステートを使うことで三角形の裏面を描画しないようにしたり、ワイヤーフレームだけを描画したりすることができます。 また、ビューポートやシザー矩形などでレンダーターゲットに書き込む範囲も指定することができます。

それではラスタライザステージについて見ていきましょう。

概要

今回はラスタライザステージで出来ることについて順に見ていきます。 対応しているプロジェクトはPart09_RasterizerStateになります。

ラスタライザステート

上でも書きましたが、ラスタライザステートはID3D11RasterizerStateで表現します。

設定

先にGPUへの設定はID3D11DeviceContext::RSSetStateで行います。
ドキュメント:ID3D11DeviceContext::RSSetState (日本語) (英語)

// Scene::onRender関数の一部
this->mpImmediateContext->RSSetState(this->mpRSScissor.Get());

作成

作成はID3D11Device::CreateRasterizerStateで行います。
ドキュメント:ID3D11DeviceContext::CreateRasterizerState (日本語) (英語)

// Scene::onInit関数の一部
//様々なラスタライザステートを作成している
//三角形の裏面をカリングするように指定したステート
D3D11_RASTERIZER_DESC desc = {};
desc.CullMode = D3D11_CULL_BACK;
desc.FillMode = D3D11_FILL_SOLID;
desc.FrontCounterClockwise = true;
desc.ScissorEnable = false;
desc.MultisampleEnable = false;
auto hr = this->mpDevice->CreateRasterizerState(&desc, this->mpRSCulling.GetAddressOf());
if (FAILED(hr)) {
  throw std::runtime_error("カリング用のラスタライザーステートの作成に失敗");
}
//三角形をワイヤフレームで描画するよう指定したステート
desc.FillMode = D3D11_FILL_WIREFRAME;
hr = this->mpDevice->CreateRasterizerState(&desc, this->mpRSFill.GetAddressOf());
if (FAILED(hr)) {
  throw std::runtime_error("カリング用のラスタライザーステートの作成に失敗");
}
//シザー矩形を使用するよう指定したステート
desc.CullMode = D3D11_CULL_NONE;
desc.FillMode = D3D11_FILL_SOLID;
desc.ScissorEnable = true;
hr = this->mpDevice->CreateRasterizerState(&desc, this->mpRSScissor.GetAddressOf());
if (FAILED(hr)) {
  throw std::runtime_error("シザー矩形用のラスタライザーステートの作成に失敗");
}

D3D11_RASTERIZER_DESCでラスタライザステートの内容決めます。各メンバの意味は以下のとおりです。
ドキュメント:D3D11_RASTERIZER_DESC (日本語) (英語)

D3D11_RASTERIZER_DESC

  • FillMode

    三角形描画時の描画モードを指定するものになります。 指定にはD3D11_FILL_MODEを使用します。
    ドキュメント:D3D11_FILL_MODE (日本語) (英語)

  • CullMode

    描画しない三角形の面の向きを指定します。 三角形の面向きにより描画するかしないかを決めることをカリング(英訳:Culling)と呼びます。 三角形の面向きは構成する頂点が時計回りか反時計回りかで決まります。 それだけだと表裏は決まりませんが、下のFrontCounterClockwiseを使用することで決定します。 指定にはD3D11_CULL_MODEを使用します。
    ドキュメント:D3D11_CULL_MODE (日本語) (英語)

  • FrontCounterClockwise

    三角形を構成する頂点が反時計回りの場合に表面とみなすかどうかを表すフラグになります。 trueなら反時計回りを表面に、falseなら時計回りを表面にします。

  • DepthBias, DepthBiasClamp, SlopeScaledDepthBias

    深度バイアスを計算するときに使用する値になります。 度バイアスは同じ深度値があった場合の優先順位をつけるためのものになります。 詳細はドキュメントを御覧ください。
    ドキュメント:深度バイアス(英訳:Depth Bias) (日本語) (英語)

  • DepthClipEnable

    距離によるクリッピングを行うかのフラグになります。

  • ScissorEnable

    シザー矩形カリングを行うかのフラグになります。 シザー矩形については下の方で説明します。

  • MultisampleEnable

    マルチサンプリングアンチエイリアス(略称:MSAA)のレンダーターゲットを使用している時、四辺形ラインアンチエイリアス(英訳:quadrilateral line anti-aliasing algorithm)を行うか、アルファラインアンチエイリアス(英訳:alpha line anti-aliasing algorithm)を行うかを決めるフラグになります。 tureで四辺形ラインアンチエイリアスをfalseでアルファラインアンチエイリアスを使用します。 MSAAを使用するにはリソース生成時にDX11_SAMPLE_DESC::Countを1より上の値を設定する必要があります。

  • AntialiasedLineEnable

    MSAAのレンダーターゲットを使用している時、線分描画でMultisampleEnableがfalseのとき、アンチエイリアスを有効にします。

ビューポート

ビューポートはレンダーターゲットのどの範囲を使用するかを決めるものです。

ビューポートを設定する際は特別なものを作成する必要はありません。 D3D11_VIEWPORTを1つか複数用意し、ID3D11DeviceContext::RSSetViewportsで設定します。


ドキュメント:
ID3D11DeviceContext::RSSetViewports (日本語) (英語)
D3D11_VIEWPORT (日本語) (英語)

// Scene::onRender関数の一部
//ビューポートの設定
//この設定だとレンダーターゲットの左上から、縦横半分の領域を使用する
D3D11_VIEWPORT vp;
vp.Width = static_cast<float>(this->width() / 2);
vp.Height = static_cast<float>(this->height() / 2);
vp.TopLeftX = 0;
vp.TopLeftY = 0;
vp.MinDepth = 0.f;
vp.MaxDepth = 1.f;
this->mpImmediateContext->RSSetViewports(1, &vp);

シザー矩形

シザー矩形はビューポートと似ていますが、こちらは描画領域を指定するものになります。 シザー矩形の範囲外に描画されるピクセルはカリングされます。 そのためゲームにおけるGUIの表示などで使われているみたいです。 使用する際はラスタライザステートにて有効にする必要があるので注意してください。

シザー矩形はレンダーターゲットの範囲内になるよう指定する必要があり、またビューポートとは独立しています。

シザー矩形も設定する際は特別なものを作成する必要はありません。 D3D11_RECTを1つか複数用意し、ID3D11DeviceContext::RSSetScissorRectsで設定します。
ドキュメント:
ID3D11DeviceContext::RSSetScissorRects (日本語) (英語)
D3D11_RECT (日本語) (英語)

// Scene::onRender関数の一部
//シザー矩形の設定
//この設定だとレンダーターゲットの左上から、縦横半分の領域を使用する
//レンダーターゲットの範囲から見た領域になり、ビューポートは関係ないので注意
UINT count = 1;
D3D11_RECT rect;
rect.left = static_cast<LONG>(this->width() / 4.f);
rect.right= static_cast<LONG>(this->width() * 3.f / 4.f);
rect.top = static_cast<LONG>(this->height() / 4.f);
rect.bottom = static_cast<LONG>(this->height() * 3.f / 4.f);
this->mpImmediateContext->RSSetScissorRects(count, &rect);

まとめ

今回はラスタライザステージについて見てきました。 このステージは三角形など形状データからピクセルデータへ変換を行うものになります。 またGPUの固定機能となります。

余分な三角形の描画を防ぐためのカリングや手軽にワイヤーフレームを描画できたりしますし、 Zバッファの値を調節することもできるなどちょっとした小技がこのステージでできますので頭の片隅にでも覚えておくといいかもしれません。

<前 トップ 次>