トップページ > 記事閲覧
フェードイン/アウトを重ねて使用する画像の部分書き換え
名前:reah 日時: 2013/06/28 02:47

現在サウンドノベル風ゲームを作成しています。 キャラクター画像の部分的な書き換えのため、2枚の画像を使用しアルファブレンドによるフェードイン/フェードアウトを 行なっているのですが、実際に表示される結果が半透明になってしまいます。 具体例を説明します。 同じ位置・サイズで表示する2枚のキャラクター画像を用意します。 1枚は目を開けている画像、もう1枚は目を閉じている画像です。 1枚目の画像はアルファ値を0→255へ変化させ、それと同時に2枚目の画像はアルファ値を255→0へと変化させます。 常に(1枚目のアルファ値)+(2枚目のアルファ値)= 255 となるようにして描画しています。 こうすることで、フェードの最中に画像全体の明るさは変化せず、キャラクターの目の部分だけぼんやりと切り替わる という想定でした。 ところが実際にこれを実装すると、常に(1枚目のアルファ値)+(2枚目のアルファ値)= 255 であるにもかかわらず フェード中はほんの少しだけ半透明になってしまいます。(フェード中は常に同じ透明度に見えます) この問題は何故発生してしまうのでしょうか。 以下サンプルです。 int bright_fadein = 0; int bright_fadeout = 255; while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){ //フェードイン SetDrawBlendMode(DX_BLENDMODE_ALPHA, bright_fadein); DrawGraph(x, y, img_before, true); bright_fadein++; SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0); //フェードアウト SetDrawBlendMode(DX_BLENDMODE_ALPHA, bright_fadeout); DrawGraph(x, y, img_after, true); bright_fadeout--; SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0); }
メンテ

Page: 1 |

Re: フェードイン/アウトを重ねて使用する画像の… ( No.1 )
名前:Sura 日時:2013/06/28 03:32

ブレンド率を50%と仮定すると、つまり双方とも128の時、 背景の上にキャラ1をブレンドすると 背景:50%、キャラ1:50% さらにキャラ2をブレンドすると 背景とキャラ1が更に50%となり、 背景:25%、キャラ1:25%、キャラ2:50% となります。 だから、背景が透けて見えるのです。 意図する結果を出すには、 キャラ1→キャラ2へのフェードは 背景描画 上書きでキャラ1を(NOBLENDで) アルファブレンドでキャラ2 の順で描画します。
メンテ
Re: フェードイン/アウトを重ねて使用する画像の部分書き換え ( No.2 )
名前:reah 日時:2013/06/28 04:09

素早いご回答ありがとうございます。 仰るとおり、背景のブレンド率を考慮していませんでした。 透過しないキャラ1の上にアルファブレンドでキャラ2を重ねることで、無事望み通りの結果が得られました。 追加の質問になってしまうのですが、仮に1枚目の画像と2枚目の画像に重ならない箇所があった場合は どうすれば良いのでしょうか。 例えば、1枚目と2枚目の画像で胴体の画素は全く同じですが、腕の角度だけ異なる、といった場合です。 この場合は、Sura様の方法ですと腕が2本生えてしまうかと思います。 そのため2枚目のフェードインと同時に、どうしても1枚目をフェードアウトさせる必要があります。(他の方法があれば申し訳ありません) そうすると結局、最初に上げた問題に当たってしまいます。 解決するには2枚目をNOBLENDで描画すれば良いかとは思うのですが、そうすると今度はフェード効果が使用できなくなってしまいます。 追加の質問になってしまい申し訳ありませんが、宜しくお願いします。
メンテ
Re: フェードイン/アウトを重ねて使用する画像の部分… ( No.3 )
名前:Sura 日時:2013/06/28 22:08

・キャラ1及びキャラ2に共通する部分にのみ描画できるマスクを作成する。 ・背景を描画する ・マスクを施しキャラ1を上書き描画する(よって共通部分だけ上書き描画される) ・マスク解除後、キャラ1をアルファブレンドする ・キャラ2をアルファブレンドする 以上の処理で、共通部分は透けずにフェードできると思います。
メンテ
Re: フェードイン/アウトを重ねて使用する画像の部分書き換え ( No.4 )
名前:管理人 日時:2013/06/30 18:58

二つの画像をクロスフェードさせるための機能は以前専用に作りましたので、 よろしければお試しになってみてください 機能を作成した当時の私の書き込みは以下の通りです ---------------------------- // 描画処理時に描画する画像とブレンドする画像のブレンド設定を行う // BlendGraph を -1 にすれば設定を解除、その場合 BlendType とその後ろのパラメータは無視される int SetBlendGraphParam( int BlendGraph, int BlendType, ... ) ; 今までも LoadBlendGraph と DrawBlendGraph という関数で使用していた『画像合成描画の機能』を拡張して作った関数で、 二つの画像を合成して描画することが出来ます // 例:grhandle1 と grhandle2 の画像を同じ比率で合成して描画する SetBlendGraphParam( grhandle2, DX_BLENDGRAPHTYPE_NORMAL, 128 ) ; // 合成する画像の設定 DrawGraph( 0, 0, grhandle1, TRUE ) ; // 合成の設定がある状態で DrawGraph をすると合成されます SetBlendGraphParam( -1, 0 ) ; // 合成の設定を解除 という感じに、DrawGraph などで描画する前に SetBlendGraphParam の第一引数に合成したい画像、 第二引数に DX_BLENDGRAPHTYPE_NORMAL、 第三引数にブレンド率( 0( 合成画像0% )〜255( 合成画像100% ) ) を渡して呼んだ後に DrawGraph, DrawExtendGraph, DrawRotaGraph の何れかの描画関数を呼ぶと 指定の通りの合成を施した状態で描画されます( DrawModiGraph は未対応です ) 合成の設定はずっと残ってしまうので、描画した後は第一引数に -1、第二引数に 0 を代入して もう一度 SetBlendGraphParam を呼んでください
メンテ
Re: フェードイン/アウトを重ねて使用する画像の部分書き換え ( No.5 )
名前:reah 日時:2013/07/02 15:44

返事が遅くなってしまい申し訳ありません。 Sura様 有用なアドバイス有難うございます。 今回は透過色のあるpng画像が対象でしたので、透過箇所のマスクをメモリ上に作成することで、 共通箇所を透けずにフェードさせることができました。 ただ後から調べたところ、事前に用意できる場合にはマスク画像を予め作成しておくのが一般的なようですので、 実装方法を一度検討すべきなのかな、と感じています。 管理人様 専用の関数があったのですね。 画像毎にマスクを作成する必要がなく簡単にフェード効果が作成でき助かります。 BlendGraph系関数の処理を理解していれば自作できたのでしょうか。 簡単に処理を書くことができ非常に助かります。 有難うございます。
メンテ

Page: 1 |

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

   クッキー保存