レンダリング フレームワーク I: レンダリングの概要Rendering framework I: Intro to rendering

これまでのトピックでは、Windows ランタイムで動作するユニバーサル Windows プラットフォーム (UWP) ゲームを構築する方法、ステート マシンを定義してゲームのフローを処理する方法について説明してきました。We've covered how to structure a Universal Windows Platform (UWP) game and how to define a state machine to handle the flow of the game in the earlier topics. ここでは、レンダリング フレームワークをアセンブルする方法について説明します。Now, it's time to learn how to assemble the rendering framework. サンプル ゲームで Direct3D 11 (通常は DirectX 11 と呼ばれます) を使用して、ゲームのシーンをレンダリングする方法を見てみましょう。Let's look at how the sample game renders the game scene using Direct3D 11 (commonly known as DirectX 11).

注意

このサンプルの最新ゲーム コードをダウンロードしていない場合は、Direct3D ゲーム サンプルのページに移動してください。If you haven't downloaded the latest game code for this sample, go to Direct3D game sample. このサンプルは、UWP 機能のサンプルの大規模なコレクションの一部です。This sample is part of a large collection of UWP feature samples. サンプルをダウンロードする手順については、「GitHub から UWP のサンプルを取得する」をご覧ください。For instructions on how to download the sample, see Get the UWP samples from GitHub.

Direct3D 11 には、ゲームなどのグラフィックス負荷の高いアプリケーションの 3D グラフィックスを作成するために使用できる高パフォーマンスのグラフィックス ハードウェアの高度な機能へのアクセスを提供する API のセットが含まれています。Direct3D 11 contains a set of APIs that provide access to the advanced features of high-performance graphic hardware that can be used to create 3D graphics for graphic intensive applications such as games.

画面上のゲームのグラフィックのレンダリングは、基本的に画面上のフレームのシーケンスのレンダリングです。Rendering game graphics on-screen is basically rendering a sequence of frames on-screen. 各フレームでは、ビューに基づいて、シーンに表示されているオブジェクトをレンダリングする必要があります。In each frame, you have to render objects that are visible in the scene, based on the view.

フレームをレンダリングするには、画面に表示できるように、必要なシーンの情報をハードウェアに渡す必要があります。In order to render a frame, you have to pass the required scene information to the hardware so that it can be displayed on the screen. 何かを画面に表示するには、ゲームの実行を開始すると同時にレンダリングを開始する必要があります。If you want to have anything displayed on screen, you need to start rendering as soon as the game starts running.

目標Objective

基本的なレンダリング フレームワークを設定して、UWP DirectX ゲームのグラフィックス出力を表示する方法は、大きく次の 3 つの手順にグループ分けすることができます。To set up a basic rendering framework to display the graphics output for a UWP DirectX game, you can loosely group them into these three steps.

  1. グラフィックス インターフェイスへの接続を確立するEstablish a connection to the graphics interface
  2. グラフィックスを描画するために必要なリソースを作成するCreate the resources needed to draw the graphics
  3. フレームをレンダリングすることによってグラフィックスを表示するDisplay the graphics by rendering the frame

この記事では、手順 1 と 3 を取り上げて、グラフィックスをレンダリングする方法について説明します。This article explains how graphics are rendered, covering steps 1 and 3.

レンダリング フレームワーク II: ゲームのレンダリング」では手順 2 を取り上げて、レンダリング フレームワークを設定する方法と、レンダリングの前にデータを準備する方法について説明します。Rendering framework II: Game rendering covers step 2; how to set up the rendering framework and how data is prepared before rendering can happen.

概要Get started

作業を開始する前に、基本的なグラフィックスとレンダリングの概念を理解しておく必要があります。Before you begin, you should familiarize yourself with the basic graphics and rendering concepts. Direct3D とレンダリングを使用して初めて開発を行う場合は、この記事で使用するグラフィックスとレンダリング用語の簡単な説明については、「用語と概念」を参照してください。If you're new to Direct3D and rendering, see Terms and concepts for a brief description of the graphics and rendering terms used in this article.

このゲームでは、GameRenderer クラス オブジェクトがこのサンプル ゲームのレンダラーを表します。For this game, the GameRenderer class object represents the renderer for this sample game. レンダラーは、ゲームの視覚効果を生成するために使用する、すべての Direct3D 11 オブジェクトと Direct2D オブジェクトの作成と保持を担当します。It's responsible for creating and maintaining all the Direct3D 11 and Direct2D objects used to generate the game visuals. また、レンダリングするオブジェクトのリストとヘッドアップ ディスプレイ (HUD) 用にゲームの状態を取得するために使用される Simple3DGame オブジェクトへの参照も保持します。It also maintains a reference to the Simple3DGame object used to retrieve the list of objects to render as well as status of the game for the Heads Up Display (HUD).

このチュートリアルでは、ゲームの 3D オブジェクトのレンダリングに重点を置いています。In this part of the tutorial, we'll focus on rendering 3D objects in the game.

グラフィックス インターフェイスへの接続を確立するEstablish a connection to the graphics interface

レンダリング用のハードウェアにアクセスする方法については、UWP フレームワークの記事にある App::Initialize の説明を参照してください。To access to the hardware for rendering, see the UWP framework article under App::Initialize.

make_shared 関数__は (以下に示すように) [__DX::DeviceResources](#dxdeviceresources) への shared_ptr を作成するために使用されます。これもデバイスへのアクセスを提供します。The make_shared function, as shown below, is used to create a shared_ptr to DX::DeviceResources, which also provides access to the device.

Direct3D 11 では、デバイスを使用して、オブジェクトの割り当てと破棄、プリミティブのレンダリング、グラフィックス ドライバー経由のグラフィックス カードとの通信を行います。In Direct3D 11, a device is used to allocate and destroy objects, render primitives, and communicate with the graphics card through the graphics driver.

App::Initialize メソッドApp::Initialize method

void App::Initialize(
    CoreApplicationView^ applicationView
    )
{
    //...

    // At this point we have access to the device. 
    // We can create the device-dependent resources.
    m_deviceResources = std::make_shared<DX::DeviceResources>();
}

フレームをレンダリングすることによってグラフィックスを表示するDisplay the graphics by rendering the frame

ゲームのシーンは、ゲームが起動したときにレンダリングされる必要があります。The game scene needs to render when the game is launched. レンダリングのための手順は、以下に示すように、GameMain::Run メソッド内で始まります。The instructions for rendering start in the GameMain::Run method, as shown below.

単純なフローは次のとおりです。The simple flow is:

  1. UpdateUpdate
  2. RenderRender
  3. PresentPresent

GameMain::Run メソッドGameMain::Run method

// Comparing this to App::Run() in the DirectX 11 App template
void GameMain::Run()
{
    while (!m_windowClosed)
    {
        if (m_visible) // if the window is visible
        {
            // Added: Switching different game states since this game sample is more complex
            switch (m_updateState) 
            {

                // ...
                CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
                // 1. Update
                // Also exist in DirectX 11 App template: Update loop to get the latest game changes
                Update();

                // 2. Render
                // Present also in DirectX 11 App template: Prepare to render
                m_renderer->Render();

                // 3. Present
                // Present also in DirectX 11 App template: Present the 
                // contents of the swap chain to the screen.
                m_deviceResources->Present(); 

                // Added: resetting a variable we've added to indicate that 
                // render has been done and no longer needed to render
                m_renderNeeded = false; 
            }
        }
        else
        {   
            // Present also in DirectX 11 App template
            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending); 
        }
    }
    m_game->OnSuspending();  // exiting due to window close. Make sure to save state.
}

UpdateUpdate

App::Update および GameMain::Update メソッドで、ゲームの状態がどのように更新される化については、「ゲームのフロー管理」の記事を参照してください。See the Game flow management article for more information about how game states are updated in the App::Update and GameMain::Update method.

RenderRender

レンダリングは、GameMain::RunGameRenderer::Render メソッドを呼び出すことによって実装されます。Rendering is implemented by calling the GameRenderer::Render method in GameMain::Run.

ステレオ レンダリング が有効な場合、右目用と左目用の 2 つのレンダリング パスがあります。If stereo rendering is enabled, there are two rendering passes: one for the right eye and one for the left eye. 各レンダリング パスで、レンダー ターゲットと深度ステンシル ビューをデバイスにバインドします。In each rendering pass, we bind the render target and the depth-stencil view to the device. 後で深度ステンシル ビューをクリアします。We also clear the depth-stencil view afterward.

注意

ステレオ レンダリングは、頂点のインスタンス化やジオメトリ シェーダーを使用する単一パス ステレオなど、他の方法で実現することもできます。Stereo rendering can be achieved using other methods such as single pass stereo using vertex instancing or geometry shaders. 2 つのレンダリング パスを使用する方法は時間がかかりますが、ステレオ レンダリングを実現するのに便利な方法です。The two rendering pass method is a slower, but more convenient way to achieve stereo rendering.

ゲームが作成され、リソースが読み込まれたら、レンダリング パスごとに 1 回、射影行列を更新します。Once the game exists and resources are loaded, update the projection matrix, once per rendering pass. オブジェクトは、各ビューで若干異なります。Objects are slightly different from each view. 次に、グラフィックス レンダリング パイプラインを設定します。Next, set up the graphics rendering pipeline.

注意

リソースを読み込む方法については、「DirectX グラフィックス リソースの作成と読み込み」を参照してください。See Create and load DirectX graphic resources for more information on how resources are loaded.

このゲーム サンプルでは、レンダラーは、すべてのオブジェクトについて標準の頂点レイアウトを使用するように設計されています。In this game sample, the renderer is designed to use a standard vertex layout across all objects. これにより、シェーダーの設計が簡素化され、オブジェクトのジオメトリに関係なく、シェーダー間で簡単に切り替えることができます。This simplifies the shader design and allows for easy changes between shaders, independent of the objects' geometry.

GameRenderer::Render メソッドGameRenderer::Render method

入力頂点レイアウトを使用する Direct3D コンテキストを設定します。Set the Direct3D context to use an input vertex layout. 入力レイアウト オブジェクトは、頂点バッファー データをレンダリング パイプラインにストリーミングする方法を記述します。Input-layout objects describe how vertex buffer data is streamed into the rendering pipeline.

次に、以前に定義した定数バッファーを使用する Direct3D コンテキストを設定します。この定数バッファーは、頂点シェーダーのパイプライン ステージとピクセル シェーダーのパイプライン ステージで使用されます。Next, we set the Direct3D context to use the constant buffers defined earlier, that are used by the vertex shader pipeline stage and the pixel shader pipeline stage.

注意

定数バッファーの定義の詳細については、「レンダリング フレームワーク II: ゲームのレンダリング」を参照してください。See Rendering framework II: Game rendering for more information about definition of the constant buffers.

同じ入力レイアウトと一連の定数バッファーが、パイプライン内のすべてのシェーダーで使用されるため、設定はフレームごとに 1 回です。Because the same input layout and set of constant buffers is used for all shaders that are in the pipeline, it's set up once per frame.

void GameRenderer::Render()
{
    bool stereoEnabled = m_deviceResources->GetStereoState();

    auto d3dContext = m_deviceResources->GetD3DDeviceContext();
    auto d2dContext = m_deviceResources->GetD2DDeviceContext();

    int renderingPasses = 1;
    if (stereoEnabled)
    {
        renderingPasses = 2;
    }

    for (int i = 0; i < renderingPasses; i++)
    {
        // Iterate through the number of rendering passes to be completed.
        // 2 rendering passes if stereo is enabled
        if (i > 0)
        {
            // Doing the Right Eye View.
            ID3D11RenderTargetView *const targets[1] = { m_deviceResources->GetBackBufferRenderTargetViewRight() };

            // Resets render targets to the screen.
            // OMSetRenderTargets binds 2 things to the device.
            // 1. Binds one render target atomically to the device.
            // 2. Binds the depth-stencil view, as returned by the GetDepthStencilView method, to the device.
            // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476464.aspx

            d3dContext->OMSetRenderTargets(1, targets, m_deviceResources->GetDepthStencilView());

            // Clears the depth stencil view.
            // A depth stencil view contains the format and buffer to hold depth and stencil info.
            // For more info about depth stencil view, go to: 
            // https://docs.microsoft.com/windows/uwp/graphics-concepts/depth-stencil-view--dsv-
            // A depth buffer is used to store depth information to control which areas of 
            // polygons are rendered rather than hidden from view. To learn more about a depth buffer,
            // go to: https://docs.microsoft.com/windows/uwp/graphics-concepts/depth-buffers
            // A stencil buffer is used to mask pixels in an image, to produce special effects. 
            // The mask determines whether a pixel is drawn or not,
            // by setting the bit to a 1 or 0. To learn more about a stencil buffer,
            // go to: https://docs.microsoft.com/windows/uwp/graphics-concepts/stencil-buffers

            d3dContext->ClearDepthStencilView(m_deviceResources->GetDepthStencilView(), D3D11_CLEAR_DEPTH, 1.0f, 0);

            // d2d -- Discussed later
            d2dContext->SetTarget(m_deviceResources->GetD2DTargetBitmapRight());
        }
        else
        {
            // Doing the Mono or Left Eye View.
            // As compared to the right eye:
            // m_deviceResources->GetBackBufferRenderTargetView instead of GetBackBufferRenderTargetViewRight
            ID3D11RenderTargetView *const targets[1] = { m_deviceResources->GetBackBufferRenderTargetView() }; 

            // Same as the Right Eye View.
            d3dContext->OMSetRenderTargets(1, targets, m_deviceResources->GetDepthStencilView());
            d3dContext->ClearDepthStencilView(m_deviceResources->GetDepthStencilView(), D3D11_CLEAR_DEPTH, 1.0f, 0);

            // d2d -- Discussed later under Adding UI
            d2dContext->SetTarget(m_deviceResources->GetD2DTargetBitmap()); 
        }

        // Render the scene objects
        if (m_game != nullptr && m_gameResourcesLoaded && m_levelResourcesLoaded)
        {
            // This section is only used after the game state has been initialized and all device
            // resources needed for the game have been created and associated with the game objects.
            if (stereoEnabled)
            {
                // When doing stereo, it is necessary to update the projection matrix once per rendering pass.

                auto orientation = m_deviceResources->GetOrientationTransform3D();

                ConstantBufferChangeOnResize changesOnResize;

                // Apply either a left or right eye projection, which is an offset from the middle
                XMStoreFloat4x4(
                    &changesOnResize.projection,
                    XMMatrixMultiply(
                        XMMatrixTranspose(
                            i == 0 ?
                            m_game->GameCamera()->LeftEyeProjection() :
                            m_game->GameCamera()->RightEyeProjection()
                            ),
                        XMMatrixTranspose(XMLoadFloat4x4(&orientation))
                        )
                    );

                d3dContext->UpdateSubresource(
                    m_constantBufferChangeOnResize.Get(),
                    0,
                    nullptr,
                    &changesOnResize,
                    0,
                    0
                    );
            }

            // Update variables that change once per frame.
            ConstantBufferChangesEveryFrame constantBufferChangesEveryFrame;
            XMStoreFloat4x4(
                &constantBufferChangesEveryFrame.view,
                XMMatrixTranspose(m_game->GameCamera()->View())
                );
            d3dContext->UpdateSubresource(
                m_constantBufferChangesEveryFrame.Get(),
                0,
                nullptr,
                &constantBufferChangesEveryFrame,
                0,
                0
                );

            // Setup the graphics pipeline. This sample uses the same InputLayout and set of
            // constant buffers for all shaders, so they only need to be set once per frame.
            // For more info about the graphics or rendering pipeline, 
            // go to https://msdn.microsoft.com/library/windows/desktop/ff476882.aspx

            // IASetInputLayout binds an input-layout object to the input-assembler (IA) stage. 
            // Input-layout objects describe how vertex buffer data is streamed into the IA pipeline stage.
            // Set up the Direct3D context to use this vertex layout.
            // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476454.aspx
            d3dContext->IASetInputLayout(m_vertexLayout.Get());

            // VSSetConstantBuffers sets the constant buffers used by the vertex shader pipeline stage.
            // Set up the Direct3D context to use these constant buffers.
            // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476491.aspx

            d3dContext->VSSetConstantBuffers(0, 1, m_constantBufferNeverChanges.GetAddressOf());
            d3dContext->VSSetConstantBuffers(1, 1, m_constantBufferChangeOnResize.GetAddressOf());
            d3dContext->VSSetConstantBuffers(2, 1, m_constantBufferChangesEveryFrame.GetAddressOf());
            d3dContext->VSSetConstantBuffers(3, 1, m_constantBufferChangesEveryPrim.GetAddressOf());

            // Sets the constant buffers used by the pixel shader pipeline stage. 
            // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476470.aspx

            d3dContext->PSSetConstantBuffers(2, 1, m_constantBufferChangesEveryFrame.GetAddressOf());
            d3dContext->PSSetConstantBuffers(3, 1, m_constantBufferChangesEveryPrim.GetAddressOf());
            d3dContext->PSSetSamplers(0, 1, m_samplerLinear.GetAddressOf());

            auto objects = m_game->RenderObjects();
            for (auto object = objects.begin(); object != objects.end(); object++)
            {
                // The 3D object render method handles the rendering.
                // For more info, see Primitive rendering below.
                (*object)->Render(d3dContext, m_constantBufferChangesEveryPrim.Get()); /
            }
        }
        else
        {
            const float ClearColor[4] = {0.5f, 0.5f, 0.8f, 1.0f};

            // Only need to clear the background when not rendering the full 3D scene since
            // the 3D world is a fully enclosed box and the dynamics prevents the camera from
            // moving outside this space.
            if (i > 0)
            {
                // Doing the Right Eye View.
                d3dContext->ClearRenderTargetView(m_deviceResources->GetBackBufferRenderTargetViewRight(), ClearColor);
            }
            else
            {
                // Doing the Mono or Left Eye View.
                d3dContext->ClearRenderTargetView(m_deviceResources->GetBackBufferRenderTargetView(), ClearColor);
            }
        }

        // Start of 2D rendering
        d3dContext->BeginEventInt(L"D2D BeginDraw", 1);
        d2dContext->BeginDraw();

        // ...
    }
}

プリミティブのレンダリングPrimitive rendering

シーンをレンダリングする場合は、レンダリングする必要があるすべてのオブジェクトをループ処理します。When rendering the scene, you loop through all the objects that need to be rendered. 次の手順は、オブジェクト (プリミティブ) ごとに繰り返されます。The steps below are repeated for each object (primitive).

  • モデルのワールド変換行列とマテリアルの情報を使用して定数バッファー (m_constantBufferChangesEveryPrim) を更新します。Update the constant buffer(m_constantBufferChangesEveryPrim) with the model's world transformation matrix and material information.
  • m_constantBufferChangesEveryPrim には、各オブジェクトのパラメーターが格納されます。The m_constantBufferChangesEveryPrim contains parameters for each object. ワールド変換行列に渡されるオブジェクトや、照明の計算の色と鏡面反射指数などのマテリアルのプロパティが含まれます。It includes the object to world transformation matrix as well as material properties like color and specular exponent for lighting calculations.
  • レンダリング パイプラインの入力アセンブラー (IA) ステージにストリーミングされるメッシュ オブジェクトのデータ用に入力頂点レイアウトを使用する Direct3D コンテキストを設定します。Set Direct3D context to use the input vertex layout for the mesh object data to be streamed into the input-assembler (IA) stage of the rendering pipeline
  • IA ステージでインデックス バッファーを使用する Direct3D コンテキストを設定します。Set Direct3D context to use an index buffer in the IA stage. プリミティブの情報 (型、データの順序) を提供します。Provide the primitive info: type, data order.
  • インデックス付きの、インスタンス化されていないプリミティブを描画する描画呼び出しを送信します。Submit a draw call to draw the indexed, non-instanced primitive. GameObject::Render メソッドは、特定のプリミティブに固有のデータでプリミティブ定数バッファーを更新します。The GameObject::Render method updates the primitive constant buffer with the data specific to a given primitive. これにより、各プリミティブのジオメトリを描画するコンテキストで DrawIndexed 呼び出しが行われます。This results in a DrawIndexed call on the context to draw the geometry of that each primitive. 特に、この描画呼び出しは、定数バッファー データによってパラメーター化されたとおり、コマンドとデータをグラフィックス処理装置 (GPU) のキューに入れます。Specifically, this draw call queues commands and data to the graphics processing unit (GPU), as parameterized by the constant buffer data. 各描画呼び出しは、頂点ごとに 1 回頂点シェーダーを実行し、次にプリミティブの各三角形のピクセルごとに 1 回ピクセル シェーダーを実行します。Each draw call executes the vertex shader one time per vertex, and then the pixel shader one time for every pixel of each triangle in the primitive. テクスチャは、ピクセル シェーダーがレンダリングの実行に使う状態の一部です。The textures are part of the state that the pixel shader uses to do the rendering.

複数の定数バッファーを使用する理由は次のとおりです。Reasons for multiple constant buffers:

  • ゲームでは複数の定数バッファーが使われますが、これらのバッファーはプリミティブごとに 1 回更新するだけで済みます。The game uses multiple constant buffers but only needs to update these buffers one time per primitive. 前述のように、定数バッファーは、プリミティブごとに実行されるシェーダーに対する入力のようなものです。As mentioned earlier, constant buffers are like inputs to the shaders that run for each primitive. 静的なデータ (m_constantBufferNeverChanges) もあれば、カメラの位置のようにフレームで一定のデータ (m_constantBufferChangesEveryFrame) もあれば、色やテクスチャなどのようにプリミティブに固有のデータ (m_constantBufferChangesEveryPrim) もあります。Some data is static (m_constantBufferNeverChanges); some data is constant over the frame (m_constantBufferChangesEveryFrame), like the position of the camera; and some data is specific to the primitive, like its color and textures (m_constantBufferChangesEveryPrim)
  • ゲーム レンダラーはこれらの入力を別個の定数バッファーに分けて、CPU や GPU が使うメモリ帯域幅を最適化します。The game renderer separates these inputs into different constant buffers to optimize the memory bandwidth that the CPU and GPU use. この方法は、GPU が追跡する必要のあるデータ量を最小限に抑えるのにも役立ちます。This approach also helps to minimize the amount of data the GPU needs to keep track of. GPU にはコマンドの大きいキューがあり、ゲームが Draw を呼び出すたびに、そのコマンドは関連するデータと共にキューに入れられます。The GPU has a big queue of commands, and each time the game calls Draw, that command is queued along with the data associated with it. ゲームがプリミティブ定数バッファーを更新して、次の Draw コマンドを発行すると、グラフィックス ドライバーはこの次のコマンドと関連するデータをキューに追加します。When the game updates the primitive constant buffer and issues the next Draw command, the graphics driver adds this next command and the associated data to the queue. ゲームで 100 のプリミティブを描画する場合、キューに定数バッファー データの 100 のコピーが存在する可能性があります。If the game draws 100 primitives, it could potentially have 100 copies of the constant buffer data in the queue. ゲームから GPU に送るデータ量を最小限に抑えるために、ゲームでは、各プリミティブの更新情報のみを含む個別のプリミティブ定数バッファーを使用します。To minimize the amount of data the game is sending to the GPU, the game uses a separate primitive constant buffer that only contains the updates for each primitive.

GameObject::Render メソッドGameObject::Render method

void GameObject::Render(
    _In_ ID3D11DeviceContext *context,
    _In_ ID3D11Buffer *primitiveConstantBuffer
    )
{
    if (!m\_active || (m\_mesh == nullptr) || (m_normalMaterial == nullptr))
    {
        return;
    }

    ConstantBufferChangesEveryPrim constantBuffer;

    // Put the model matrix info into a constant buffer, in world matrix.
    XMStoreFloat4x4(
        &constantBuffer.worldMatrix,
        XMMatrixTranspose(ModelMatrix())
        );

    // Check to see which material to use on the object.
    // If a collision (a hit) is detected, GameObject::Render checks the current context, which 
    // indicates whether the target has been hit by an ammo sphere. If the target has been hit, 
    // this method applies a hit material, which reverses the colors of the rings of the target to 
    // indicate a successful hit to the player. Otherwise, it applies the default material 
    // with the same method. In both cases, it sets the material by calling Material::RenderSetup, 
    // which sets the appropriate constants into the constant buffer. Then, it calls 
    // ID3D11DeviceContext::PSSetShaderResources to set the corresponding texture resource for the 
    // pixel shader, and ID3D11DeviceContext::VSSetShader and ID3D11DeviceContext::PSSetShader 
    // to set the vertex shader and pixel shader objects themselves, respectively.

    if (m_hit && m_hitMaterial != nullptr)
    {
        m_hitMaterial->RenderSetup(context, &constantBuffer);
    }
    else
    {
        m_normalMaterial->RenderSetup(context, &constantBuffer);
    }

    // Update the primitive constant buffer with the object model's info.
    context->UpdateSubresource(primitiveConstantBuffer, 0, nullptr, &constantBuffer, 0, 0);

    // Render the mesh.
    // See MeshObject::Render method below.
    m_mesh->Render(context);
}

#### MeshObject::Render method

void MeshObject::Render(\_In\_ ID3D11DeviceContext *context)
{
    // PNTVertex is a struct. stride provides us the size required for all the mesh data
    // struct PNTVertex
    //{
    //  DirectX::XMFLOAT3 position;
    //  DirectX::XMFLOAT3 normal;
    //  DirectX::XMFLOAT2 textureCoordinate;
    //};
    uint32 stride = sizeof(PNTVertex);
    uint32 offset = 0;

    // Similar to the main render loop.
    // Input-layout objects describe how vertex buffer data is streamed into the IA pipeline stage.
    context->IASetVertexBuffers(0, 1, m_vertexBuffer.GetAddressOf(), &stride, &offset);

    // IASetIndexBuffer binds an index buffer to the input-assembler stage.
    // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476453.aspx
    context->IASetIndexBuffer(m_indexBuffer.Get(), DXGI_FORMAT_R16_UINT, 0);

    // Binds information about the primitive type, and data order that describes input data for the input assembler stage.
    // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476455.aspx
    context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    // Draw indexed, non-instanced primitives. A draw API submits work to the rendering pipeline.
    // For more info, go to: https://msdn.microsoft.com/library/windows/desktop/ff476409.aspx
    context->DrawIndexed(m_indexCount, 0, 0);
}

PresentPresent

DX::DeviceResources::Present メソッドを呼び出して、配置した内容をバッファーに格納し、表示します。We call the DX::DeviceResources::Present method to put the contents we've placed in the buffers and display it.

ユーザーにフレームを表示するために使用されるバッファーのコレクションという意味で、スワップ チェーンという用語を使用します。We use the term swap chain for a collection of buffers that are used for displaying frames to the user. アプリケーションが表示する新しいフレームを提供するたびに、スワップ チェーンの最初のバッファーが、表示されているバッファーの場所を取得します。Each time an application presents a new frame for display, the first buffer in the swap chain takes the place of the displayed buffer. このプロセスは、スワップまたはフリップと呼ばれます。This process is called swapping or flipping. 詳しくは、「スワップ チェーン」をご覧ください。For more information, see Swap chains.

  • IDXGISwapChain1 インターフェイスの Present メソッドは、DXGI に対して垂直同期 (VSync) までブロックするよう指示し、アプリケーションを次の VSync までスリープ状態にします。IDXGISwapChain1 interface's Present method the instructs DXGI to block until Vertical Synchronization (VSync), putting the application to sleep until the next VSync. これによって、画面に表示されないフレームのレンダリングによるサイクルの無駄をなくします。This ensures you don't waste any cycles rendering frames that will never be displayed to the screen.
  • ID3D11DeviceContext3 インターフェイスの DiscardView メソッドは、レンダー ターゲットの内容を破棄します。ID3D11DeviceContext3 interface's DiscardView method discards the contents of the render target. これは、既存の内容が完全に上書きされる場合にのみ有効な操作です。This is a valid operation only when the existing contents will be entirely overwritten. dirty rect や scroll rect を使用する場合は、この呼び出しを削除してください。If dirty or scroll rects are used, this call should be removed.
  • 同じ DiscardView メソッドを使用して、深度/ステンシルの内容を破棄します。Using the same DiscardView method, discard the contents of the depth-stencil.
  • デバイスが削除される場合は、HandleDeviceLost メソッドを使用してシナリオを管理します。HandleDeviceLost method is used to manage the scenario if the device is removed. 切断またはドライバーのアップグレードによってデバイスが削除された場合は、すべてのデバイス リソースを作成し直す必要があります。If the device was removed either by a disconnection or a driver upgrade, you must recreate all device resources. 詳細については、「Direct3D 11 でのデバイス削除シナリオの処理」を参照してください。For more information, see Handle device removed scenarios in Direct3D 11.

ヒント

滑らかなフレーム レートを実現するには、フレームのレンダリングの作業量が、VSync 間の時間に収まることを確認する必要があります。To achieve a smooth frame rate, you must ensure that the amount of work to render a frame fits the time between VSyncs.

// Present the contents of the swap chain to the screen.
void DX::DeviceResources::Present()
{
    // The first argument instructs DXGI to block until VSync, putting the application
    // to sleep until the next VSync. This ensures we don't waste any cycles rendering
    // frames that will never be displayed to the screen.
    HRESULT hr = m_swapChain->Present(1, 0);

    // Discard the contents of the render target.
    // This is a valid operation only when the existing contents will be entirely
    // overwritten. If dirty or scroll rects are used, this call should be removed.
    m_d3dContext->DiscardView(m_d3dRenderTargetView.Get());

    // Discard the contents of the depth-stencil.
    m_d3dContext->DiscardView(m_d3dDepthStencilView.Get());

    // If the device was removed either by a disconnection or a driver upgrade, we 
    // must recreate all device resources.
    // For more info about how to handle a device lost scenario, go to:
    // https://docs.microsoft.com/windows/uwp/gaming/handling-device-lost-scenarios
    if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
    {
        HandleDeviceLost();
    }
    else
    {
        DX::ThrowIfFailed(hr);
    }
}

次の手順Next steps

この記事では、ディスプレイにグラフィックスをレンダリングする方法を説明し、使用されるレンダリング用語の一部について簡単に説明しました。This article explained how graphics is rendered on the display and provided a short description for some of the rendering terms used. レンダリング フレームワーク II: ゲームのレンダリング」では、レンダリングの詳細や、レンダリングする前に必要なデータを準備する方法について説明します。Learn more about rendering in the Rendering framework II: Game rendering article, and learn how to prepare the data needed before rendering.

用語と概念Terms and concepts

シンプルなゲームのシーンSimple game scene

シンプルなゲームのシーンは、数個のオブジェクトといくつかの光源で構成されます。A simple game scene is made up of a few objects with several light sources.

オブジェクトのシェイプは、空間の一連の X、Y、Z 座標で定義されます。An object's shape is defined by a set of X, Y, Z coordinates in space. ゲーム ワールド内の実際のレンダリングの位置は、位置の X、Y、Z 座標に変換行列を適用することで決定できます。The actual render location in the game world can be determined by applying a transformation matrix to the positional X, Y, Z coordinates. 一連のテクスチャ座標 (マテリアルをオブジェクトに適用する方法を指定する U と V) が含まれる場合もあります。It may also have a set of texture coordinates - U and V which specifies how a material is applied to the object. これはオブジェクトのサーフェスのプロパティを定義し、これを使ってオブジェクトがテニス ボールのような粗いサーフェスを持つのか、ボーリングの球のように滑らかな光沢のあるサーフェスを持つのかを確認できます。This defines the surface properties of the object and gives you the ability to see if an object has a rough surface like a tennis ball or a smooth glossy surface like a bowling ball.

シーンとオブジェクトの情報は、レンダリング フレームワークでフレームごとにシーンを再作成し、シーンをディスプレイ モニターに表示するために使用されます。Scene and object info are used by the rendering framework to recreate the scene frame by frame, making it come alive on your display monitor.

レンダリング パイプラインRendering pipeline

レンダリング パイプラインは、3D シーンの情報が画面に表示される画像に変換されるプロセスです。The rendering pipeline is the process in which 3D scene info is translated to an image displayed on screen. Direct3D 11 では、このパイプラインはプログラミング可能です。In Direct3D 11, this pipeline is programmable. レンダリングのニーズをサポートするために、ステージを適合させることができます。You can adapt the stages to support your rendering needs. 一般的なシェーダー コアの機能を利用するステージは、HLSL プログラミング言語を使用することによってプログラミングできます。Stages that feature common shader cores are programmable by using the HLSL programming language. これは、グラフィックス レンダリング パイプラインまたは単にパイプラインとも呼ばれます。It is also known as the graphics rendering pipeline or simply pipeline.

このパイプラインを作成するには、以下についての知識が必要です。To help you create this pipeline, you need to be familiar with:

詳細については、Direct3D 11 のレンダリング パイプラインに関するページグラフィックス パイプラインに関するページを参照してください。For more information, see Understand the Direct3D 11 rendering pipeline and Graphics pipeline.

HLSLHLSL

HLSL は、DirectX 用の上位レベル シェーダー言語です。HLSL is the High Level Shading Language for DirectX. HLSL を使用して、Direct3D パイプライン用の C に似たプログラミング可能なシェーダーを作成できます。Using HLSL, you can create C like programmable shaders for the Direct3D pipeline. 詳しくは、「HLSL」をご覧ください。For more information, see HLSL.

シェーダーShaders

シェーダーは、レンダリングするときのオブジェクトのサーフェスの表示方法を決定する命令のセットと考えることができます。Shaders can be thought of as a set of instructions that determine how the surface of an object appears when rendered. HLSL を使用してプログラミングされるシェーダーは、HLSL シェーダーと呼ばれます。Those that are programmed using HLSL are known as HLSL shaders. [HLSL])(#hlsl) シェーダーのソース コード ファイルには、.hlsl というファイル拡張子が付きます。Source code files for [HLSL])(#hlsl) shaders have .hlsl file extension. これらのシェーダーは、作成時または実行時にコンパイルでき、実行時に適切なパイプライン ステージに設定できます。コンパイルされたシェーダー オブジェクトには、.cso というファイル拡張子が付きます。These shaders can be compiled at author-time or at runtime, and set at runtime into the appropriate pipeline stage; a compiled shader object has a .cso file extension.

Direct3D 9 シェーダーは、シェーダー モデル 1、シェーダー モデル 2、シェーダー モデル 3 を使用して設計できます。Direct3D 10 シェーダーは、シェーダー モデル 4 でのみ設計できます。Direct3D 9 shaders can be designed using shader model 1, shader model 2 and shader model 3; Direct3D 10 shaders can only be designed on shader model 4. Direct3D 11 シェーダーは、シェーダー モデル 5 で設計できます。Direct3D 11 shaders can be designed on shader model 5. Direct3D 11.3 および Direct3D 12 シェーダーは、シェーダー モデル 5.1 で設計できます。Direct3D 12 シェーダーは、シェーダー モデル 6 でも設計できます。Direct3D 11.3 and Direct3D 12 can be designed on shader model 5.1, and Direct3D 12 can also be designed on shader model 6.

頂点シェーダーとピクセル シェーダーVertex shaders and pixel shaders

データは、プリミティブのストリームとしてグラフィックス パイプラインに入り、頂点シェーダーやピクセル シェーダーなどさまざまなシェーダーによって処理されます。Data enters the graphics pipeline as a stream of primitives and is processed by various shaders such as the vertex shaders and pixel shaders.

頂点シェーダーは、通常、変換、スキン、照明の適用などの操作を実行することによって、頂点を処理します。Vertex shaders processes vertices, typically performing operations such as transformations, skinning, and lighting. ピクセル シェーダーは、ピクセル単位の照明や後処理など、豊富なシェーディング手法を実現します。Pixel shaders enables rich shading techniques such as per-pixel lighting and post-processing. ピクセル シェーダーは、定数変数、テクスチャ データ、補間された頂点単位の値などのデータを組み合わせて、ピクセル単位の出力を生成します。It combines constant variables, texture data, interpolated per-vertex values, and other data to produce per-pixel outputs.

シェーダー ステージShader stages

このプリミティブのストリームを処理するために定義されたさまざまなシェーダーのシーケンスは、レンダリング パイプラインのシェーダー ステージと呼ばれます。A sequence of these various shaders defined to process this stream of primitives is known as shader stages in a rendering pipeline. 実際のステージは、Direct3D のバージョンによって異なりますが、通常は、頂点、ジオメトリ、ピクセルのステージが含まれます。The actual stages depend on the version of Direct3D, but usually include the vertex, geometry, and pixel stages. テセレーション用のハル シェーダーやドメイン シェーダー、計算シェーダーなど、他のステージもあります。There are also other stages, such as the hull and domain shaders for tessellation, and the compute shader. これらステージはすべて、[HLSL])(#hlsl) を使用して完全にプログラミングできます。All these stages are completely programmable using the [HLSL])(#hlsl). 詳細については、グラフィックス パイプラインに関するページを参照してください。For more information, see Graphics pipeline.

さまざまなシェーダー ファイル形式Various shader file formats

シェーダー コード ファイルの拡張子は次のとおりです。Shader code file extensions:

  • .hlsl という拡張子を持つファイルは、[HLSL])(#hlsl) ソース コードを保持します。A file with the .hlsl extension holds [HLSL])(#hlsl) source code.
  • .cso という拡張子を持つファイルは、コンパイル済みシェーダー オブジェクトを保持します。A file with the .cso extension holds a compiled shader object.
  • .h という拡張子を持つファイルはヘッダー ファイルですが、シェーダー コードのコンテキストでは、このヘッダー ファイルはシェーダー データを保持するバイト配列を定義します。A file with the .h extension is a header file, but in a shader code context, this header file defines a byte array that holds shader data.
  • .hlsli という拡張子を持つファイルは、定数バッファーの形式を格納します。A file with the .hlsli extension contains the format of the constant buffers. ゲーム サンプルでは、このファイルは Shaders>ConstantBuffers.hlsli です。In the game sample, the file is Shaders>ConstantBuffers.hlsli.

注意

シェーダーを埋め込むには、実行時に .cso ファイルを読み込むか、または実行可能コードに .h ファイルを追加します。You would embed the shader either by loading a .cso file at runtime or adding the .h file in your executable code. ただし、同じシェーダーで両方を使用しないでください。But you would not use both for the same shader.

DirectX に関する高度な知識Deeper understanding of DirectX

Direct3D 11 は、ゲームなどのグラフィックスを多用するアプリケーションのグラフィックスを作成するのに役立つ一連の API です。このようなアプリケーションでは、負荷の高い計算を処理するために優れたグラフィックス カードを使用します。Direct3D 11 is a set of APIs that can help us create graphics for graphics intensive applications like games, where we want to have a good graphics card to process intensive computation. このセクションでは、Direct3D 11 グラフィックス プログラミングの概念 (リソース、サブリソース、デバイス、デバイス コンテキスト) について簡単に説明します。This section briefly explains the Direct3D 11 graphics programming concepts: resource, subresource, device, and device context.

リソースResource

グラフィックス プログラミングに関する経験が浅い場合は、リソース (デバイス リソースとも呼ばれる) は、テクスチャ、位置、色など、オブジェクトをレンダリングする方法に関する情報と考えてもかまいません。For those who are new, you can think of resources (also known as device resources) as info on how to render an object like texture, position, color. リソースは、パイプラインにデータを提供し、シーン内でレンダリングされる対象を定義します。Resources provide data to the pipeline and define what is rendered during your scene. リソースは、ゲーム メディアから読み込むことも、実行時に動的に作成することもできます。Resources can be loaded from your game media or created dynamically at run time.

リソースは、実際には、Direct3D パイプラインからアクセスできるメモリ内の領域です。A resource is, in fact, an area in memory that can be accessed by the Direct3D pipeline. パイプラインでメモリに効率的にアクセスするには、パイプラインに渡すデータ (入力ジオメトリ、シェーダー リソース、テクスチャなど) をリソースに格納する必要があります。In order for the pipeline to access memory efficiently, data that is provided to the pipeline (such as input geometry, shader resources, and textures) must be stored in a resource. すべての Direct3D リソースの派生元となるリソースは 2 種類あります。バッファーとテクスチャです。There are two types of resources from which all Direct3D resources derive: a buffer or a texture. 各パイプライン ステージでは最大 128 個のリソースをアクティブにできます。Up to 128 resources can be active for each pipeline stage. 詳しくは、「リソース」をご覧ください。For more information, see Resources.

サブリソースSubresource

サブリソースという用語はリソースのサブセットを指します。The term subresource refers to a subset of a resource. Direct3D は、リソース全体を参照することも、リソースのサブセットを参照することもできます。Direct3D can reference an entire resource or it can reference subsets of a resource. 詳しくは、「サブリソース」をご覧ください。For more information, see Subresource.

深度/ステンシルDepth-stencil

深度/ステンシル リソースには、深度とステンシルの情報を保持するための形式とバッファーが含まれます。A depth-stencil resource contains the format and buffer to hold depth and stencil information. このリソースは、テクスチャー リソースを使用して作成されます。It is created using a texture resource. 深度/ステンシル リソースを作成する方法について詳しくは、「深度/ステンシル機能の構成」を参照してください。For more information on how to create a depth-stencil resource, see Configuring Depth-Stencil Functionality. 深度/ステンシル リソースにアクセスするには、ID3D11DepthStencilView インターフェイスを使って実装される深度/ステンシル ビュー使用します。We access the depth-stencil resource through the depth-stencil view implemented using the ID3D11DepthStencilView interface.

深度情報は、ビューから隠すのではなくレンダリングする多角形の領域を示します。Depth info tells us which areas of polygons are rendered rather than hidden from view. ステンシル情報は、マスクするピクセルを示します。Stencil info tells us which pixels are masked. ステンシル情報は、ピクセルを描画するかどうかを決定する (ビットを 1 または 0 に設定する) ため、特殊効果を生成するために使用できます。It can be used to produce special effects since it determines whether a pixel is drawn or not; sets the bit to a 1 or 0.

詳細については、「深度ステンシル ビュー」、「深度バッファー」、「ステンシル バッファー」を参照してください。For more information, see: Depth-stencil view, depth buffer, and stencil buffer.

レンダー ターゲットRender target

レンダー ターゲットは、レンダリング パスの最後に書き込むことができるリソースです。A render target is a resource that we can write to at the end of a render pass. 通常、ID3D11Device::CreateRenderTargetView メソッドで、入力パラメーターとしてスワップ チェーン バック バッファー (これもリソースです) を使用して作成されます。It is commonly created using the ID3D11Device::CreateRenderTargetView method using the swap chain back buffer (which is also a resource) as the input parameter.

各レンダー ターゲットには、対応する深度/ステンシル ビューも必要です。これは、レンダー ターゲットを使用する前に、OMSetRenderTargets を使用してレンダー ターゲットを設定するときに、深度/ステンシル ビューも必要となるためです。Each render target should also have a corresponding depth-stencil view because when we use OMSetRenderTargets to set the render target before using it, it requires also a depth-stencil view. レンダー ターゲット リソースにアクセスするには、ID3D11RenderTargetView インターフェイスを使用して実装されるレンダー ターゲット ビューを使用します。We access the render target resource through the render target view implemented using the ID3D11RenderTargetView interface.

デバイスDevice

Direct3D 11 の使用経験が浅い場合は、デバイスは、オブジェクトの割り当てと破棄、プリミティブのレンダリング、グラフィックス ドライバー経由のグラフィックス カードとの通信を行うための方法であると考えることができます。For those who are new to Direct3D 11, you can imagine a device as a way to allocate and destroy objects, render primitives, and communicate with the graphics card through the graphics driver.

より正確に説明すると、Direct3D デバイスは Direct3D のレンダリング コンポーネントです。For a more precise explanation, a Direct3D device is the rendering component of Direct3D. デバイスは、レンダリングの状態をカプセル化して格納します。また、変換や照明の操作、サーフェスへのイメージのラスタライズを実行します。A device encapsulates and stores the rendering state, performs transformations and lighting operations, and rasterizes an image to a surface. 詳しくは、「デバイス」をご覧ください。For more information, see Devices

デバイスは、ID3D11Device インターフェイスによって表されます。A device is represented by the ID3D11Device interface. つまり、ID3D11Device インターフェイスは仮想ディスプレイ アダプターを表し、デバイスによって所有されるリソースを作成するために使用します。In other words, the ID3D11Device interface represents a virtual display adapter and is used to create resources that are owned by a device.

ID3D11Device には複数のバージョンがあり、ID3D11Device5 が最新バージョンで、ID3D11Device4 に新しいメソッドが追加されています。Note that there are different versions of ID3D11Device, ID3D11Device5 is the latest version and adds new methods to those in ID3D11Device4. Direct3D が基になるハードウェアと通信する方法の詳細については、Windows Device Driver Model (WDDM) アーキテクチャに関するページを参照してください。For more information on how Direct3D communicates with the underlying hardware, see Windows Device Driver Model (WDDM) architecture.

各アプリケーションには少なくとも 1 つのデバイスが必要であり、ほとんどのアプリケーションは 1 つだけデバイスを作成します。Each application must have at least one device, most applications only create one device. コンピューターにインストールされているいずれかのハードウェア ドライバーについてデバイスを作成するには、D3D11CreateDevice または D3D11CreateDeviceAndSwapChain を呼び出して、D3D_DRIVER_TYPE フラグでドライバーの種類を指定します。Create a device for one of the hardware drivers installed on your machine by calling D3D11CreateDevice or D3D11CreateDeviceAndSwapChain and specifying the driver type with the D3D_DRIVER_TYPE flag. 各デバイスでは、必要な機能に応じて、1 つまたは複数のデバイス コンテキストを使用できます。Each device can use one or more device contexts, depending on the functionality desired. 詳細については、D3D11CreateDevice 関数に関するページを参照してください。For more information, see D3D11CreateDevice function.

デバイス コンテキストDevice context

デバイス コンテキストは、パイプラインの状態を設定し、デバイスによって所有されるリソースを使用してレンダリング コマンドを生成するために使用されます。A device context is used to set pipeline state and generate rendering commands using the resources owned by a device.

Direct3D 11 は 2 種類のデバイス コンテキストを実装します。1 つは即時レンダリング用で、もう 1 つは遅延レンダリング用です。いずれのコンテキストも ID3D11DeviceContext インターフェイスを使用して表されます。Direct3D 11 implements two types of device contexts, one for immediate rendering and the other for deferred rendering; both contexts are represented with an ID3D11DeviceContext interface.

ID3D11DeviceContext インターフェイスには複数のバージョンがあり、ID3D11DeviceContext4ID3D11DeviceContext3 に新しいメソッドを追加します。The ID3D11DeviceContext interfaces have different versions; ID3D11DeviceContext4 adds new methods to those in ID3D11DeviceContext3.

注: ID3D11DeviceContext4 は Windows 10 Creators Update で導入され、ID3D11DeviceContext インターフェイスの最新バージョンです。Note: ID3D11DeviceContext4 is introduced in the Windows 10 Creators Update and is the latest version of the ID3D11DeviceContext interface. Windows 10 Creators Update を対象とするアプリケーションでは、以前のバージョンではなく、このインターフェイスを使用する必要があります。Applications targeting Windows 10 Creators Update should use this interface instead of earlier versions. 詳しくは、ID3D11DeviceContext4 に関するページを参照してください。For more information, see ID3D11DeviceContext4.

DX::DeviceResourcesDX::DeviceResources

DX::DeviceResources クラスは、DeviceResources.cpp/.h ファイルに含まれており、すべての DirectX デバイス リソースを制御します。The DX::DeviceResources class is in the DeviceResources.cpp/.h files and controls all of DirectX device resources. サンプル ゲーム プロジェクトおよび DirectX 11 アプリ テンプレート プロジェクトでは、これらのファイルは Commons フォルダーにあります。In the sample game project and the DirectX 11 App template project, these files are in the Commons folder. Visual Studio 2015 以降で、新しい DirectX 11 アプリ テンプレート プロジェクトを作成するときに、これらのファイルの最新バージョンを取り込むことができます。You can grab the latest version of these files when you create a new DirectX 11 App template project in Visual Studio 2015 or later.

バッファーBuffer

バッファー リソースは完全に型指定されたデータのコレクションであり、複数の要素にグループ化されます。A buffer resource is a collection of fully typed data grouped into elements. バッファーを使用して、さまざまなデータを格納できます。たとえば、位置ベクトル、法線ベクトル、頂点バッファー内のテクスチャ座標、インデックス バッファー内のインデックス、デバイスの状態などのデータが格納されます。You can use buffers to store a wide variety of data, including position vectors, normal vectors, texture coordinates in a vertex buffer, indexes in an index buffer, or device state. バッファー要素には、圧縮済みデータ値 (R8G8B8A8 サーフェス値)、単一の 8 ビット整数、または 4 つの 32 ビット浮動小数点値を含めることができます。Buffer elements can include packed data values (like R8G8B8A8 surface values), single 8-bit integers, or four 32-bit floating point values.

利用可能なバッファーには、頂点バッファー、インデックス バッファー、定数バッファーの 3 つの種類があります。There are three types of buffers available: Vertex buffer, index buffer, and constant buffer.

頂点バッファーVertex Buffer

ジオメトリの定義に使われる頂点データが格納されます。Contains the vertex data used to define your geometry. 頂点データには、位置座標、色データ、テクスチャ座標データ、法線データなどが含まれます。Vertex data includes position coordinates, color data, texture coordinate data, normal data, and so on.

インデックス バッファーIndex Buffer

頂点バッファーへの整数オフセットが格納されます。このバッファーは、より効率的なプリミティブのレンダリングに使われます。Contains integer offsets into vertex buffers and are used to render primitives more efficiently. インデックス バッファーは 16 ビットまたは 32 ビットの連続するインデックスを格納します。各インデックスは頂点バッファーの頂点を識別するのに使用されます。An index buffer contains a sequential set of 16-bit or 32-bit indices; each index is used to identify a vertex in a vertex buffer.

定数バッファーまたはシェーダー定数バッファーConstant Buffer or shader-constant buffer

シェーダー データをパイプラインに効率的に提供できます。Allows you to efficiently supply shader data to the pipeline. 定数バッファーは、各プリミティブについて実行され、レンダリング パイプラインのストリーム出力ステージの結果を格納するシェーダーの入力として使用できます。You can use constant buffers as inputs to the shaders that run for each primitive and store results of the stream-output stage of the rendering pipeline. 定数バッファーは、概念的には要素が 1 つの頂点バッファーに似ています。Conceptually, a constant buffer looks just like a single-element vertex buffer.

バッファーの設計と実装Design and implementation of buffers

バッファーはデータ型に基づいて設計できます。たとえば、ゲームのサンプルでは、静的データ用に 1 つのバッファー、フレームで一定のデータ用に別のバッファー、プリミティブに固有のデータ用にまた別のバッファーを作成します。You can design buffers based on the data type, for example, like in our game sample, one buffer is created for static data, another for data that's constant over the frame, and another for data that's specific to a primitive.

すべてのバッファーの種類は ID3D11Buffer インターフェイスによってカプセル化され、ID3D11Device::CreateBuffer を呼び出すことによってバッファー リソースを作成できます。All buffer types are encapsulated by the ID3D11Buffer interface and you can create a buffer resource by calling ID3D11Device::CreateBuffer. ただし、バッファーにアクセスするには、その前にバッファーがパイプラインにバインドされている必要があります。But a buffer must be bound to the pipeline before it can be accessed. バッファーは、読み取りのために同時に複数のパイプライン ステージにバインドできます。Buffers can be bound to multiple pipeline stages simultaneously for reading. バッファーは、書き込みのために単一のパイプライン ステージにバインドすることもできます。ただし、同じバッファーを読み取りと書き込みのために同時にバインドすることはできません。A buffer can also be bound to a single pipeline stage for writing; however, the same buffer cannot be bound for reading and writing simultaneously.

次のようなステージにバッファーをバインドします。Bind buffers to the:

  • 入力アセンブラー ステージ。そのためには、ID3D11DeviceContextID3D11DeviceContext::IASetVertexBuffers メソッドや ID3D11DeviceContext::IASetIndexBuffer メソッドを呼び出します。Input-assembler stage by calling ID3D11DeviceContext methods like ID3D11DeviceContext::IASetVertexBuffers and ID3D11DeviceContext::IASetIndexBuffer
  • ストリーム出力ステージ。そのためには、ID3D11DeviceContext::SOSetTargets を呼び出します。Stream-output stage by calling ID3D11DeviceContext::SOSetTargets
  • シェーダー ステージ。そのためには、ID3D11DeviceContext::VSSetConstantBuffers などのシェーダー メソッドを呼び出します。Shader stage by calling shader methods, like ID3D11DeviceContext::VSSetConstantBuffers

詳しくは、「Direct3D 11 のバッファーについて」をご覧ください。For more information, see Introduction to buffers in Direct3D 11.

DXGIDXGI

Microsoft DirectX Graphics Infrastructure (DXGI) は、Direct3D 10、10.1、11、11.1 で必要とされる低レベルのタスクの一部をカプセル化する、Windows Vista で導入された新しいサブシステムです。Microsoft DirectX Graphics Infrastructure (DXGI) is a new subsystem that was introduced with Windows Vista that encapsulates some of the low-level tasks that are needed by Direct3D 10, 10.1, 11, and 11.1. マルチスレッド アプリケーションで DXGI を使用する場合、デッドロックが発生しないように特に注意する必要があります。Special care must be taken when using DXGI in a multithreaded application to ensure that deadlocks do not occur. 詳細については、DirectX グラフィックス インフラストラクチャ (DXGI): ベスト プラクティスのマルチスレッドに関する説明を参照してください。For more info, see DirectX Graphics Infrastructure (DXGI): Best Practices- Multithreading

機能レベルFeature Level

機能レベルは、最新または既存のコンピューターで多様なビデオ カードを処理するために、Direct3D 11 で導入された概念です。Feature level is a concept introduced in Direct3D 11 to handle the diversity of video cards in new and existing machines. 機能レベルは、明確に定義されたグラフィックス処理装置 (GPU) 機能のセットです。A feature level is a well defined set of graphics processing unit (GPU) functionality.

各ビデオ カードは、インストールされている GPU に応じて、特定のレベルの DirectX の機能を実装します。Each video card implements a certain level of DirectX functionality depending on the GPUs installed. 以前のバージョンの Microsoft Direct3D では、ビデオ カードが実装しているバージョンを検出し、それに応じてアプリケーションをプログラミングすることができました。In prior versions of Microsoft Direct3D, you could find out the version of Direct3D the video card implemented, and then program your application accordingly.

機能レベルを使用すると、デバイスを作成するときに、必要な機能レベルのデバイスを作成してみることができます。With feature level, when you create a device, you can attempt to create a device for the feature level that you want to request. デバイスの作成に成功した場合は、その機能レベルが存在します。失敗した場合は、ハードウェアはその機能レベルをサポートしていません。If the device creation works, that feature level exists, if not, the hardware does not support that feature level. 低い機能レベルでデバイスを再作成してみることも、アプリケーションの終了を選択することもできます。You can either try to recreate a device at a lower feature level or you can choose to exit the application. たとえば、12_0 機能レベルでは、Direct3D 11.3 や Direct3D 12、およびシェーダー モデル 5.1 が必要です。For instance, the 12_0 feature level requires Direct3D 11.3 or Direct3D 12, and shader model 5.1. 詳細については、Direct3D の各機能レベルの概要に関するページを参照してください。For more information, see Direct3D feature levels: Overview for each feature level.

機能レベルを使用して、Direct3D 9 や Microsoft Direct3D 10、Direct3D 11 のアプリケーションを開発し、9、10、または 11 のハードウェアで実行できます (いくつか例外があります)。Using feature levels, you can develop an application for Direct3D 9, Microsoft Direct3D 10, or Direct3D 11, and then run it on 9, 10, or 11 hardware (with some exceptions). 詳細については、Direct3D の機能レベルに関するページを参照してください。For more information, see Direct3D feature levels.

ステレオ レンダリングStereo rendering

ステレオ レンダリングは奥行き感を強化するために使用されます。Stereo rendering is used to enhance the illusion of depth. 左目の視点から画像と右目の視点からの画像の 2 つの画像を使用して、ディスプレイの画面にシーンを表示します。It uses two images, one from the left eye and the other from the right eye to display a scene on the display screen.

数学的には、ステレオ射影行列を適用することによってこれを実現します。ステレオ射影行列は、通常のモノラル射影行列を水平方向にわずかに右および左にオフセットしたものです。Mathematically, we apply a stereo projection matrix, which is a slight horizontal offset to the right and to the left, of the regular mono projection matrix to achieve this.

このゲーム サンプルでは、ステレオ レンダリングを実現するために、次の 2 つのレンダリング パスを実行しました。We did two rendering passes to achieve stereo rendering in this game sample:

  • 右側のレンダー ターゲットにバインドし、右の射影を適用したのち、プリミティブ オブジェクトを描画します。Bind to right render target, apply right projection, then draw the primitive object.
  • 左側のレンダー ターゲットにバインドし、左の射影を適用したのち、プリミティブ オブジェクトを描画します。Bind to left render target, apply left projection, then draw the primitive object.

カメラと座標空間Camera and coordinate space

ゲームには、独自の座標系でワールドを更新するためのコードがあります (ワールド空間またはシーン空間と呼ばれることもあります)。The game has the code in place to update the world in its own coordinate system (sometimes called the world space or scene space). カメラを含むすべてのオブジェクトはこの空間に配置されます。All objects, including the camera, are positioned and oriented in this space. 詳細については、「座標系」を参照してください。For more information, see Coordinate systems.

頂点シェーダーは、次のアルゴリズムを使って (V はベクター、M は行列を表す) モデル座標からデバイス座標への変換を行います。A vertex shader does the heavy lifting of converting from the model coordinates to device coordinates with the following algorithm (where V is a vector and M is a matrix).

V(device) = V(model) x M(model-to-world) x M(world-to-view) x M(view-to-device)。V(device) = V(model) x M(model-to-world) x M(world-to-view) x M(view-to-device).

この場合where:

  • M(model-to-world) はモデル座標からワールド座標への変換行列であり、ワールド変換行列とも呼ばれます。M(model-to-world) is a transformation matrix for model coordinates to world coordinates, also known as the World transform matrix. これは、プリミティブによって提供されます。This is provided by the primitive.
  • M(world-to-view) はワールド座標からビュー座標への変換行列であり、ビュー変換行列とも呼ばれます。M(world-to-view) is a transformation matrix for world coordinates to view coordinates, also known as the View transform matrix.
    • これは、カメラのビュー行列によって提供されます。This is provided by the view matrix of the camera. これは、カメラの位置とルック ベクター (カメラからシーンを直接ポイントする "ルック アット" ベクターとシーンに対して垂直かつ上向きの "ルック アップ" ベクター) によって定義されます。It's defined by the camera's position along with the look vectors (the "look at" vector that points directly into the scene from the camera, and the "look up" vector that is upwards perpendicular to it)
    • サンプル ゲームでは、m_viewMatrix はビュー変換行列であり、Camera::SetViewParams を使用して計算されます。In the sample game, m_viewMatrix is the view transformation matrix and is calculated using Camera::SetViewParams
  • M(view-to-device) はビュー座標からデバイス座標への変換行列であり、射影変換行列とも呼ばれます。M(view-to-device) is a transformation matrix for view coordinates to device coordinates, also known as the Projection transform matrix
    • これは、カメラの射影によって提供されます。This is provided by the projection of the camera. その空間のどれくらいの量が実際に最終的なシーンに表示されるかについての情報を提供します。It provides info how much of that space is actually visible in the final scene. 視野 (FoV)、縦横比、クリッピング面によって、射影変換行列が定義されます。The Field of View (FoV), aspect ratio, and clipping planes define the projection transform matrix.
    • サンプル ゲームでは、m_projectionMatrix は、Camera::SetProjParams を使用して計算された、射影座標への変換を定義します (ステレオ射影の場合は、それぞれの目のビューに 1 つずつ、2 つの射影行列を使用します)。In the sample game, m_projectionMatrix defines transformation to the projection coordinates, calculated using Camera::SetProjParams (For stereo projection, you use two projection matrices: one for each eye's view.)

VertexShader.hlsl のシェーダー コードがこれらのベクターや行列と共に定数バッファーから読み込まれ、各頂点に対してこの変換を実行します。The shader code in VertexShader.hlsl is loaded with these vectors and matrices from the constant buffers, and performs this transformation for every vertex.

座標変換Coordinate transformation

Direct3D では、3 つの変換を使用して 3D モデル座標をピクセル座標 (スクリーン空間) に変更します。Direct3D uses three transformations to change your 3D model coordinates into pixel coordinates (screen space). これらの変換は、ワールド変換、ビュー変換、射影変換です。These transformations are world transform, view transform, and projection transform. 詳細については、「変換の概要」を参照してください。For more info, go to Transform overview.

ワールド変換行列World transform matrix

ワールド変換は、座標系をモデル空間からワールド空間に変更します。モデル空間では、頂点はモデルのローカル原点を基準として相対的に定義されます。ワールド空間では、頂点はシーン内のすべてのオブジェクトに共通の原点を基準として相対的に定義されます。A world transform changes coordinates from model space, where vertices are defined relative to a model's local origin, to world space, where vertices are defined relative to an origin common to all the objects in a scene. 基本的に、ワールド変換はモデルをワールド空間に配置します。そのため、このように呼ばれます。In essence, the world transform places a model into the world; hence its name. 詳細については、「ワールド変換」を参照してください。For more information, see World transform.

ビュー変換行列View transform matrix

ビュー変換は、ビューアーをワールド空間に配置し、頂点をカメラ空間に変換します。The view transform locates the viewer in world space, transforming vertices into camera space. カメラ空間では、カメラつまりビューアーは原点に位置し、Z 軸の正方向を向いています。In camera space, the camera, or viewer, is at the origin, looking in the positive z-direction. 詳細については、「ビュー変換」を参照してください。For more info, go to View transform.

射影変換行列Projection transform matrix

射影変換では、視錐台を立方体に変換します。The projection transform converts the viewing frustum to a cuboid shape. 視錐台とは、ビューポートのカメラに対して相対的に配置された、シーン内の 3D ボリュームです。A viewing frustum is a 3D volume in a scene positioned relative to the viewport's camera. ビューポートとは、3D シーンが投影される 2D の四角形です。A viewport is a 2D rectangle into which a 3D scene is projected. 詳細については、「ビューポートとクリッピング」を参照してください。For more information, see Viewports and clipping

視錐台の近くの端は遠くの端よりも小さいので、この変換にはカメラの近くのオブジェクトを拡大するという効果があり、これによってシーンに遠近感が生まれます。Because the near end of the viewing frustum is smaller than the far end, this has the effect of expanding objects that are near to the camera; this is how perspective is applied to the scene. したがって、プレイヤーに近いオブジェクトは大きく表示され、遠くにあるオブジェクトは小さく表示されます。So objects that are closer to the player, appear larger; objects that are further away, appear smaller.

数学的には、射影変換は、通常、スケーリングおよび遠近法の両方の行列です。Mathematically, the projection transform is a matrix that is typically both a scale and perspective projection. カメラのレンズと同様に機能します。It functions like the lens of a camera. 詳細については、「射影変換」を参照してください。For more information, see Projection transform.

サンプラーの状態Sampler state

サンプラーの状態は、テクスチャのアドレス指定モード、フィルター、詳細レベルを使用して、テクスチャ データをサンプリングする方法を決定します。Sampler state determines how texture data is sampled using texture addressing modes, filtering, and level of detail. サンプリングは、テクスチャ ピクセル、つまりテクセルがテクスチャから読み取られるたびに実行されます。Sampling is done each time a texture pixel, or texel, is read from a texture.

テクスチャには、テクセル、つまりテクスチャ ピクセルの配列が含まれています。A texture contains an array of texels, or texture pixels. 各テクセルの位置は (u, v) で表されます。u が幅、v が高さで、テクスチャの幅と高さに基づいて、0 ~ 1 にマッピングされます。The position of each texel is denoted by (u,v), where u is the width and v is the height, and is mapped between 0 and 1 based on the texture width and height. 結果として得られるテクスチャ座標は、テクスチャをサンプリングするときに、テクセルのアドレス指定に使用されます。The resulting texture coordinates are used to address a texel when sampling a texture.

テクスチャ座標が 0 未満または 1 を超える場合、テクスチャ アドレス モードは、テクスチャ座標がテクセル位置を指定する方法を定義します。When texture coordinates are below 0 or above 1, the texture address mode defines how the texture coordinate addresses a texel location. たとえば、TextureAddressMode.Clamp を使用する場合、0 ~ 1 の範囲外の座標は、サンプリングの前に、最大値 1 および最小値 0 にクランプされます。For example, when using TextureAddressMode.Clamp, any coordinate outside the 0-1 range is clamped to a maximum value of 1, and minimum value of 0 before sampling.

テクスチャがポリゴンに対して大きすぎる場合や小さすぎる場合は、テクスチャは空間に合わせてフィルタリングされます。If the texture is too large or too small for the polygon, the texture is filtered to fit the space. 拡大フィルターはテクスチャを拡大し、縮小フィルターは小さな領域に収まるようにテクスチャを縮小します。A magnification filter enlarges a texture, a minification filter reduces the texture to fit into a smaller area. テクスチャの拡大では、サンプル テクセルが 1 つまたは複数のアドレスに繰り返され、ぼやけた画像が生成されます。Texture magnification repeats the sample texel for one or more addresses which yields a blurrier image. テクスチャの縮小では、1 つ以上のテクセルの値が 1 つの値に結合する必要があるためより複雑です。Texture minification is more complicated because it requires combining more than one texel value into a single value. これによって、テクスチャ データに応じてエイリアシングやぎざぎざのエッジが発生する場合があります。This can cause aliasing or jagged edges depending on the texture data. 縮小の最も一般的なアプローチでは、ミップマップを使用します。The most popular approach for minification is to use a mipmap. ミップマップは、複数レベルのテクスチャです。A mipmap is a multi-level texture. 各レベルのサイズは、上のレベルよりも 2 の累乗だけ小さくなり、最終的には 1 x 1 のテクスチャになります。The size of each level is a power-of-two smaller than the previous level down to a 1x1 texture. 縮小を使用すると、ゲームはレンダリング時に必要なサイズに最も近いミップマップ レベルを選択します。When minification is used, a game chooses the mipmap level closest to the size that is needed at render time.

BasicLoaderBasicLoader

BasicLoader は、ディスク上のファイルからのシェーダー、テクスチャ、メッシュの読み込みをサポートする、単純なローダー クラスです。BasicLoader is a simple loader class that provides support for loading shaders, textures, and meshes from files on disk. 同期メソッドと非同期メソッドの両方を提供します。It provides both synchronous and asynchronous methods. このゲーム サンプルでは、BasicLoader.h/.cpp ファイルは Commons フォルダーにあります。In this game sample, the BasicLoader.h/.cpp files are found in the Commons folder.

詳細については、BasicLoader を参照してください。For more information, see Basic Loader.