トップページ > 記事閲覧
DxLibでシェーダーを使うにはどうすればいいのか?
名前:たそたん 日時: 2020/05/10 20:26

Dxlibでシェーダーを使いたいのですがどうすればいいのでしょうか? DirectXの場合のものは検索にヒットして構文など基本的なことを知ることができると思いますが Dxlibに実装する方法がわかりません。初期化などDirectXとは違うためサイト等が参考にならないです 提示コードの////コメントの内部のシェーダーのコード実装部です。これはシェーダコードを何もしてないから何も表示されないのでしょうか? 当然のことですが公式リファレンスを見てなんとなく実装を試しましたがこれでいいのかどうなのかわかりません。シェーダコードでは何もしていないことは 知っています。とりま実行しています。 #include "DxLib.h" #include "Game.hpp" #include "Input.hpp" #include "Frame.hpp" #include "Vector.hpp" const char* filename = "Log.txt"; std::ofstream ofs(filename); /*コンストラクタ 初期化*/ Game::Game() { /*操作切替*/ mc = ModeChange::rotate; /*ライト設定*/ LightHandle = CreateDirLightHandle(VGet(0, -1, 0)); if (LightHandle == -1) { exit(1); } SetLightEnable(false); //標準ライトを有効にするかどうか? SetUseLighting(false); SetUseZBuffer3D(true); SetWriteZBuffer3D(true); handle = LoadGraph("assets/resource/texturePos.png"); cameraPos.x = 0; cameraPos.y = 20; cameraPos.z = -40; targetV.x = 0; targetV.y = 0; targetV.z = 0; /*上 手前から右回りで 回ったら下で手前から右回り 省略*/ //////////////////////////////////////////////////////////上の面の頂点 Vertex[0].pos = VGet(targetV.x - RANGE, targetV.y + RANGE, targetV.z - RANGE); Vertex[0].norm = VGet(0.0f, 0.0f, -1.0f); Vertex[0].dif = color_dif; Vertex[0].spc = color_spc; Vertex[0].u = 0.0f; Vertex[0].v = 0.0f; /*地面 ポリゴン*/ Ground_Vertex[0].pos = VGet(-GROUND_X, GROUND_Y, GROUND_Z); Ground_Vertex[0].norm = VGet(0.0f, 0.0f, -1.0f); Ground_Vertex[0].dif = color_dif; Ground_Vertex[0].spc = color_spc; Ground_Vertex[0].u = 0.0f; Ground_Vertex[0].v = 0.0f; ////////////////////////////////////////////////////////////////////////// /*Shader 設定*/ sh_V_handle = LoadVertexShader("assets/source/VertexShader.vso"); if (sh_V_handle == -1) { exit(1); } sh_V_handle = SetUseVertexShader(sh_V_handle); if (sh_V_handle == -1) { exit(1); } if (SetUseTextureToShader(0, handle) == -1) { exit(1); } ////////////////////////////////////////////////////////////////////////// Vertex_Norm(); } void Game::Update() { change(); /*カメラ回転*/ if (Input::keyboard(KEY_INPUT_LEFT) > 0) { rotate(&cameraPos, ROTATE_SPEED, targetV, Vector(0, 1, 0)); } else if (Input::keyboard(KEY_INPUT_RIGHT) > 0) { rotate(&cameraPos, ROTATE_SPEED, targetV, Vector(0, -1, 0)); } else if (Input::keyboard(KEY_INPUT_UP) > 0) { rotate(&cameraPos, ROTATE_SPEED, targetV, get_axis(cameraPos, targetV, Vector(0, 1, 0))); } else if (Input::keyboard(KEY_INPUT_DOWN) > 0) { rotate(&cameraPos, ROTATE_SPEED, targetV, get_axis(cameraPos, targetV, Vector(0, -1, 0))); } /*編集*/ switch (mc) { } // Vertex_Norm(); } /*確認用 描画*/ void Game::Debug_Draw() { DrawFormatString(0, 0, GetColor(255, 255, 255), "カメラ 座標 x: %.2f , y: %.2f , z:%.2f ", cameraPos.x, cameraPos.y, cameraPos.z); int t = GetValidShaderVersion() / 100; //DrawFormatString(0, 0, GetColor(255, 255, 255), "シェーダー: %d",t); DrawFormatString(0, 32 * 1, GetColor(255, 255, 255), "注視点 座標 x: %.2f , y: %.2f , z:%.2f ", targetV.x, targetV.y, targetV.z); } void Game::DrawUpdate() { // DrawFormatString(0, 32 * 3, GetColor(255, 255, 255), "chqnge();"); SetCameraPositionAndTarget_UpVecY(VGet(cameraPos.x, cameraPos.y, cameraPos.z), VGet(targetV.x, targetV.y, targetV.z)); /*キューブ描画*/ for (int i = 0; i < 6; i++) { switch (i) { /*手前*/ case 0: { Vertex[0].u = 0.0; Vertex[0].v = 0.0; Vertex[1].u = 1.0; Vertex[1].v = 0.0; Vertex[4].u = 0.0; Vertex[4].v = 1.0; Vertex[5].u = 1.0; Vertex[5].v = 1.0; } break;//同じようなコードのため省略 // DrawPolygonIndexed3D(Vertex, 8, Index[i], 2, DX_NONE_GRAPH, false); // DrawPolygonIndexed3D(Vertex, 8, Index[i], 2, handle, false); }    ////////////////////////////////////////////////////////////////////////////////// if (DrawPolygonIndexed3DToShader(Vertex, 8, Index[i], 2) == -1) { exit(1); } ////////////////////////////////////////////////////////////////////////////////// } /*平面描画*/ DrawPolygonIndexed3D(Ground_Vertex, 4, Ground_Index, 2, handle, false); /*ライト*/ // SetLightEnableHandle(LightHandle,true); Debug_Draw(); } /*シェーダーコード*/ float4x4 matWVP : WorldViewProjection; struct vertexInput { float3 Position : POSITION; }; struct vertexOutput { float3 HPosition : POSITION; float4 Diffuse : COLORD; }; //vertexOutput VS_TransformDiffuse(vertexInput IN) vertexOutput main(vertexInput IN) { vertexOutput OUT; // OUT.HPosition = mul(float4(IN.Position.xyz, 1.f), matWVP); // OUT.Diffuse = float4(1.f, 1.f, 1.f, 1.f); return OUT; } technique textured { pass p0 { VertexShader = compile vs_5_0 main(); } }
メンテ

Page: 1 |

Re: DxLibでシェーダーを使うにはどうすればいいのか? ( No.1 )
名前:管理人 日時:2020/05/10 22:57

DXライブラリで Direct3D 11 のシェーダーを使用する場合は頂点の入力は以下で固定されています // 頂点シェーダーの入力 struct VS_INPUT { float3 pos : POSITION0 ; // 座標( ローカル空間 ) float4 spos : POSITION1 ; // 予備座標 float3 norm : NORMAL0 ; // 法線( ローカル空間 ) float3 tan : TANGENT0 ; // 接線( ローカル空間 ) float3 binorm : BINORMAL0 ; // 従法線( ローカル空間 ) float4 dif : COLOR0 ; // ディフューズカラー float4 spc : COLOR1 ; // スペキュラカラー float2 texCoords0 : TEXCOORD0 ; // テクスチャ座標 float2 texCoords1 : TEXCOORD1 ; // サブテクスチャ座標 } ; 定数も現状では固定で以下のようになっています <頂点シェーダー> // 基本パラメータ struct DX_D3D11_VS_CONST_BUFFER_BASE { float4 AntiViewportMatrix[ 4 ] ; // アンチビューポート行列 float4 ProjectionMatrix[ 4 ] ; // ビュー → プロジェクション行列 float4 ViewMatrix[ 3 ] ; // ワールド → ビュー行列 float4 LocalWorldMatrix[ 3 ] ; // ローカル → ワールド行列 float4 ToonOutLineSize ; // トゥーンの輪郭線の大きさ float DiffuseSource ; // ディフューズカラー( 0.0f:マテリアル 1.0f:頂点 ) float SpecularSource ; // スペキュラカラー( 0.0f:マテリアル 1.0f:頂点 ) float MulSpecularColor ; // スペキュラカラー値に乗算する値( スペキュラ無効処理で使用 ) float Padding ; } ; // その他の行列 struct DX_D3D11_VS_CONST_BUFFER_OTHERMATRIX { float4 ShadowMapLightViewProjectionMatrix[ 3 ][ 4 ] ; // シャドウマップ用のライトビュー行列とライト射影行列を乗算したもの float4 TextureMatrix[ 3 ][ 2 ] ; // テクスチャ座標操作用行列 } ; // 基本パラメータ cbuffer cbD3D11_CONST_BUFFER_VS_BASE : register( b1 ) { DX_D3D11_VS_CONST_BUFFER_BASE g_Base ; } ; // その他の行列 cbuffer cbD3D11_CONST_BUFFER_VS_OTHERMATRIX : register( b2 ) { DX_D3D11_VS_CONST_BUFFER_OTHERMATRIX g_OtherMatrix ; } ; <ピクセルシェーダー> // 定数バッファピクセルシェーダー基本パラメータ struct DX_D3D11_PS_CONST_BUFFER_BASE { float4 FactorColor ; // アルファ値等 float MulAlphaColor ; // カラーにアルファ値を乗算するかどうか( 0.0f:乗算しない 1.0f:乗算する ) float AlphaTestRef ; // アルファテストで使用する比較値 float2 Padding1 ; int AlphaTestCmpMode ; // アルファテスト比較モード( DX_CMP_NEVER など ) int3 Padding2 ; float4 IgnoreTextureColor ; // テクスチャカラー無視処理用カラー } ; // 基本パラメータ cbuffer cbD3D11_CONST_BUFFER_PS_BASE : register( b1 ) { DX_D3D11_PS_CONST_BUFFER_BASE g_Base ; } ; SamplerState g_DiffuseMapSampler : register( s0 ) ; // ディフューズマップサンプラ Texture2D g_DiffuseMapTexture : register( t0 ) ; // ディフューズマップテクスチャ あと、事前にコンパイルされたシェーダーバイナリしか使用できないため、シェーダーコードの technique は使用できません Direct3D 11 のシェーダーを使用して画面に画像を描画するサンプルを作成してみましたので、 よろしければご覧ください m(_ _)m https://dxlib.xsrv.jp/temp/ShaderPolygon3DTestD3D11.zip zipファイルの中身は以下の通りです ShaderCompiler.exe // シェーダーコンパイラ ShaderPolygon3DTest.cpp // サンプルのC++コード ShaderPolygon3DTest.exe // サンプルコードをビルドして作成した実行ファイル ShaderPolygon3DTest_ShaderCompile.bat // サンプルのシェーダーコードをコンパイルするためのバッチファイル ShaderPolygon3DTestPS.hlsl // サンプルのピクセルシェーダーコード ShaderPolygon3DTestPS.pso // サンプルのピクセルシェーダーコードをコンパイルして作成したバイナリファイル ShaderPolygon3DTestVS.hlsl // サンプルの頂点シェーダーコード ShaderPolygon3DTestVS.vso // サンプルの頂点シェーダーコードをコンパイルして作成したバイナリファイル Texture0.bmp // サンプルで使用している画像ファイル サンプルの C++、 頂点シェーダー、 ピクセルシェーダーのコードは以下の通りです <C++> #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int grhandle, pshandle, vshandle ; VERTEX3DSHADER Vert[ 6 ] = { 0.0f } ; // ウインドウモードで起動 ChangeWindowMode( TRUE ) ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1 ; // 画像の読み込み grhandle = LoadGraph( "Texture0.bmp" ); // 頂点シェーダーバイナリコードの読み込み vshandle = LoadVertexShader( "ShaderPolygon3DTestVS.vso" ) ; // ピクセルシェーダーバイナリコードの読み込み pshandle = LoadPixelShader( "ShaderPolygon3DTestPS.pso" ) ; // 頂点データの準備 Vert[ 0 ].pos = VGet( 100.0f, 356.0f, 0.0f ) ; Vert[ 1 ].pos = VGet( 356.0f, 356.0f, 0.0f ) ; Vert[ 2 ].pos = VGet( 100.0f, 100.0f, 0.0f ) ; Vert[ 3 ].pos = VGet( 356.0f, 100.0f, 0.0f ) ; Vert[ 0 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 1 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 2 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 3 ].dif = GetColorU8( 255,255,255,255 ) ; Vert[ 0 ].u = 0.0f ; Vert[ 0 ].v = 0.0f ; Vert[ 1 ].u = 1.0f ; Vert[ 1 ].v = 0.0f ; Vert[ 2 ].u = 0.0f ; Vert[ 3 ].v = 1.0f ; Vert[ 3 ].u = 1.0f ; Vert[ 2 ].v = 1.0f ; Vert[ 4 ] = Vert[ 2 ] ; Vert[ 5 ] = Vert[ 1 ] ; // 使用するテクスチャをセット SetUseTextureToShader( 0, grhandle ) ; // 使用する頂点シェーダーをセット SetUseVertexShader( vshandle ) ; // 使用するピクセルシェーダーをセット SetUsePixelShader( pshandle ) ; // 描画 DrawPolygon3DToShader( Vert, 2 ) ; // キー入力待ち WaitKey() ; // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; } <頂点シェーダー> // 頂点シェーダーの入力 struct VS_INPUT { float3 pos : POSITION0 ; // 座標( ローカル空間 ) float4 spos : POSITION1 ; // 予備座標 float3 norm : NORMAL0 ; // 法線( ローカル空間 ) float3 tan : TANGENT0 ; // 接線( ローカル空間 ) float3 binorm : BINORMAL0 ; // 従法線( ローカル空間 ) float4 dif : COLOR0 ; // ディフューズカラー float4 spc : COLOR1 ; // スペキュラカラー float2 texCoords0 : TEXCOORD0 ; // テクスチャ座標 float2 texCoords1 : TEXCOORD1 ; // サブテクスチャ座標 } ; // 頂点シェーダーの出力 struct VS_OUTPUT { float4 dif : COLOR0 ; // ディフューズカラー float2 texCoords0 : TEXCOORD0 ; // テクスチャ座標 float4 pos : SV_POSITION ; // 座標( プロジェクション空間 ) } ; // 基本パラメータ struct DX_D3D11_VS_CONST_BUFFER_BASE { float4 AntiViewportMatrix[ 4 ] ; // アンチビューポート行列 float4 ProjectionMatrix[ 4 ] ; // ビュー → プロジェクション行列 float4 ViewMatrix[ 3 ] ; // ワールド → ビュー行列 float4 LocalWorldMatrix[ 3 ] ; // ローカル → ワールド行列 float4 ToonOutLineSize ; // トゥーンの輪郭線の大きさ float DiffuseSource ; // ディフューズカラー( 0.0f:マテリアル 1.0f:頂点 ) float SpecularSource ; // スペキュラカラー( 0.0f:マテリアル 1.0f:頂点 ) float MulSpecularColor ; // スペキュラカラー値に乗算する値( スペキュラ無効処理で使用 ) float Padding ; } ; // その他の行列 struct DX_D3D11_VS_CONST_BUFFER_OTHERMATRIX { float4 ShadowMapLightViewProjectionMatrix[ 3 ][ 4 ] ; // シャドウマップ用のライトビュー行列とライト射影行列を乗算したもの float4 TextureMatrix[ 3 ][ 2 ] ; // テクスチャ座標操作用行列 } ; // 基本パラメータ cbuffer cbD3D11_CONST_BUFFER_VS_BASE : register( b1 ) { DX_D3D11_VS_CONST_BUFFER_BASE g_Base ; } ; // その他の行列 cbuffer cbD3D11_CONST_BUFFER_VS_OTHERMATRIX : register( b2 ) { DX_D3D11_VS_CONST_BUFFER_OTHERMATRIX g_OtherMatrix ; } ; // main関数 VS_OUTPUT main( VS_INPUT VSInput ) { VS_OUTPUT VSOutput ; float4 lLocalPosition ; float4 lWorldPosition ; float4 lViewPosition ; // 頂点座標変換 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++( 開始 ) // ローカル座標のセット lLocalPosition.xyz = VSInput.pos ; lLocalPosition.w = 1.0f ; // 座標計算( ローカル→ビュー→プロジェクション ) lWorldPosition.x = dot( lLocalPosition, g_Base.LocalWorldMatrix[ 0 ] ) ; lWorldPosition.y = dot( lLocalPosition, g_Base.LocalWorldMatrix[ 1 ] ) ; lWorldPosition.z = dot( lLocalPosition, g_Base.LocalWorldMatrix[ 2 ] ) ; lWorldPosition.w = 1.0f ; lViewPosition.x = dot( lWorldPosition, g_Base.ViewMatrix[ 0 ] ) ; lViewPosition.y = dot( lWorldPosition, g_Base.ViewMatrix[ 1 ] ) ; lViewPosition.z = dot( lWorldPosition, g_Base.ViewMatrix[ 2 ] ) ; lViewPosition.w = 1.0f ; VSOutput.pos.x = dot( lViewPosition, g_Base.ProjectionMatrix[ 0 ] ) ; VSOutput.pos.y = dot( lViewPosition, g_Base.ProjectionMatrix[ 1 ] ) ; VSOutput.pos.z = dot( lViewPosition, g_Base.ProjectionMatrix[ 2 ] ) ; VSOutput.pos.w = dot( lViewPosition, g_Base.ProjectionMatrix[ 3 ] ) ; // 頂点座標変換 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++( 終了 ) // 出力パラメータセット ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++( 開始 ) VSOutput.texCoords0 = VSInput.texCoords0 ; VSOutput.dif = VSInput.dif ; // 出力パラメータセット ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++( 終了 ) // 出力パラメータを返す return VSOutput ; } <ピクセルシェーダー> // ピクセルシェーダーの入力 struct PS_INPUT { float4 dif : COLOR0 ; // ディフューズカラー float2 texCoords0 : TEXCOORD0 ; // テクスチャ座標 } ; // ピクセルシェーダーの出力 struct PS_OUTPUT { float4 color0 : SV_TARGET0 ; // 色 } ; // 定数バッファピクセルシェーダー基本パラメータ struct DX_D3D11_PS_CONST_BUFFER_BASE { float4 FactorColor ; // アルファ値等 float MulAlphaColor ; // カラーにアルファ値を乗算するかどうか( 0.0f:乗算しない 1.0f:乗算する ) float AlphaTestRef ; // アルファテストで使用する比較値 float2 Padding1 ; int AlphaTestCmpMode ; // アルファテスト比較モード( DX_CMP_NEVER など ) int3 Padding2 ; float4 IgnoreTextureColor ; // テクスチャカラー無視処理用カラー } ; // 基本パラメータ cbuffer cbD3D11_CONST_BUFFER_PS_BASE : register( b1 ) { DX_D3D11_PS_CONST_BUFFER_BASE g_Base ; } ; SamplerState g_DiffuseMapSampler : register( s0 ) ; // ディフューズマップサンプラ Texture2D g_DiffuseMapTexture : register( t0 ) ; // ディフューズマップテクスチャ // main関数 PS_OUTPUT main( PS_INPUT PSInput ) { PS_OUTPUT PSOutput ; float4 TextureDiffuseColor ; // テクスチャカラーの読み込み TextureDiffuseColor = g_DiffuseMapTexture.Sample( g_DiffuseMapSampler, PSInput.texCoords0 ) ; // 出力カラー = テクスチャカラー * ディフューズカラー PSOutput.color0 = TextureDiffuseColor * PSInput.dif ; // 出力パラメータを返す return PSOutput ; } ( ピクセルシェーダーでは定数を一切使用していないので定数部分は記述する必要が無いのですが、 一応DXライブラリ側で用意している定数ということで記述してあります )
メンテ
Re: DxLibでシェーダーを使うにはどうすればいいのか? ( No.2 )
名前:たそたん 日時:2020/05/11 09:53

質問ですが検索するとよく出てくるスクリーン座標に変換する処理はGPUでするにはシェーダーでそのためのコードを書く必要があるのでしょうか?
メンテ
Re: DxLibでシェーダーを使うにはどうすればいいのか? ( No.3 )
名前:管理人 日時:2020/05/12 00:23

> 質問ですが検索するとよく出てくるスクリーン座標に変換する処理はGPUでするにはシェーダーでそのためのコードを書く必要があるのでしょうか? はい、ビューポート座標からスクリーン座標に変換する処理は Direct3D が行ってくれるのですが、 ワールド座標からビューポート座標に変換する処理は頂点シェーダーで行う必要があるので、 頂点シェーダーではそのためのコードを書く必要があります <ビューポート座標> 描画先の矩形領域を x軸の左右端をそれぞれ -1.0〜1.0、y軸の上下端をそれぞれ 1.0〜-1.0 で表した座標 <スクリーン座標> 画面の解像度に応じたピクセル座標( DXライブラリの座標と同じ x軸の左右端は 0〜横軸ピクセル数-1、y軸の上下端は 0〜縦軸ピクセル数-1 ) DirectX 9 まではシェーダーを使用しない場合に限りスクリーン座標を直接指定することも可能だったのですが、 シェーダーを使用する場合は頂点シェーダーで出力する座標はビューポート座標となっているために、 必ずビューポート座標に変換するコードを書く必要があります
メンテ
Re: DxLibでシェーダーを使うにはどうすればいいのか? ( No.4 )
名前:たそたん 日時:2020/05/12 21:01

追記2020/5/12 21 : 00 fxc.exe コンパイルエラーですが自分のタイプミスでした。 なるほどわかりました。質問ですが.zip形式で提示されたコードをfxc.exeでコンパイルしたところエラーが出ましてdxLibのToolにある ShaderComplierにてコンパイルを試しましたが"ターゲットmainが設定されていませんとエラーでてしまいます。"これはなぜでしょうか?/Tmainなどと設定 しましたがエラーが出てしまいます。.hlslファイルはファイル名だけ自分のわかりやすい名前に変更したたけで何も触っていません。コードは確認しました。 また別のサイトよりHLSLではなくGLSLに書き直すという回答を得ましたがdxlibににおけるシェーダー言語はどっちなのでしょうか? h ttps://teratail.com/questions/260700
メンテ
Re: DxLibでシェーダーを使うにはどうすればいいのか? ( No.5 )
名前:管理人 日時:2020/05/12 19:52

> なるほどわかりました。質問ですが.zip形式で提示されたコードをfxc.exeでコンパイルしたところエラーが出ましてdxLibのToolにある > ShaderComplierにてコンパイルを試しましたが"ターゲットmainが設定されていませんとエラーでてしまいます。"これはなぜでしょうか?/Tmainなどと設定 > しましたがエラーが出てしまいます。.hlslファイルはファイル名だけ自分のわかりやすい名前に変更したたけで何も触っていません。コードは確認しました。 ファイル名の変更などを一切行わない状態で zipファイルの中の ShaderPolygon3DTest_ShaderCompile.bat を実行してもエラーが 発生してしまいますでしょうか? > また別のサイトよりHLSLではなくGLSLに書き直すという回答を得ましたがdxlibににおけるシェーダー言語はどっちなのでしょうか? > h ttps://teratail.com/questions/260700 DXライブラリは DirectX を使用しているので HLSL です
メンテ
Re: DxLibでシェーダーを使うにはどうすればいいのか?(解決) ( No.6 )
名前:たそたん 日時:2020/05/12 21:04

追記しましたがコンパイルエラーは自分のタイプミスです。解決しました。ありがとうございました。
メンテ

Page: 1 |

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

   クッキー保存