404.リアルな3Dの描画

 この項では3D表現に中でも、よりリアルな描画方法について説明します。
 FullSample404を実行すると以下のような画面が現れます。

 

図0404a

 前項のサンプルとほぼ同じですが、シェーダが違います。リアルなライティングフォグが施されています。
 また、モデルの描画には法線マップが設定されているものもあります。

プリミティブの描画

 奥に並んでいる球体は、前項とほぼ同じです。描画コンポーネントをリアルな描画のものに変更すればおおむね実装できます。以下はPtSphere(PT頂点を持つ球)ですが、PtSphere::OnCreate()には以下のようになってます。
void PtSphere::OnCreate() {
//中略

    //描画コンポーネント
    auto PtrDraw = AddComponent<BcPTStaticDraw>();
    PtrDraw->SetFogEnabled(true);

//中略
}
 上記のようにBcPTStaticDrawコンポーネントを描画コンポーネントにすればリアルな描画になります。
 またPtrDraw->SetFogEnabled(true);と設定すればフォグが有効になります。
 フォグを有効にすると画面を引いたときに以下のような表示になります。

 

図0404b


モデルの描画

 モデルをリアルな描画にしたのが手前の8体です。左4つはアニメーションが入ってます。
 以下はボーンモデルの描画ですがタンジェントがついているものとついてないものの違いを確認してください。

 

図0404c


 モデルは通常PNT頂点で作成します。これをリアルなライティングにするためには、描画コンポーネントを以下のようにします。以下はスタティックモデルの描画(右から2つ)ですが
//初期化
void StaticChara::OnCreate() {

//中略

    if (m_TamgentUse) {
        auto PtrDraw = AddComponent<BcPNTnTStaticModelDraw>();
        PtrDraw->SetFogEnabled(true);
        PtrDraw->SetMeshResource(L"MODEL_MESH_WITH_TAN");
        PtrDraw->SetNormalMapTextureResource(L"MODEL_NORMAL_TX");
        PtrDraw->SetMeshToTransformMatrix(SpanMat);
    }
    else {
        auto PtrDraw = AddComponent<BcPNTStaticModelDraw>();
        PtrDraw->SetFogEnabled(true);
        PtrDraw->SetMeshResource(L"MODEL_MESH");
        PtrDraw->SetMeshToTransformMatrix(SpanMat);
    }
}
 m_TamgentUseが有効の場合タンジェントが入っているモデルのリソースを記述します。
 以下はボーンモデルの処理です。
//初期化
void BoneChara::OnCreate() {
    //中略

    if (m_TamgentUse) {
        //描画コンポーネントの設定
        auto PtrDraw = AddComponent<BcPNTnTBoneModelDraw>();
        PtrDraw->SetFogEnabled(true);
        //描画するメッシュを設定
        PtrDraw->SetMeshResource(L"Chara_R_MESH_WITH_TAN");
        PtrDraw->SetNormalMapTextureResource(L"Chara_R_NORMAL_TX");
        PtrDraw->SetMeshToTransformMatrix(SpanMat);
        PtrDraw->AddAnimation(L"Default", 0, 100, true, 20.0f);
        PtrDraw->ChangeCurrentAnimation(L"Default");
    }
    else {
        //描画コンポーネントの設定
        auto PtrDraw = AddComponent<BcPNTBoneModelDraw>();
        PtrDraw->SetFogEnabled(true);
        //描画するメッシュを設定
        PtrDraw->SetMeshResource(L"Chara_R_MESH");
        PtrDraw->SetMeshToTransformMatrix(SpanMat);

        PtrDraw->AddAnimation(L"Default", 0, 100, true, 20.0f);
        PtrDraw->ChangeCurrentAnimation(L"Default");

    }
    //透明処理
    SetAlphaActive(true);
}
 タンジェント付きモデルは、例えば、シーンなどでMeshResource::CreateBoneModelMeshWithTangent()関数(ボーンモデル用)MeshResource::CreateStaticModelMeshWithTangent()関数(スタティック用)PNT頂点のモデルをPNTnT頂点のモデルに変換して使用します。
void Scene::CreateResourses() {
//中略

    //ボーンモデルの通常リソース
    auto ModelMesh = MeshResource::CreateBoneModelMesh(DataDir, L"Chara_R.bmf");
    App::GetApp()->RegisterResource(L"Chara_R_MESH", ModelMesh);

    //ボーンモデルのタンジェント付きリソース
    ModelMesh = MeshResource::CreateBoneModelMeshWithTangent(DataDir, L"Chara_R.bmf");
    App::GetApp()->RegisterResource(L"Chara_R_MESH_WITH_TAN", ModelMesh);
    //法線マップ
    strTexture = DataDir + L"Chara_R_narmal.png";
    App::GetApp()->RegisterTexture(L"Chara_R_NORMAL_TX", strTexture);

    //ボーンモデル(マルチメッシュ)の通常リソース
    auto MultiModelMesh 
    = MultiMeshResource::CreateBoneModelMultiMesh(DataDir, L"Object_WalkAnimation.bmf");
    App::GetApp()->RegisterResource(L"Object_WalkAnimation_MESH", MultiModelMesh);

    //ボーンモデル(マルチメッシュ)のタンジェント付きリソース
    MultiModelMesh 
    = MultiMeshResource::CreateBoneModelMultiMeshWithTangent(DataDir, L"Object_WalkAnimation.bmf");
    App::GetApp()->RegisterResource(L"Object_WalkAnimation_MESH_WITH_TAN", MultiModelMesh);

    //法線マップ
    strTexture = DataDir + L"Tx_Checker_Normal.png";
    App::GetApp()->RegisterTexture(L"OBJECT_NORMAL_TX", strTexture);

    //スタティックモデルの通常リソース
    auto StaticModelMesh = MeshResource::CreateStaticModelMesh(DataDir, L"Character_01.bmf");
    App::GetApp()->RegisterResource(L"MODEL_MESH", StaticModelMesh);
    //スタティックモデルのタンジェント付きリソース
    StaticModelMesh = MeshResource::CreateStaticModelMeshWithTangent(DataDir, L"Character_01.bmf");
    App::GetApp()->RegisterResource(L"MODEL_MESH_WITH_TAN", StaticModelMesh);
    //法線マップ
    strTexture = DataDir + L"Character_2_normal.png";
    App::GetApp()->RegisterTexture(L"MODEL_NORMAL_TX", strTexture);

    //スタティックモデル(マルチメッシュ)の通常リソース
    auto StaticMultiModelMesh 
    = MultiMeshResource::CreateStaticModelMultiMesh(DataDir, L"ObjectOnly.bmf");
    App::GetApp()->RegisterResource(L"ObjectOnly_MESH", StaticMultiModelMesh);

    //スタティックモデル(マルチメッシュ)のタンジェント付きリソース
    StaticMultiModelMesh 
    = MultiMeshResource::CreateStaticModelMultiMeshWithTangent(DataDir, L"ObjectOnly.bmf");
    App::GetApp()->RegisterResource(L"ObjectOnly_MESH_WITH_TAN", StaticMultiModelMesh);

}
 このようにリアルな描画を実装するためには、基本的に描画コンポーネントの変更や、タンジェント付きのリソースを作成すればいいわけですが、ゲームによってどこまでリアルな描画が必要かどうかが違うと思いますので、前項のような描画が良いかどうかはしっかり検討して実装するといいと思います。
 また、このサンプルにも前項に使用したマルチメッシュのモデルもタンジェント付きタンジェント無しで実装されています。設置方法は前項と大きく変わりませんので、確認してみましょう。