トップページ > 過去ログ > 記事閲覧
αチャンネル付き描画可能画像について
名前:yasi 日時: 2011/10/24 14:45

いつもお世話になっております。 αチャンネル付き描画可能画像(バッファ)について2つほど質問させていただきます。 1つ目はVer3.06以降、MakeScreenの第三引数としてαチャンネルの有無に関するフラグが追加されましたが、 これは、従来のSetDrawValidAlphaChannelGraphCreateFlagを使用した後にMakeScreenを行う物を 簡易化した物と捉えればよろしいでしょうか? (掲示板等に特にこれに関する記述が無さそうなので確認させていただきました。) もう1つは、上記のように作成されたαチャンネル付き描画可能画像(バッファ)に対し、 MV1DrawModelでモデル描画を行った場合、 透過要素を含まないメッシュ(以下、通常メッシュ)より手前に 透過要素を含むメッシュ(以下、透過メッシュ)があると、 通常メッシュで書き込まれたα値に、乗算か無視されて上書きされているようです。 (結果としてその部分は背景が透けて見えてしまいます。) 恐らくは透過メッシュ(マテリアル)の描画順による物と思われますが、 これは仕様という事なのでしょうか? できればα値に関しては加算という結果が望めればと思っているのですが。 実験的にプログラム上で透過メッシュと通常メッシュの描画順を逆にした物と、 通常描画の物の2回を描画し、結果のα値を1ピクセルずつ差換えるというのも行ってみましたが、 それなりのマシンパワーを取られてしまう為、現実的ではありませんでした。 以上2点の質問と、もし仕様であるとしても何か良い方法等あればお答えいただけますよう、 よろしくおねがいします。 確認DxLib Ver3.06c

Page: 1 |

Re: αチャンネル付き描画可能画像について ( No.1 )
名前:管理人 日時:2011/10/30 21:00

> 1つ目はVer3.06以降、MakeScreenの第三引数としてαチャンネルの有無に関するフラグが追加されましたが、 > これは、従来のSetDrawValidAlphaChannelGraphCreateFlagを使用した後にMakeScreenを行う物を > 簡易化した物と捉えればよろしいでしょうか? > (掲示板等に特にこれに関する記述が無さそうなので確認させていただきました。) はい、そう考えて頂いて問題ありません MakeScreen は SetDrawValidGraphCreateFlag と MakeGraph を使って描画可能画像を作成する処理を 簡略化する関数だったのですが、アルファチャンネルを含んだ描画可能画像を作ることも一般的になるだろうと思って、 引数に UseAlphaChannel を加えて内部で使う関数に SetDrawValidAlphaChannelGraphCreateFlag が加わりました > アルファ値の加算 DirectX の機能を調べてみましたが、アルファ値の加算を素直に実現するには GeFroce の場合は 6000シリーズ以降 Radeon の場合は 9000シリーズ以降 Intelチップセットの場合は大体 2008年以降のチップ でないと存在しない機能を使う必要があるということで、シェーダーモデル2.0よりもGPUに求める敷居が高くなります もしそれでも yasiさんがお使いになるということでしたら機能を追加してみようと思います (・・; その機能を使う以外の方法では・・・仮にシェーダーを使った場合でもyasiさんが試された方法と 同じくらいの処理負荷が掛かるものしか思いつきませんでした (_ _;
Re: αチャンネル付き描画可能画像について ( No.2 )
名前:yasi 日時:2011/10/31 23:35

管理人様、ご回答ありがとうございます。 α値の加算についてはお話からすると、以前別のαに関するスレッドで出ていた話の絡みのようですね。 GPUの敷居値としてはDirectX9.0c正式対応辺りからといった感じでしょうか。 私としては現在とあるデスクトップマスコットアプリの3D描画モジュールの製作をしており、 その関係上、UpdateLayerdWindow等も使用している為、CUPに関しても必要スペックとしてCore2以上を想定しています。 そういった意味でオンボードは別としても年代的にGPU側の敷居値は問題ないと判断しています。 最終的に総合での必要スペックは実際に組んでみてからでなければ判らないところですが、 比較的低いコストで回せるようであればアウトラインにもアンチエイリアスの掛かった ジャギーの無い描画をする事ができるようになるので、 可能であれば是非実装をお願いしたいと思います。 勿論、他の案件も多いようですし急ぎませんのでよろしくお願いします。
Re: αチャンネル付き描画可能画像について ( No.3 )
名前:管理人 日時:2011/11/07 00:07

デスクトップマスコットとなると、最終的に作成したアルファチャンネル付きの画像を使用して デスクトップ上で半透明が反映されるようにするということですよね? だとしますと、正確な透明度を反映するにはα値の加算の機能だけでは実現できません Dr,Dg,Db,Da ← 出力先に書き込まれるR:G:B:A値( 0〜255 を 0.0f〜1.0f で表します ) Sr,Sg,Sb,Sa ← 書き込むR:G:B:A値( 0〜255 を 0.0f〜1.0f で表します ) Ta ← ローカル変数的なものと考えてください 1.既存のαブレンド描画で描画先に格納される値 Dr = ( 1.0 - Sa ) * Dr + Sa * Sr Dg = ( 1.0 - Sa ) * Dg + Sa * Sg Db = ( 1.0 - Sa ) * Db + Sa * Sb Da = ( 1.0 - Sa ) * Da + Sa * Sa 2.アルファ値を加算にして描画した場合の描画先に格納される値 Dr = ( 1.0 - Sa ) * Dr + Sa * Sr Dg = ( 1.0 - Sa ) * Dg + Sa * Sg Db = ( 1.0 - Sa ) * Db + Sa * Sb Da = Da + Sa 3.正確にデスクトップに描画画像の透明度を反映させる場合の描画先に格納される値 Ta = ( 1.0 - Sa ) * Da + Sa Dr = ( ( 1.0 - Sa ) * Da * Dr + Sa * Sr ) / Ta Dg = ( ( 1.0 - Sa ) * Da * Dg + Sa * Sg ) / Ta Db = ( ( 1.0 - Sa ) * Da * Db + Sa * Sb ) / Ta Da = Ta 1が現時点の計算式で、2が前回お話した DirectX の機能を使用した場合の式で、3が正確な計算結果を導き出すための式です 結構違いますので、恐らくα値の加算の機能を使用して描画しても「不自然に透明にならなくなったけど何か変」な 表示結果になると思います 例えば、デスクトップに真っ白の四角形を透明度50%で表示したいとします それを真っ黒(0)の何も描かれていない描画可能画像に透明度50%(128)で真っ白(255)の四角を描画したものを デスクトップに UpdateLayerdWidnow で表示することを想定すると、まず描画バッファに書き込まれる内容は 真っ黒な何も描かれていない描画可能画像 Dr=0 Dg=0 Db=0 Da=0 真っ白の透明度50%の四角形の色 Sr=1.0 Sg=1.0 Sb=1.0 Sa=0.5 描画結果 Dr = ( 1.0 - 0.5 ) * 0.0 + 0.5 * 1.0 = 0.5 Dg = ( 1.0 - 0.5 ) * 0.0 + 0.5 * 1.0 = 0.5 Db = ( 1.0 - 0.5 ) * 0.0 + 0.5 * 1.0 = 0.5 Da = 0 + 0.5 = 0.5 と、R:G:B:A すべてが 0.5 になり、これを UpdateLayerdWindow で表示した場合、デスクトップの画像と 合成されるのは透明度50%(128)の灰色(128)の四角ということになります これを希望通りの真っ白の半透明の四角をデスクトップ画面に表示するには上記の3の式で描画を行う必要があります そして3の式を使った結果は前回見つけた DirectX の機能をポンと使うだけでは得ることができません というわけで、DirectX の機能を直で使えるようにすれば済むと考えていたので今回の週末中に 実装することができませんでした・・・ 要点を述べますと・・・すみませんがもうしばらくお時間をください m(_ _;m
Re: αチャンネル付き描画可能画像について ( No.4 )
名前:yasi 日時:2011/11/07 04:39

ご回答ありがとうございます。 ご指摘頂いた通り、背景とのブレンド結果では正確な値にはならない事は承知しておりました。 その為、仕様として背景に掛かるような大きな透過マテリアルを設定したメッシュの含まれるモデルは 現段階で保障しない予定で進めておりました。 しかし、眼鏡や髪の毛の影用に設定されたキャラクタに密着しているような透過メッシュの場合であれば、 透過メッシュの奥に必ず透過要素の無い通常メッシュがあるという前提で α値の加算のみで現状と同じカラー情報でアンチエイリアスの掛かったα値を元に、 ジャーギーの無い綺麗に抜いた形でUpdateLayerdWindowを使用できるという意図で要望させていただきました。 ですので、どちらかというとアンチエイリアスの掛かった比較的まともなα値を安価に取得したいという 意味合いの要望だと考えていただいて結構です。 とは言え、管理人様もお考えの通りデスクトップ上にULWで描画した状態での正常なα+RGB値の 安価な実現というのは、勿論可能であれば望んでいる物ではあります。 しかしながら、3DCG自体が元々、何かしらの背景の上にレンダリングされる事を前提に 考えられてきた物ではあるので、一筋縄ではいかない事も承知しております。 (そういった意味ではPhotoshopでは安易ではない合成チャンネル処理ができるAfterEffectsは とても重宝するわけですが・・・) 話がそれましたが、多くは望みませんし急ぎませんので可能な限りで宜しくお願いします。
Re: αチャンネル付き描画可能画像について ( No.5 )
名前:管理人 日時:2011/11/20 15:03

すみません、まだ少しだけ事情を把握できずにいます No.2にありますアルファ値の加算の機能があるとアウトラインにアンチエイリアスを 掛ける事ができる、というのはどのように実現するのでしょうか? ともあれ、正確なアルファ値の重ね合わせは実現できたのですが、 負荷はとても高いものとなりました・・・ 通常描画より少し重いくらいで実現する方法もあったのですが、それを 実装しようとするとモデルの描画用シェーダー関係に若干大きめの変更が必要だったので、 簡易的に実現する方法を実装したら重い物になってしまいました・・・ なので、当初のご要望にありましたアルファ値の加算の機能をお使い頂くのが良いかも知れません ただ件の機能は動作する環境の敷居が若干高く、今のところDXライブラリには関数として 機能を追加する予定はありませんので、申し訳ありませんが Direct3DDevice9 のAPIを直接呼んでください こちらの3行を実行すると、GPUが対応していればアルファ値が加算される状態になります 書き込むアルファ値の設定を変更する機能は今のところDXライブラリでは使用していないので、 DXライブラリの設定と競合する心配はありません GetUseDirect3DDevice9()->SetRenderState( D_D3DRS_SEPARATEALPHABLENDENABLE, TRUE ) ; GetUseDirect3DDevice9()->SetRenderState( D_D3DRS_SRCBLENDALPHA, D_D3DBLEND_ONE ) ; GetUseDirect3DDevice9()->SetRenderState( D_D3DRS_DESTBLENDALPHA, D_D3DBLEND_ONE ) ; あと、アルファチャンネル専用のブレンド設定にGPUが対応しているかどうかは デバイスの能力を調べるAPIの GetDeviceCaps を使うことで知ることができます D_D3DCAPS9 Caps ; GetUseDirect3DDevice9()->GetDeviceCaps( &Caps ) ; if( ( Caps.PrimitiveMiscCaps & D_D3DPMISCCAPS_SEPARATEALPHABLEND ) != 0 ) { // GPUが対応している } else { // GPUが対応していない } GetUseDirect3DDevice9 はDXライブラリの関数で最近追加したものですので、 お手数ですがこちらのバージョンをお使いになってください m(_ _)m http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibGCCTest.exe // Dev-C++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibMinGWTest.exe // MinGW 用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』を、VCをお使いの場合は『リビルド』を、 Dev-C++をお使いの方は「Rebuild All(Ctrl+F11)」をして下さい) あと、描画結果のデスクトップへの表示を少し高速化する GraphFilter のタイプ DX_GRAPH_FILTER_PREMUL_ALPHA と関数を追加しました UpdateLayerdWindow ではOSにアルファ値の影響を反映したRGB値を持つ画像を渡す必要があるのですが、 DXライブラリで普段使用する画像はアルファ値の影響を反映する前のRGB値となっているので、 OSに画像を渡す前に、アルファ値の影響を反映していないRGB値から影響を反映したRGB値に 変換する必要があります アルファ値の影響が反映していないRGB値の例 A = 128 R = 255 G = 110 B = 53 ↓アルファ値の影響を反映( 反映後の値 = ( 反映前の値 * A ) / 255 ) A = 128 R = 128 G = 55 B = 26 この処理を普段はCPUで行うのですが、この処理を行う GraphFilter 関数用のフィルタータイプ DX_GRAPH_FILTER_PREMUL_ALPHA を追加しました、これを使うことでシェーダー2.0以降が使える 環境であればアルファ値の影響を反映した値の画像への変換が高速になります あと、UpdateLayerdWindowForSoftImage の中で行っていたアルファ値の影響を反映させる処理を 事前に行っている画像を UpdateLayerdWindowForSoftImage に渡すための関数 UpdateLayerdWindowForPremultipliedAlphaSoftImage を追加しました 合わせると使い方の例としては以下のようになります <<変数説明>> int DrawScreenHandle ; // MakeScreen で作成した、描画結果が格納されている描画可能画像 int SoftImageHandle ; // MakeARGB8ColorSoftImage で作成した UpdateLayerdWindow 用のソフトウェア画像 <<描画処理が終わってから UpdateLayerdWindowForPremultipliedAlphaSoftImage を使うまでの流れ>> // アルファ値の影響を反映していないRGB値からアルファ値の影響を反映しているRGB値に変換 GraphFilter( DrawScreenHandle, DX_GRAPH_FILTER_PREMUL_ALPHA ) ; // 描画先を DrawScreenHandle に変更 SetDrawScreen( DrawScreenHandle ) ; // 描画先である DrawScreenHandle の内容をソフトウエアイメージに取り込む GetDrawScreenSoftImage( 0, 0, 640/* 画面の幅 */, 480/* 画面の高さ */, SoftImageHandle ) ; // 取り込んだソフトウエアイメージをデスクトップに表示 UpdateLayerdWindowForPremultipliedAlphaSoftImage( SoftImageHandle ) ; よろしければお使いください m(_ _)m 最後に、今回追加した負荷の高い正確にアルファ値を重ね合わせる方法についても一応ご解説します <準備> 1.3Dモデルの透明要素を持つマテリアルの描画ブレンドモードを DX_BLENDMODE_SRCCOLOR に変更   ( 使用する関数 MV1SetMaterialDrawBlendMode ) 2.アルファチャンネル付き描画可能画像を2つ作成   ( 使用する関数 MakeScreen ) <実行時> 1.アルファチャンネル付き描画可能画像Aに3Dモデルの透明要素の無いメッシュをすべて描画 2.アルファチャンネル付き描画可能画像Bに3Dモデルの透明要素のあるメッシュを一つ描画 3.GraphBlend をブレンドタイプ DX_GRAPH_BLEND_NORMAL_ALPHACH で使用して   アルファチャンネル付き描画可能画像Aにアルファチャンネル付き描画可能画像Bを   正確な計算でブレンド   ( DX_GRAPH_BLEND_NORMAL_ALPHACH は今回追加したブレンドタイプです ) 4.透明要素のあるメッシュがまだある場合はアルファチャンネル付き描画可能画像Bを   ClearDrawScreen でクリアした後、2に戻る 5.アルファチャンネル付き描画可能画像Aが完成画像 という感じです 実行時の2〜4については、透明要素のあるメッシュ同士が重なることがないのであれば2で すべての透明要素のあるメッシュを描画してしまうことで2〜4のループを1回に抑えることができます で、「シェーダー関係に若干大き目の変更」を施せば描画可能画像は一つで済み、普通の描画と同じように 不透明のメッシュを描画した後透明要素のあるメッシュを描画するだけで良くなる( 3の部分をモデルの 描画処理に含めてしまうことで別バッファに描画してからブレンドという手間を省く )ので、 いずれ実装したいと思います
Re: αチャンネル付き描画可能画像について ( No.6 )
名前:yasi 日時:2011/11/26 19:35

多数の関連機能を実装していただきありがとうございました。 >No.2にありますアルファ値の加算の機能があるとアウトラインにアンチエイリアスを >掛ける事ができる、というのはどのように実現するのでしょうか? 今回私が作成しているような、MV1モデルのリアルタイムレンダリングによるデスクトップマスコットの場合、 αチャンネル無しの通常描画可能画像に対して、SetDrawValidMultiSample等でアンチエイリアスを掛けても、 ULW時にカラーキーでしか背景を抜けない為、どうしても外周部にジャギが出てしまいます。 一方で、α付き描画可能画像にアンチエイリアスを掛ければ、α値にも同時にアンチエイリアスが掛かるので、 ULW時にα値で背景を抜けばジャギを無くす事ができますが、 透過要素無しメッシュよりカメラ側に透過要素有りメッシュが重なるとRGB値と同じように書き換えられていた為、 せめてα値が加算であればその部分をクリアできる、という内容の物でした。 言葉足らずで申し訳ありません。 早速、今回実装していただいた機能を一通り使用させていただき、 GetUseDirect3DDevice9等で私の望む結果を得る事ができました。 高速化への機能も追加していただき感謝しております。ありがとうございました。 しかし、最期に説明していただいたGraphBlend等を使用する正確にα値を重ねる方法について テストを行っている際に気になる点がありましたので確認させてください。 これは今回実装していただいた内容に直接関わる事では無いとは思いますが…。 SetDrawValidMultiSample(FSAA含む)を使用した描画可能画像に対しGraphBlendを使用すると、 正常に動作しない事があるようですがアンチエイリアスは使えないのでしょうか? (GraphBlendの戻り値は0が返って来ていますが、画像がブレンドされませんでした。) 又、GraphBlendでのブレンドではZバッファ値は無視されてしまうのでしょうか? テストではカメラ側からZ方向へ透過有り>透過無し>透過有りの順に少しずつ重なって並んでいるメッシュを 説明にある順で描画・ブレンドを行いましたが、 描画結果は透過有り>透過有り>透過無しのような描画結果が得られました。 透過有りが透過無しより奥にある場合、透過無しより先に奥にある透過有りを描画する必要があるのでしょうか? 今回最期に説明していただいた部分のテストに使用したコードとモデルを以下のアドレスにアップしましたので、 処理の順番など、まずい部分などあれば指摘いただけると助かります。 尚、テストコードでは透過有りメッシュのZ値に関して、奥側から描画される順にメッシュ番号が並んでいる事を 事前に確認していますので、コード内でメッシュの位置は確認しておりません。 テストコード&モデル //members2.jcom.home.ne.jp/mydimension/anti_test.zip
Re: αチャンネル付き描画可能画像について ( No.7 )
名前:管理人 日時:2011/11/27 21:33

ご希望の処理を実現することができたようで何よりです > 一方で、α付き描画可能画像にアンチエイリアスを掛ければ、α値にも同時にアンチエイリアスが掛かるので、 > ULW時にα値で背景を抜けばジャギを無くす事ができますが、 > 透過要素無しメッシュよりカメラ側に透過要素有りメッシュが重なるとRGB値と同じように書き換えられていた為、 > せめてα値が加算であればその部分をクリアできる、という内容の物でした。 > 言葉足らずで申し訳ありません。 なるほど、α付き描画可能画像を使用して透過ウインドウを実装した場合の不都合があったのですね というか少し考えれば分かることでした、すいません > SetDrawValidMultiSample(FSAA含む)を使用した描画可能画像に対しGraphBlendを使用すると、 > 正常に動作しない事があるようですがアンチエイリアスは使えないのでしょうか? > (GraphBlendの戻り値は0が返って来ていますが、画像がブレンドされませんでした。) アンチエイリアス付き描画可能画像を GraphBlend や GraphFilter で使用した場合に正常に動作しないというバグがありました orz 修正版をアップしましたので、よろしければお使いください m(_ _;m http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibGCCTest.exe // Dev-C++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibMinGWTest.exe // MinGW 用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』を、VCをお使いの場合は『リビルド』を、 Dev-C++をお使いの方は「Rebuild All(Ctrl+F11)」をして下さい) > 又、GraphBlendでのブレンドではZバッファ値は無視されてしまうのでしょうか? こちらも申し訳ありません、前回の書き込みはZバッファに関する手順が丸々抜けていました orz 正しくは以下のようになります <準備> 1.3Dモデルの透明要素を持つマテリアルの描画ブレンドモードを DX_BLENDMODE_SRCCOLOR に変更   ( 使用する関数 MV1SetMaterialDrawBlendMode ) 2.α値付き描画可能画像を2つ(仮にAとBとします)作成   ( 使用する関数 MakeScreen ) 3.α値付き描画可能画像Aに付属するZバッファを作成する   ( 使用する関数 SetUseGraphZBuffer ) <実行時> 1.α値付き描画可能画像Aを描画対象に、付属するZバッファを描画先Zバッファにする   ( 使用する関数 SetDrawScreen, SetDrawZBuffer ) 2.α値付き描画可能画像Aに3Dモデルの透明要素の無いメッシュをすべて描画 3.α値付き描画可能画像Bを描画対象にする( 描画先Zバッファはα値付き描画可能画像Aの付属Zバッファのまま )   ( 使用する関数 SetDrawScreen ) 4.α値付き描画可能画像Bに3Dモデルの透明要素のあるメッシュを一つ描画 5.GraphBlend をブレンドタイプ DX_GRAPH_BLEND_NORMAL_ALPHACH で使用して   α値付き描画可能画像Aにα値付き描画可能画像Bを正確な計算でブレンド   ( DX_GRAPH_BLEND_NORMAL_ALPHACH は今回追加したブレンドタイプです ) 6.透明要素のあるメッシュがまだある場合はα値付き描画可能画像Bを ClearDrawScreen でクリアした後、4に戻る   ( SetDrawZBuffer( -1 ) ; で使用するZバッファをデフォルトに戻した後 ClearDrawScreen() ;、    その後 SetDrawZBuffer で再度α値付き描画可能画像A付属のZバッファを描画先Zバッファに設定 ) 7.α値付き描画可能画像Aが完成画像 上記の説明で出てくる SetUseGraphZBuffer と SetDrawZBuffer は以下のような関数になっています // グラフィック専用のZバッファを持つかどうかを設定する( 描画可能画像のみ可能 ) // GrHandle : Zバッファの使用の有無を設定するグラフィックハンドル // UseFlag : 使用の有無( TRUE:使用する FALSE:使用しない ) int SetUseGraphZBuffer( int GrHandle, int UseFlag ) ; // 描画先Zバッファのセット( DrawScreen 付属のZバッファを描画先Zバッファにする、DrawScreen を -1 にするとデフォルトの描画先Zバッファに戻る ) int SetDrawZBuffer( int DrawScreen ) ; 通常Zバッファは常に裏画面用のZバッファを使用しますが、SetUseGraphZBuffer で描画可能画像専用の Zバッファを作成することができ、それを SetDrawZBuffer で実際に使用することができます 今回の例では、途中描画先を合成処理用のバッファにしつつも、Zバッファ自体は最初から最後まで 同じものを使う必要があるので、α値付き描画可能画像Aに専用のZバッファを作成して、それを常に使うようにしています アップして頂いたテストコードに SetUseGraphZBuffer と SetDrawZBuffer を使用して正しい結果が得られるように してみましたので( あと UpdateLayerdWindowForPremultipliedAlphaSoftImage も使ってみました )、 よろしければご覧になってください m(_ _)m ( 変更や追加の箇所には *** 追加 *** というような記述付きのコメントをしました ) #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int ModelHandle; int acsh, bsh1, bsh2; int MeshNum; ChangeWindowMode( TRUE ); SetAlwaysRunFlag( TRUE ); SetUseBackBufferTransColorFlag( TRUE ); SetGraphMode( 800, 600, 32 ); if ( DxLib_Init() < 0 ) return -1; SetBackgroundColor( 0, 0, 0 ); SetTransColor( 0, 255, 0 ); ModelHandle = MV1LoadModel( "SimpleModel2.mqo" ); MV1SetPosition( ModelHandle, VGet( 320.0f, 300.0f, 600.0f ) ); acsh = MakeARGB8ColorSoftImage( 800, 600 ); // ULW用ソフトイメージ作成 SetDrawValidMultiSample( 8, 8 ); // コメントアウトするとブレンドされる? bsh1 = MakeScreen( 800, 600, TRUE ); // 透過要素無し用描画可能バッファ作成 bsh2 = MakeScreen( 800, 600, TRUE ); // 透過要素有り用描画可能バッファ作成 SetDrawValidMultiSample( 0, 0 ); // *** 追加 *** bsh1付属のZバッファを作成 SetUseGraphZBuffer( bsh1, TRUE ) ; MV1SetMaterialDrawBlendMode( ModelHandle, 1, DX_BLENDMODE_SRCCOLOR ); // マテリアル描画ブレンド変更 MeshNum = MV1GetMeshNum( ModelHandle ); // メッシュ数取得 while ( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { // 透過要素無しメッシュ SetDrawScreen( bsh1 ); // *** 追加 *** 使用するZバッファをbsh1付属のZバッファにする SetDrawZBuffer( bsh1 ) ; ClearDrawScreen(); // bsh1のカラーバッファとZバッファをクリア for( int i = 0; i < MeshNum; i++ ){ if( !MV1GetMeshSemiTransState( ModelHandle, i ) ){ MV1DrawMesh( ModelHandle, i ); } } // 透過要素有りメッシュ SetDrawScreen( bsh2 ); for( int i = 0; i < MeshNum; i++ ){ if( MV1GetMeshSemiTransState( ModelHandle, i ) ){ // *** 追加 *** 使用するZバッファをデフォルトに戻す( ClearDrawScreen でクリアされないようにするため ) SetDrawZBuffer( -1 ) ; ClearDrawScreen() ; // bsh2のカラーバッファとデフォルトのZバッファをクリア // *** 追加 *** 使用するZバッファをbsh1付属のZバッファにする SetDrawZBuffer( bsh1 ) ; MV1DrawMesh( ModelHandle, i ); GraphBlend( bsh1, bsh2, 255, DX_GRAPH_BLEND_NORMAL_ALPHACH ); } } // *** 追加 *** bsh1のカラー値にアルファ値を反映 GraphFilter( bsh1, DX_GRAPH_FILTER_PREMUL_ALPHA ) ; SetDrawScreen( bsh1 ); GetDrawScreenSoftImage( 0, 0, 800, 600, acsh ); // *** 変更 *** アルファ値の値を反映させたイメージを使って UpdateLayerdWindow を行う UpdateLayerdWindowForPremultipliedAlphaSoftImage( acsh ); } DxLib_End(); return 0 ; }
Re: αチャンネル付き描画可能画像について ( No.8 )
名前:yasi 日時:2011/11/28 01:26

早速の対応、ありがとうございます。 こちらでも動作確認いたしました。 なるほど、bsh2の分もbsh1側にZバッファ情報を書き込んでしまえばいいのですね。 細かいコメントまで付けていただき感謝します。 負荷についてですが、私が思っていた程でもなかったので、可能であれば是非実装してみたいと思います。 (半透明の衣装や光エフェクトの要望も上がっていましたので。) ただ今一つ。 今回追記していただいたコードのSetDrawValidMultiSample部分2箇所をコメントアウトし、 DxLib_Init前にSetFullSceneAntiAliasingModeを行った結果、 描画はされていますがアンチエイリアスが掛かっていないようです。 現在私の方ではいずれの制作プロジェクトでもFSAAは使用してはいませんが、 確認願えますでしょうか。よろしくお願いします。
Re: αチャンネル付き描画可能画像について ( No.9 )
名前:管理人 日時:2011/12/04 03:51

関数解説の説明不足で申し訳ありません SetFullSceneAntiAliasingMode は裏画面をアンチエイリアス付きにするかどうかの機能となりますので、 MakeScreen で作成した描画可能画像に描画した結果をアンチエイリアス付きにするかどうかは SetFullSceneAntiAliasingMode の設定に関わらず SetDrawValidMultiSmaple の設定に従います ( リファレンスの SetFullSceneAntiAliasingMode の解説にもこのことについて追記しておきました )
Re: αチャンネル付き描画可能画像について ( No.10 )
名前:yasi(解決) 日時:2011/12/04 04:58

ご回答ありがとうございます。 そのような使い分けが有ったのですね、納得しました。 最初から用意されてる裏画面にはSetDrawValidMultiSmapleが 使用できない事を考えれば普通に思いつく事でした、すみません…。 長々と質問、要望等にお付き合いいただき感謝です。 また宜しくお願いいたします。

Page: 1 |