トップページ > 記事閲覧
ノーマルマップの3Dポリゴン
名前:Tir 日時: 2017/09/03 23:12

質問します。 シェーダーモデル5.0のスレッドでDirectX11の法線マップ付きモデルの描画のシェーダーがあったので それを利用してDrawPolygon3Dに法線マップがついたような事がしたいのですが可能でしょうか? 試しに深く考えずに以下のプログラムを試しましたがやっぱり成功しませんでした #include "DxLib.h" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { VERTEX3DSHADER Vertex[6]; int vshandle; int pshandle; int texhandle; int normalhandle; // DXライブラリの初期化 ChangeWindowMode(true); if (DxLib_Init() < 0) { // エラーが発生したら直ちに終了 return -1; } // 2ポリゴン分の頂点のデータをセットアップ Vertex[0].pos = VGet(220.0f, 340.0f, 0.0f); Vertex[0].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[0].dif = GetColorU8(255, 255, 255, 255); Vertex[0].spc = GetColorU8(0, 0, 0, 0); Vertex[0].u = 0.0f; Vertex[0].v = 0.0f; Vertex[0].su = 0.0f; Vertex[0].sv = 0.0f; Vertex[1].pos = VGet(420.0f, 340.0f, 0.0f); Vertex[1].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[1].dif = GetColorU8(255, 255, 255, 255); Vertex[1].spc = GetColorU8(0, 0, 0, 0); Vertex[1].u = 1.0f; Vertex[1].v = 0.0f; Vertex[1].su = 1.0f; Vertex[1].sv = 0.0f; Vertex[2].pos = VGet(220.0f, 140.0f, 0.0f); Vertex[2].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[2].dif = GetColorU8(255, 255, 255, 255); Vertex[2].spc = GetColorU8(0, 0, 0, 0); Vertex[2].u = 0.0f; Vertex[2].v = 1.0f; Vertex[2].su = 0.0f; Vertex[2].sv = 1.0f; Vertex[3].pos = VGet(220.0f, 140.0f, 0.0f); Vertex[3].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[3].dif = GetColorU8(255, 255, 255, 255); Vertex[3].spc = GetColorU8(0, 0, 0, 0); Vertex[3].u = 0.0f; Vertex[3].v = 1.0f; Vertex[3].su = 0.0f; Vertex[3].sv = 1.0f; Vertex[4].pos = VGet(420.0f, 340.0f, 0.0f); Vertex[4].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[4].dif = GetColorU8(255, 255, 255, 255); Vertex[4].spc = GetColorU8(0, 0, 0, 0); Vertex[4].u = 1.0f; Vertex[4].v = 0.0f; Vertex[4].su = 1.0f; Vertex[4].sv = 0.0f; Vertex[5].pos = VGet(420.0f, 140.0f, 0.0f); Vertex[5].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[5].dif = GetColorU8(255, 255, 255, 255); Vertex[5].spc = GetColorU8(0, 0, 0, 0); Vertex[5].u = 1.0f; Vertex[5].v = 1.0f; Vertex[5].su = 1.0f; Vertex[5].sv = 1.0f; // 頂点シェーダーを読み込む vshandle = LoadVertexShader("NormalMesh_DirLight_NrmMapVS.vso"); // ピクセルシェーダーを読み込む pshandle = LoadPixelShader("NormalMesh_DirLight_NrmMapPS.pso"); // 描画に使用する画像の読み込み texhandle = LoadGraph("test.png"); // ノーマルマップ読み込み normalhandle = LoadGraph("NormalMap.png"); // 描画先を裏画面にする SetDrawScreen(DX_SCREEN_BACK); //ライトを設定 SetLightEnable(true); ChangeLightTypeDir(VGet(0, 0, 1)); // ESCキーが押されるまでループ while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) { // 画面を初期化 ClearDrawScreen(); // 使用する頂点シェーダーのセット SetUseVertexShader(vshandle); // 使用するピクセルシェーダーをセット SetUsePixelShader(pshandle); // 使用するテクスチャを0番にセット SetUseTextureToShader(0, texhandle); // 使用する法線マップを1番にセット SetUseTextureToShader(1, normalhandle); // シェーダーを使用した2ポリゴンの描画 DrawPolygon3DToShader(Vertex, 2); // 裏画面の内容を表画面に反映させる ScreenFlip(); } // 読み込んだ頂点シェーダーの削除 DeleteShader(vshandle); // 読み込んだピクセルシェーダーの削除 DeleteShader(pshandle); // 読み込んだ画像のグラフィックハンドルを削除 DeleteGraph(texhandle); DeleteGraph(normalhandle); // DXライブラリの後始末 DxLib_End(); // ソフトの終了 return 0; }
メンテ

Page: 1 |

Re: ノーマルマップの3Dポリゴン ( No.1 )
名前:管理人 日時:2017/09/04 01:08

> それを利用してDrawPolygon3Dに法線マップがついたような事がしたいのですが可能でしょうか? 試したことはありませんが、VERTEX3DSHADER のメンバー変数 tan, binorm に適切な 接線、従法線の値を代入して、頂点シェーダー、ピクセルシェーダーで法線マップの 処理を行えば法線マップ付きのポリゴン描画を DrawPolygon3DToShader で実現できるかもしれません
メンテ
Re: ノーマルマップの3Dポリゴン ( No.2 )
名前:Tir 日時:2017/09/04 12:03

使用するシェーダーは付属のNormalMesh_DirLight_NrmMapVSとNormalMesh_DirLight_NrmMapPSで大丈夫でしょうか? ttp://w w w.opengl-tutorial.org/jp/intermediate-tutorials/tutorial-13-normal-mapping/#%E6%8E%A5%E7%B7%9A%E3%81%A8%E5%BE%93%E6%8E%A5%E7%B7%9A%E3%81%AE%E8%A8%88%E7%AE%97 また上記のページの接線と従接線の計算を参考にして前回貼ったプログラムに以下の接戦と従法線の計算を追加してみましたが上手く行きませんでした 接線と従法線を正しく求めるにはどうしたらいいのでしょうか… for (int i = 0; i < 2 * 3; i += 3) { VECTOR pos1, pos2; pos1 = VSub(Vertex[1].pos, Vertex[0].pos); pos2 = VSub(Vertex[2].pos, Vertex[0].pos); float u1, u2, v1, v2; u1 = Vertex[1].u - Vertex[0].u; u2 = Vertex[2].u - Vertex[0].u; v1 = Vertex[1].v - Vertex[0].v; v2 = Vertex[2].v - Vertex[0].v; float r = 1.0f / (u1 * v2 - u2 * v1); float tangent[3]; tangent[0] = (pos1.x * v2 - pos2.x * v1)*r; tangent[1] = (pos1.y * v2 - pos2.y * v1)*r; tangent[2] = (pos1.z * v2 - pos2.z * v1)*r; float bitangent[3]; bitangent[0] = (pos2.x * u1 - pos1.x * u2)*r; bitangent[1] = (pos2.y * u1 - pos1.y * u2)*r; bitangent[2] = (pos2.z * u1 - pos1.z * u2)*r; Vertex[i + 0].tan= VNorm( VGet( tangent[0], tangent[1], tangent[2])); Vertex[i + 0].binorm = VNorm(VGet(bitangent[0], bitangent[1], bitangent[2])); Vertex[i + 1].tan = VNorm(VGet(tangent[0], tangent[1], tangent[2])); Vertex[i + 1].binorm = VNorm(VGet(bitangent[0], bitangent[1], bitangent[2])); Vertex[i + 2].tan = VNorm(VGet(tangent[0], tangent[1], tangent[2])); Vertex[i + 2].binorm = VNorm(VGet(bitangent[0], bitangent[1], bitangent[2])); }
メンテ
Re: ノーマルマップの3Dポリゴン ( No.3 )
名前:管理人 日時:2017/09/05 00:16

> 使用するシェーダーは付属のNormalMesh_DirLight_NrmMapVSとNormalMesh_DirLight_NrmMapPSで大丈夫でしょうか? いえ、NormalMesh_DirLight_NrmMapVS は MV1DrawModel で描画するモデル用の頂点シェーダーなので DrawPolygon3DToShader の頂点シェーダーとして使用する場合は頂点シェーダーの入力の頂点データの記述を変更する必要があります NormalMesh_DirLight_NrmMapVS では頂点シェーダーの入力の記述が // 頂点シェーダーの入力 struct VS_INPUT { float3 Position : POSITION ; // 座標( ローカル空間 ) float3 Normal : NORMAL ; // 法線( ローカル空間 ) float4 Diffuse : COLOR0 ; // ディフューズカラー float4 Specular : COLOR1 ; // スペキュラカラー float4 TexCoords0 : TEXCOORD0 ; // テクスチャ座標 float4 TexCoords1 : TEXCOORD1 ; // サブテクスチャ座標 float3 Tan : TANGENT0 ; // 接線( ローカル空間 ) float3 Bin : BINORMAL0 ; // 従法線( ローカル空間 ) } ; となっていますが、こちらは剛体メッシュのモデルを MV1DrawModel で描画する際の頂点データの記述なので、こちらを // 頂点シェーダーの入力 struct VS_INPUT { float3 Position : POSITION0 ; // 座標( ローカル空間 ) float4 SubPosition : POSITION1 ; // 補助座標 float3 Normal : NORMAL ; // 法線 float3 Tangent : TANGENT ; // 接線 float3 Binormal : BINORMAL ; // 従法線 float4 Diffuse : COLOR0 ; // ディフューズカラー float4 Specular : COLOR1 ; // スペキュラカラー float2 TexCoords0 : TEXCOORD0 ; // テクスチャ座標0 float2 TexCoords1 : TEXCOORD1 ; // テクスチャ座標1 } ; ↑のように VERTEX3DSHADER 構造体用に書き換えてください m(_ _)m ( Direct3D 11 の HLSL は Direct3D 9 の HLSL と異なり順番も重要ですので、記述の順番も上記の通りに変更してください ) あと、TexCoords0 と TexCoords1 が float4 から float2 に変化しているので、テクスチャ座標の代入部分は 行列計算をせず単純に代入する形にしてください( テクスチャ行列を設定していなければ問題ないので ) VSOutput.TexCoords0 = VSInput.TexCoords0;
メンテ
Re: ノーマルマップの3Dポリゴン ( No.4 )
名前:Tir 日時:2017/09/05 02:15

教えて頂きありがとうございますお陰様で描画することに成功したのですが 描画のブレンドモードがDX_BLENDMODE_NOBLENDでしか描画されません。これは仕様ですか?
メンテ
Re: ノーマルマップの3Dポリゴン ( No.5 )
名前:管理人 日時:2017/09/06 00:00

いえ、DX_BLENDMODE_NOBLEND 以外でも描画できます ピクセルシェーダーの出力となる色の a の値が SetDrawBlendMode の第二引数の値の機能をします PSOutput.Color.a = 0.0f は、 SetDrawBlendMode( ブレンドモード, 0 ) ; と同じ意味になります PSOutput.Color.a = 0.5f は、 SetDrawBlendMode( ブレンドモード, 128 ) ; と同じ意味になります PSOutput.Color.a = 1.0f は、 SetDrawBlendMode( ブレンドモード, 255 ) ; と同じ意味になります NormalMesh_DirLight_NrmMapPS.fx では PSOutput.Color0.a に代入する値の計算式の中にモデル描画時にのみ有効な パラメータ( g_Base.FactorColor.a )を使用しているので、直接アルファ値を代入する以下のような処理 PSOutput.Color0.a = 1.0f ; に変更すれば DX_BLENDMODE_NOBLEND 以外でも描画されると思います m(_ _;m
メンテ
Re: ノーマルマップの3Dポリゴン ( No.6 )
名前:Tir(解決) 日時:2017/09/06 00:44

重ね重ねありがとうございます! これで思った通りに描画することが出来ました
メンテ
Re: ノーマルマップの3Dポリゴン ( No.7 )
名前:Tir 日時:2017/09/07 15:15

質問させてください。 今はノーマルマップのシェーダーにディレクショナルライトとフォグだけの処理を行っているのですが 一応NormalMesh_DirSpotPointLight_NrmMapPSのように他のライトの処理も入れようと思ったのですが この場合ディレクショナルライトとフォグしか存在しない場合正常に描画されるのでしょうか? 例えばポイントライトとフォグしか存在しない場合はポイントライトとフォグのシェーダーと状況に合わせた シェーダーを用意しなければならないのでしょうか
メンテ
Re: ノーマルマップの3Dポリゴン ( No.8 )
名前:管理人 日時:2017/09/09 16:42

> この場合ディレクショナルライトとフォグしか存在しない場合正常に描画されるのでしょうか? > 例えばポイントライトとフォグしか存在しない場合はポイントライトとフォグのシェーダーと状況に合わせた > シェーダーを用意しなければならないのでしょうか はい、ディレクショナルライトしかない状態でポイントライトとスポットライトの処理も書かれたシェーダーを 使用した場合は正常に動作しません 組み合わせの数だけシェーダーを用意するか、自前でライトがあるかどうかを判断するための定数を用意して シェーダー内で if文を使用してポイントライトとスポットライトが無い場合は処理が行われないようにする必要があります ( 速度的には組み合わせの数だけシェーダーを用意したほうが良いです、ファイルは多くなってしまいますが… )
メンテ
Re: ノーマルマップの3Dポリゴン ( No.9 )
名前:Tir(解決) 日時:2017/09/09 18:44

解答ありがとうございます。 状況に応じてシェーダーを切り替えて対応しようと思います
メンテ
Re: ノーマルマップの3Dポリゴン ( No.10 )
名前:Tir 日時:2017/09/11 00:05

何度もすみません。 ノーマルマップのディレクショナルライト+フォグのシェーダーを適用するとテクスチャのrgb=0が透明になる現象が起きます。
メンテ
Re: ノーマルマップの3Dポリゴン ( No.11 )
名前:管理人 日時:2017/09/10 23:56

テクスチャの画像を LoadGraph で読み込む前に SetTransColor( 255,0,255 ) ; や SetUseTransColor( FALSE ) ; を実行してみても透明になってしまうでしょうか?
メンテ
Re: ノーマルマップの3Dポリゴン ( No.12 )
名前:Tir(解決) 日時:2017/09/11 00:01

記事修正の入れ違いになってしまいましたが上記の方法で解決できましたありがとうございます。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存