Texture Cube

キューブにテクスチャ座標を追加します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. Normal Cone では、頂点座標と法線ベクトルのコーンを描画しました。
    Windows8 の CreateCube() で生成したモデルは「頂点座標+法線ベクトル+テクスチャ座標」で構成されています。
    (DirectX9 では「頂点座標+法線ベクトル」で構成されていました。)
    ここでは Windows 8.1 3Dプロジェクト の 3D(XAML 無し)をベースにテクスチャ座標を設定してみましょう。
    2D描画機能は不要なので 空プロジェクト を参考にして削除して下さい。
    この状態でコンパイルして、頂点に色を設定した立方体が回転しながら描画されることを確認して下さい。
  2. Content\ShaderStructures.h を頂点データの形式に合わせて修正します。
    テクスチャ座標(tex)は、X座標とY座標で定義します。
        struct VertexPosition
        {
            DirectX::XMFLOAT3 pos;  // position
            DirectX::XMFLOAT3 norm; // surface normal vector
            DirectX::XMFLOAT2 tex;  // texture coordinate
        };
    
  3. Content\Sample3DSceneRenderer.cpp を「頂点+法線+テクスチャ」に合わせて修正して下さい。
    VertexPositionColor ⇒ VertexPosition に修正します。
    color ⇒ norm に修正します。
  4. 頂点データの形式定義を修正します。
        const D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
        {
            { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
            { "NORMAL",   0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
            { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,    0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        };
    
  5. 頂点座標と法線ベクトルとテクスチャ座標を定義します。
    立方体(6面)をそれぞれ4個の座標で定義します。
    頂点の数は8個ですが、法線ベクトルが異なるので、24個になります。
        static const VertexPosition cubeVertices[] = 
        {
            { XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, // +Y (top face)
            { XMFLOAT3( 0.5f, 0.5f, -0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f) },
            { XMFLOAT3( 0.5f, 0.5f,  0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f) },
            { XMFLOAT3(-0.5f, 0.5f,  0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f) },
    
            { XMFLOAT3(-0.5f, -0.5f,  0.5f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, // -Y (bottom face)
            { XMFLOAT3( 0.5f, -0.5f,  0.5f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 0.0f) },
            { XMFLOAT3( 0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT2(1.0f, 1.0f) },
            { XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT2(0.0f, 1.0f) },
    
            { XMFLOAT3(0.5f,  0.5f,  0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, // +X (right face)
            { XMFLOAT3(0.5f,  0.5f, -0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT2(1.0f, 0.0f) },
            { XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT2(1.0f, 1.0f) },
            { XMFLOAT3(0.5f, -0.5f,  0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT2(0.0f, 1.0f) },
    
            { XMFLOAT3(-0.5f,  0.5f, -0.5f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, // -X (left face)
            { XMFLOAT3(-0.5f,  0.5f,  0.5f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT2(1.0f, 0.0f) },
            { XMFLOAT3(-0.5f, -0.5f,  0.5f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT2(1.0f, 1.0f) },
            { XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(-1.0f, 0.0f, 0.0f), XMFLOAT2(0.0f, 1.0f) },
    
            { XMFLOAT3(-0.5f,  0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(0.0f, 0.0f) }, // +Z (front face)
            { XMFLOAT3( 0.5f,  0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 0.0f) },
            { XMFLOAT3( 0.5f, -0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 1.0f) },
            { XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(0.0f, 1.0f) },
    
            { XMFLOAT3( 0.5f,  0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT2(0.0f, 0.0f) }, // -Z (back face)
            { XMFLOAT3(-0.5f,  0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT2(1.0f, 0.0f) },
            { XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT2(1.0f, 1.0f) },
            { XMFLOAT3( 0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, -1.0f), XMFLOAT2(0.0f, 1.0f) },
        };
    
  6. 頂点 Index の定義です。
    立方体(6面)を12個の3角ポリゴンで描画します。
    unsigned short cubeIndices[] = 
    {
        0, 1, 2,      0, 2, 3,
        4, 5, 6,      4, 6, 7,
        8, 9, 10,     8, 10, 11,
        12, 13, 14,   12, 14, 15,
        16, 17, 18,   16, 18, 19,
        20, 21, 22,   20, 22, 23
    };
    
  7. Shader を頂点データの形式に合わせて修正します。
    テクスチャ画像の設定は、結構面倒なので次のページに譲って、今回は「頂点座標+法線」で描画してみます。
    テクスチャ座標を使わない SamplePixelShader.hlsl です。
    struct PixelShaderInput
    {
        float4 pos : SV_POSITION;
        float3 norm : NORMAL;
        float2 tex : TEXCOORD0;
    };
    
    float4 main(PixelShaderInput input) : SV_TARGET
    {
        float3 lightDirection = normalize(float3(1, -1, 0));
        float lightMagnitude = 0.8f * saturate(dot( input.norm, -lightDirection)) + 0.2f;
        return float4(1,1,0.2,1) * lightMagnitude;
    }
    
    テクスチャ座標を使わない SampleVertexShader.hlsl です。
    cbuffer ModelViewProjectionConstantBuffer : register(b0)
    {
        matrix model;
        matrix view;
        matrix projection;
    };
    
    struct VertexShaderInput
    {
        float3 pos : POSITION;
        float3 norm : NORMAL;
        float2 tex : TEXCOORD0;
    };
    
    struct VertexShaderOutput
    {
        float4 pos : SV_POSITION;
        float3 norm : NORMAL;
        float2 tex : TEXCOORD0;
    };
    
    VertexShaderOutput main(VertexShaderInput input)
    {
        VertexShaderOutput output;
        float4 pos = float4(input.pos, 1.0f);
    
        // Transform the vertex position into projected space.
        pos = mul(pos, model);
        pos = mul(pos, view);
        pos = mul(pos, projection);
        output.pos = pos;
        output.tex = input.tex;
    
        float4 norm = float4(normalize(input.norm), 0.0f);
        norm = mul(norm, model);
        output.norm = normalize(norm.xyz);
        return output;
    }
    
  8. コンパイルして実行すると、ページ先頭の画像のように法線ベクトルが設定されたキューブが回転しながら描画されます。
    テクスチャの貼り付けは、この後のページを参照して下さい。

超初心者のプログラム入門(DirectX Store)