005.テクスチャ付き四角形の描画(Dx11版)

 このサンプルはSimplSample005というディレクトリに含まれます。
 BaseCrossDx11.slnというソリューションを開くとDx11版が起動します。

 実行結果は以下のような画面が出ます。

 

図0005a

 


 動画は以下になります。

 

 

【共通解説】

 Dx12、Dx11両方に共通なのはシェーダーです。DxSharedプロジェクト内にシェーダファイルというフィルタがあり、そこに記述されてます。
 今回使用するシェーダは頂点シェーダとピクセルシェーダです。VertexPositionTexture型の頂点を持ち、コンスタントバッファからの入力で、位置を変更させています。
 またテクスチャも描画します。以下が頂点シェーダです。DxSharedフォルダVSPTSprite.hlslに記述されています。
#include "INCStructs.hlsli"

cbuffer ConstantBuffer : register(b0)
{
    row_major float4x4 MatrixTransform : packoffset(c0);
    float4 Emissive : packoffset(c4);
    float4 Diffuse : packoffset(c5);
};


PSPTInput main(VSPTInput input)
{
    PSPTInput result;

    result.position = mul(input.position, MatrixTransform);
    result.tex = input.tex;

    return result;
}
 ここではテクスチャを使用するために、テクスチャのUV値が、C++側から渡されますので、それを、ピクセルシェーダに渡します。赤くなっているところがその処理です。
 以下がピクセルシェーダです。PSPTSprite.hlslに記述があります。
#include "INCStructs.hlsli"

cbuffer ConstantBuffer : register(b0)
{
    row_major float4x4 MatrixTransform : packoffset(c0);
    float4 Emissive : packoffset(c4);
    float4 Diffuse : packoffset(c5);
};


Texture2D g_texture : register(t0);
SamplerState g_sampler : register(s0);


float4 main(PSPTInput input) : SV_TARGET
{
    //テクスチャとディフューズからライティングを作成
    float4 Light = g_texture.Sample(g_sampler, input.tex) * saturate(Diffuse);
    //エミッシブを足す
    return saturate(Light + Emissive);
}
 ここではテクスチャそのものサンプラーを使用します。それぞれ、C++側では、シェーダリソースビューの設定とサンプラーの設定でシェーダに渡されます。
 頂点シェーダから渡されたテクスチャUV値をもとに、サンプラーでサンプリングをしています。(赤くなっているところです)。テクスチャUV値頂点シェーダの時点jでは頂点単位ですが、ピクセルシェーダに来た時点でピクセル単位になっています。
 色要素についてはディフューズエミッシブがあります。
 これらの色のパラメータを、どのように料理するかは、シェーダを記述するプログラマにゆだねられるわけですが、一般的には、ディフューズは掛け算、エミッシブは足し算というのが基本なのではと思います。これが3D表現になった場合、3Dのライティングがなされますので、もっと複雑になっていきます。

【Dx11版解説】

 BaseCrossDx11.slnを開くと、BaseCrossDx11というメインプロジェクトがあります。この中のCharacter.h/cppが主な記述個所になります。

■初期化■

 Dx11版の初期化はSquareSprite::OnCreate()関数に記述があります。ここではVertexPositionTexture型のメッシュリソースとテクスチャリソースを作成し、スケーリングなど各パラメータを初期化して終了です。

■更新処理■

 更新処理はSquareSprite::OnUpdate()に記述があります。回転しながら移動するを実装しています。

■描画処理■

 以下が描画処理です。今回のサンプルで特徴的な、テクスチャ、サンプラー、ブレンドステート(透明処理)などが赤くなっています。
void SquareSprite::OnDraw() {
    auto Dev = App::GetApp()->GetDeviceResources();
    auto pD3D11DeviceContext = Dev->GetD3DDeviceContext();
    auto RenderState = Dev->GetRenderState();

    //中略

    //ブレンドステート
    if (m_Trace) {
        //透明処理
        pD3D11DeviceContext->OMSetBlendState(RenderState->GetAlphaBlendEx(), nullptr, 0xffffffff);
    }
    else {
        //透明処理しない
        pD3D11DeviceContext->OMSetBlendState(RenderState->GetOpaque(), nullptr, 0xffffffff);
    }
    //デプスステンシルステート
    pD3D11DeviceContext->OMSetDepthStencilState(RenderState->GetDepthNone(), 0);
    //ラスタライザステート
    pD3D11DeviceContext->RSSetState(RenderState->GetCullBack());

    //テクスチャとサンプラーの設定
    pD3D11DeviceContext->PSSetShaderResources(0, 1, 
        m_TextureResource->GetShaderResourceView().GetAddressOf());
    ID3D11SamplerState* pSampler = RenderState->GetLinearClamp();
    pD3D11DeviceContext->PSSetSamplers(0, 1, &pSampler);

    //描画
    pD3D11DeviceContext->DrawIndexed(m_SquareMesh->GetNumIndicis(), 0, 0);
    //後始末
    Dev->InitializeStates();

}