トップページ > 記事閲覧
Live2Dで自作シェーダーを使いたい
名前:すね 日時: 2022/07/28 17:58

具体的には法線マップを用意してライティングをしてみたいと考えているのですが、可能でしょうか?
メンテ

Page: 1 |

Re: Live2Dで自作シェーダーを使いたい ( No.1 )
名前:管理人 日時:2022/07/29 01:28

すみません、現状の機能ではご要望の処理を実現することはできません ちょっと想像できないのですが、法線マップとライティングを行うことでどのような見た目になるのでしょうか…? ともあれ、法線マップとライティングを行う自作シェーダーをすねさんがご用意されて、 法線マップと自作シェーダーのファイルパスを関数に渡すと、その法線マップと自作シェーダーを使用して Live2D の描画が行なわれる、 というような形の機能でしたら追加することが可能かもしれません…
メンテ
Re: Live2Dで自作シェーダーを使いたい ( No.2 )
名前:すね 日時:2022/07/29 18:25

> 法線マップとライティングを行うことでどのような見た目になるのでしょうか…? ttps://note.com/7name/n/na2f41eb51908 こちらのリンクで解説されているソフトで出力されたような感じを想定しています。ただ、最後の方にも書かれているのですが、これでもまだ表現として甘い部分があるのでシェーダーや他のテクスチャ等を使用してより最適化した表現が出来たらなと考えています。 > 法線マップとライティングを行う自作シェーダーをすねさんがご用意されて、法線マップと自作シェーダーのファイルパスを関数に渡すと、その法線マップと自作シェーダーを使用して Live2D の描画が行なわれる、というような形の機能でしたら追加することが可能かもしれません… はい、それで大丈夫ですので是非お願いしたいです!
メンテ
Re: Live2Dで自作シェーダーを使いたい ( No.3 )
名前:管理人 日時:2022/07/31 03:18

> こちらのリンクで解説されているソフトで出力されたような感じを想定しています。 なるほど、了解しました > > 法線マップとライティングを行う自作シェーダーをすねさんがご用意されて、 > > 法線マップと自作シェーダーのファイルパスを関数に渡すと、その法線マップと自作シェーダーを使用して Live2D の描画が行なわれる、 > > というような形の機能でしたら追加することが可能かもしれません… > はい、それで大丈夫ですので是非お願いしたいです! ちょっとお話した内容とは異なる実装となりましたが、機能を追加できましたのでよろしければ こちらの機能追加版の暫定最新バージョンをダウンロードしてください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 10.3 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい) 以下の関数を追加しました // Live2D のモデル描画で使用するシェーダーを設定する // TargetShader : 設定対象のシェーダー // DX_LIVE2D_SHADER_SETUP_MASK_VERTEX : マスク画像生成用頂点シェーダー // DX_LIVE2D_SHADER_SETUP_MASK_PIXEL : マスク画像生成用ピクセルシェーダー // DX_LIVE2D_SHADER_NORMAL_VERTEX : 標準の頂点シェーダー // DX_LIVE2D_SHADER_NORMAL_VERTEX_MASKED : 標準の頂点シェーダー + マスク画像 // DX_LIVE2D_SHADER_NORMAL_PIXEL : 標準のピクセルシェーダー // DX_LIVE2D_SHADER_NORMAL_PIXEL_MASKED : 標準のピクセルシェーダー + マスク画像 // DX_LIVE2D_SHADER_NORMAL_PIXEL_MASKED_INVERTED : 標準のピクセルシェーダー + マスク画像( マスク画像の値を反転して使用 ) // DX_LIVE2D_SHADER_NORMAL_PIXEL_PREMULALPHA : 標準のピクセルシェーダー + テクスチャ画像が乗算済みアルファ // DX_LIVE2D_SHADER_NORMAL_PIXEL_MASKED_PREMULALPHA : 標準のピクセルシェーダー + テクスチャ画像が乗算済みアルファ + マスク画像 // DX_LIVE2D_SHADER_NORMAL_PIXEL_MASKED_INVERTEX_PREMULALPHA : 標準のピクセルシェーダー + テクスチャ画像が乗算済みアルファ + マスク画像( マスク画像の値を反転して使用 ) // ShaderHandle : 設定するシェーダーのハンドル( LoadVertexShader や LoadPixelShader で取得できるシェーダーハンドル )、-1を指定すると設定解除 int Live2D_SetUserShader( int TargetShader, int ShaderHandle ) ; // Live2D のモデル描画の前に呼ばれるコールバック関数を設定する // Callback : 描画の前に呼ばれるコールバック関数( NULL を指定すると設定解除 ) // UserData : コールバック関数の第三引数として渡される void 型のアドレス int Live2D_DrawCallback( void ( *Callback )( int Live2DModelHandle, int TextureIndex, void *UserData ), void *UserData ) ; Live2D_SetUserShader でオリジナルのシェーダーを設定します 標準の状態でも種類が 10個もあるので、オリジナルシェーダーに変更する場合は、オリジナルのシェーダーも10個用意することになります ( ただ、DX_LIVE2D_SHADER_SETUP_MASK_VERTEX と DX_LIVE2D_SHADER_SETUP_MASK_PIXEL はデフォルトのままでも良いかもしれません ) 法線マップは恐らく描画に使用されるテクスチャに応じて変更する必要があると思いますので、描画前に呼ばれるコールバック関数を Live2D_DrawCallback でセットして、コールバック関数の中で SetUseTextureToShader でシェーダー内で使用するテクスチャを変更します 上記の関数を使用して『テクスチャ番号0の箇所は緑色を、テクスチャ番号1の箇所は赤色を加算する』サンプルを 作成してみましたので、よろしければダウンロードしてください m(_ _)m https://dxlib.xsrv.jp/temp/Live2D_UserShader.zip 中に含まれている Live2D_UserShader.cpp の内容は以下のようになっています #include "DxLib.h" int AddColorSpeed = 2 ; int AddColor = 0 ; int ConstantBuffer ; // Live2D の描画処理の前に呼ばれるコールバック関数 void Live2DDrawCallback( int Live2DModelHandle, int TextureIndex, void *UserData ) { FLOAT4 TempAddColor ; // 使用するテクスチャーによって加算色を変更する if( TextureIndex == 0 ) { // テクスチャー No.0 の場合は緑に反映 TempAddColor.x = 0.0f ; TempAddColor.y = AddColor / 255.0f ; TempAddColor.z = 0.0f ; TempAddColor.w = 0.0f ; } else { // テクスチャー No.1 の場合は赤に反映 TempAddColor.x = AddColor / 255.0f ; TempAddColor.y = 0.0f ; TempAddColor.z = 0.0f ; TempAddColor.w = 0.0f ; } if( GetUseDirect3DVersion() == DX_DIRECT3D_11 ) { // Direct3D 11 の場合は定数バッファに加算色をセット FLOAT4 *ConstantBuffer_AddColor = ( FLOAT4 * )GetBufferShaderConstantBuffer( ConstantBuffer ) ; // 加算色を定数バッファに書き込み *ConstantBuffer_AddColor = TempAddColor ; // 定数バッファへの変更を反映 UpdateShaderConstantBuffer( ConstantBuffer ) ; // 定数バッファをピクセルシェーダーのスロット4にセット SetShaderConstantBuffer( ConstantBuffer, DX_SHADERTYPE_PIXEL, 4 ) ; } else { // Direct3D 9 の場合はピクセルシェーダーの定数レジスタ16番に加算色をセット SetPSConstF( 16, TempAddColor ) ; } } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int ModelHandle ; int ShaderHandle[ DX_LIVE2D_SHADER_NUM ] ; // ウィンドウモードで起動 ChangeWindowMode( TRUE ) ; // 画面解像度を設定 SetGraphMode( 1920, 1080, 32 ) ; // Live2D Cubism Core DLL の読み込み( 64bit アプリの場合と 32bit アプリの場合で読み込む dll を変更 ) #ifdef _WIN64 Live2D_SetCubism3CoreDLLPath( "D:/Live2D/Cubism3SDKforNative-beta12-1/Core/dll/windows/x86_64/Live2DCubismCore.dll" ) ; #else Live2D_SetCubism3CoreDLLPath( "D:/Live2D/Cubism3SDKforNative-beta12-1/Core/dll/windows/x86/Live2DCubismCore.dll" ) ; #endif // DXライブラリ初期化処理 if( DxLib_Init() == -1 ) { return -1 ; } // 独自シェーダーの読み込み if( GetUseDirect3DVersion() == DX_DIRECT3D_11 ) { // Direct3D 11 の場合は Direct3D 11 用のシェーダーバイナリを読み込む ShaderHandle[ DX_LIVE2D_SHADER_SETUP_MASK_VERTEX ] = LoadVertexShader( "Direct3D11\\Live2DShader_VertSetupMask.vso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_SETUP_MASK_PIXEL ] = LoadPixelShader( "Direct3D11\\Live2DShader_PixelSetupMask.pso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_VERTEX ] = LoadVertexShader( "Direct3D11\\Live2DShader_VertNormal.vso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_VERTEX_MASKED ] = LoadVertexShader( "Direct3D11\\Live2DShader_VertMasked.vso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_PIXEL ] = LoadPixelShader( "Direct3D11\\Live2DShader_PixelNormal.pso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_PIXEL_MASKED ] = LoadPixelShader( "Direct3D11\\Live2DShader_PixelMasked.pso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_PIXEL_MASKED_INVERTED ] = LoadPixelShader( "Direct3D11\\Live2DShader_PixelMaskedInverted.pso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_PIXEL_PREMULALPHA ] = LoadPixelShader( "Direct3D11\\Live2DShader_PixelNormalPremult.pso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_PIXEL_MASKED_PREMULALPHA ] = LoadPixelShader( "Direct3D11\\Live2DShader_PixelMaskedPremult.pso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_PIXEL_MASKED_INVERTEX_PREMULALPHA ] = LoadPixelShader( "Direct3D11\\Live2DShader_PixelMaskedInvertedPremult.pso" ) ; } else { // Direct3D 9 の場合は Direct3D 9 用のシェーダーバイナリを読み込む ShaderHandle[ DX_LIVE2D_SHADER_SETUP_MASK_VERTEX ] = LoadVertexShader( "Direct3D9\\Live2DShader_VertSetupMask.vso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_SETUP_MASK_PIXEL ] = LoadPixelShader( "Direct3D9\\Live2DShader_PixelSetupMask.pso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_VERTEX ] = LoadVertexShader( "Direct3D9\\Live2DShader_VertNormal.vso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_VERTEX_MASKED ] = LoadVertexShader( "Direct3D9\\Live2DShader_VertMasked.vso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_PIXEL ] = LoadPixelShader( "Direct3D9\\Live2DShader_PixelNormal.pso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_PIXEL_MASKED ] = LoadPixelShader( "Direct3D9\\Live2DShader_PixelMasked.pso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_PIXEL_MASKED_INVERTED ] = LoadPixelShader( "Direct3D9\\Live2DShader_PixelMaskedInverted.pso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_PIXEL_PREMULALPHA ] = LoadPixelShader( "Direct3D9\\Live2DShader_PixelNormalPremult.pso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_PIXEL_MASKED_PREMULALPHA ] = LoadPixelShader( "Direct3D9\\Live2DShader_PixelMaskedPremult.pso" ) ; ShaderHandle[ DX_LIVE2D_SHADER_NORMAL_PIXEL_MASKED_INVERTEX_PREMULALPHA ] = LoadPixelShader( "Direct3D9\\Live2DShader_PixelMaskedInvertedPremult.pso" ) ; } // 独自シェーダーを Live2D の描画用にセット for( int i = 0 ; i < DX_LIVE2D_SHADER_NUM ; i ++ ) { Live2D_SetUserShader( i, ShaderHandle[ i ] ) ; } // 定数バッファの作成( Direct3D 11 の場合だけ作成 ) if( GetUseDirect3DVersion() == DX_DIRECT3D_11 ) { ConstantBuffer = CreateShaderConstantBuffer( sizeof( FLOAT4 ) ) ; } // Live2D の描画時に呼ばれるコールバック関数をセット Live2D_DrawCallback( Live2DDrawCallback, NULL ) ; // Live2Dモデルの読み込み ModelHandle = Live2D_LoadModel( "D:/Live2D/Cubism3SDKforNative-beta12-1/Samples/Res/Hiyori/Hiyori.model3.json" ) ; // 描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; // メインループ while( ProcessMessage() == 0 ) { // 画面の初期化 ClearDrawScreen() ; // モーション再生が終了していたらアイドリングモーションをランダムで再生 if( Live2D_Model_IsMotionFinished( ModelHandle ) == TRUE ) { Live2D_Model_StartMotion( ModelHandle, "Idle", GetRand( 8 ) ) ; } // モデルの状態を60分の1秒分進める Live2D_Model_Update( ModelHandle, 1 / 60.0f ) ; // Live2D描画の開始 Live2D_RenderBegin() ; // 加算色の推移 AddColor += AddColorSpeed ; if( AddColor >= 255 ) { AddColor = 255 ; AddColorSpeed = -AddColorSpeed ; } else if( AddColor <= 0 ) { AddColor = 0 ; AddColorSpeed = -AddColorSpeed ; } // Live2Dモデルの描画 Live2D_Model_Draw( ModelHandle ) ; // Live2D描画の終了 Live2D_RenderEnd() ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // Live2D モデルの削除 Live2D_DeleteModel( ModelHandle ) ; // DXライブラリ使用の終了処理 DxLib_End() ; // ソフトの終了 return 0 ; } Live2D SDK のフォルダとして D:/Live2D/Cubism3SDKforNative-beta12-1 を指定していますので、 この部分はすねさんの環境に合わせて書き換えてください まずオリジナルのシェーダーコードバイナリを LoadVertexShader や LoadPixelShader で読み込むのですが、 DXライブラリは Direct3D 11 を使用する場合と、Direct3D 9 を使用する場合があり、それぞれのバージョンで シェーダーの仕様が異なるので、GetUseDirect3DVersion() の戻り値が DX_DIRECT3D_11 かどうかで 読み込むシェーダーコードバイナリファイルを分けています その後 Live2D_SetUserShader で読み込んだシェーダーコードを Live2D の描画用に設定します このサンプルは緑色や赤色を画像に加算する処理をシェーダーの定数機能を使用して実現しているのですが、 Direct3D 9 は定数レジスタ、Direct3D 11 は定数バッファを使用することになるので、Direct3D 11 の場合のみ CreateShaderConstantBuffer で定数バッファハンドルを作成しています Live2D_DrawCallback で Live2D の描画前に呼ばれるように設定している関数 Live2DDrawCallback の中では 引数のテクスチャ番号( TextureIndex ) に応じて緑色 or 赤色を SetShaderConstantBuffer や SetPSConstF を使用して 定数バッファや定数レジスタに設定しています ライティングを行う場合は、恐らくこの関数の中で法線マップのテクスチャを SetUseTextureToShader で 設定することになると思います シェーダーコードバイナリファイルは Live2D_UserShader.zip の中にある Direct3D9\ShaderCompile.bat Direct3D11\ShaderCompile.bat を実行することで作成します Direct3D 9 用のシェーダーコードは Direct3D9\ShaderCode.fx Direct3D 11 用のシェーダーコードは Direct3D11\ShaderCode.hlsl となっています こちらの2つのファイルは Live2D SDK のサンプルにある標準シェーダーコードに、定数の addColor を 加算する処理を追加しただけとなっていますので、基本的にはこちらの2つのファイルを改造する形で ライティングの処理を追加していただくのが良いと思います もし不明な点や不足している機能などありましたら言ってください m(_ _)m
メンテ
Re: Live2Dで自作シェーダーを使いたい ( No.4 )
名前:すね 日時:2022/07/31 20:02

さっそくありがとうございます!今から色々試してみようと思います! ざっとコードを見て一つ質問なのですが、コード内のDirect3D11用の部分で定数バッファを4番のスロットにセットしていますが、1、2、3番にはライブラリ側で既に何か入れているのでしょうか?
メンテ
Re: Live2Dで自作シェーダーを使いたい ( No.5 )
名前:管理人 日時:2022/07/31 22:31

> ざっとコードを見て一つ質問なのですが、コード内のDirect3D11用の部分で定数バッファを4番のスロットにセットしていますが、1、2、3番にはライブラリ側で既に何か入れているのでしょうか? はい、0,1,2,3番 はライブラリ側で使用していますので、4番以降を使用してください m(_ _)m
メンテ

Page: 1 |

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

   クッキー保存