ふりーむ!BBS(閉鎖)
TOP > 過去ログ > 記事閲覧
掲示板一覧:[4 ゲーム開発・創作仲間募集(依頼先を探している方一覧)] [5 ゲーム・創作のお仕事募集(依頼を請け負っている方一覧)] (閉鎖:[1 初心者・質問] [2 ゲーム攻略] [3 ゲーム開発・創作の話題])

便利リンク1:[ふりーむ] [ゲーム制作ツール集(素材リンク集)] [素材ライブラリ]
便利リンク2:[イラスト投稿(サンプルやポートフォリオ用に)] [ふりーむプレミアムサービス(外部広告の削減を目指して取り組んでいます)]
下記掲示板は投稿の受付を終了しました(投稿できません)。一定期間後に公開も終了されます。2005年からご愛用頂きありがとうございました。なお、上記掲示板一覧の「4」「5」は現段階では「様子見」でしばらく投稿可能です。
fld_nor.gif ColorKeyと頂点Alphaを同時に使っちゃう
投稿日 : 2008/01/16 03:43
投稿者 instemast
(1)どうやってColorKeyを使う?

アルファチャンネル付きのテクスチャとAlphaBlendを使って実現できます。勿論AlphaTestもできます。(ここでは言わないとします)

詳しくは:
InitDeviceObjects()の中に次のものを追加:
D3DXCreateTextureFromFileEx(m_pd3dDevice,"a.bmp",D3DX_DEFAULT,D3DX_DEFAULT,1,0,
D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,D3DX_FILTER_POINT,D3DX_FILTER_POINT,
0xff000000,NULL,NULL,&m_pTexture);
中では、アルファチャンネル付きのフォーマット例えばA8R8G8B8を使うことは必要です。カラーキーは私は0xff000000真っ黒にしました。

ここで詳しく説明することにします:
実際的に、d3dにはカラーキーなどはありません。いわゆるカラーキーとは、アルファチャンネルを0x00にセットすることで実現することにすぎないんです。
D3DXCreateTextureFromFileEx関数で、もしカラーキー(例えば0xff000000)を指定したなら、この関数はテクスチャの中での0xff000000である画素のアルファチャンネルを全て0x00にセットします。

「この関数でカラーキーを使っても全然効果が出ないんだよ」と不満を漏らす人もいます。
実はこの関数はただアルファチャンネルをセットするだけです。効果が出るには、アルファチャンネル関連の描画関数を使えばです。

いま、このテクスチャには、アルファ値が含まれています。
さて、テクスチャに含まれているアルファ値を利用してアルファ混合を使いましょう。こうしたらカラーキーの効果は実現できます。

Render()関数に次のものを追加:
//アルファ混合の設定
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
//アルファの引数をテクスチャのアルファ値に設定(実は次の2行は消してもいいです、既定値ですから)
m_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);
//プリミティブのレンダリング
m_pd3dDevice->SetFVF(FVF);
m_pd3dDevice->SetStreamSource(0,m_pVB,0,sizeof(VERTEX));
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);
//レンダリング状態の復元
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ZERO);

実行してみると、確かに、ColorKeyの効果を実現できました!
編集 編集
件名 Re: ColorKeyと頂点Alphaを同時に使っちゃう
投稿日 : 2008/06/09 02:13
投稿者 インステマスト
悪意?ww
そんなのないでしょ
編集 編集
件名 Re: ColorKeyと頂点Alphaを同時に使っちゃう
投稿日 : 2008/04/02 07:46
投稿者 ろろく
こんなにスペース割いて書く話じゃないような。
レンダリング状態の復元に悪意を感じる
編集 編集
件名 Re: ColorKeyと頂点Alphaを同時に使っちゃう
投稿日 : 2008/01/29 15:22
投稿者 instemast
スナップは:
http://bbs.gameres.com/upload/sf_20081136241.jpg
編集 編集
件名 Re: ColorKeyと頂点Alphaを同時に使っちゃう
投稿日 : 2008/01/16 05:00
投稿者 instemast
(3)どうやってColorKeyと頂点Alphaを同時に使える?

直ちに実現方法を言いましょう:

上記の(2)のRender()関数中の何行かのコードを改めましょう。
間違ってしまわないように、改めた後のRender()のコードを私は全て書き出しています。

//アルファ混合の設定
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
//アルファ値の設定(テクスチャアルファを頂点アルファとかけ算する)
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
//プリミティブのレンダリング
m_pd3dDevice->SetFVF(FVF);
m_pd3dDevice->SetStreamSource(0,m_pVB,0,sizeof(VERTEX));
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);
//レンダリング状態の復元
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ZERO);

実行してみると、成功に、綺麗なColorKey及びAlpha効果を実現できました!


説明:

原理は何でしょうか?
一つのテクスチャステージで、d3dは2つの引数にある演算をして、アルファの出力(op)を1つ得るのです。

私たちの目的は:
テクスチャアルファが0x00 -- 0%(カラキー)って場合、アルファのopはゼロになる、つまり完全透明。
テクスチャアルファが0xFF -- 100%(カラキーでない)って場合、アルファのopは頂点のアルファになる。

ならば、かけ算を使うことは、もっても思い付きやすいです。
ヘッダファイルを見たら、D3DTOP_MODULATEはかけ算のことなのです。そして、検証に合格。

なぜなら,
0% * 頂点アルファ値 == 0 (完全透明)
100% * 頂点アルファ値 == (頂点アルファ値)
(計算する時になるとパーセントにされますから、つまり0xffのアルファ値は1.0 == 100%になります)


編集 編集
件名 Re: ColorKeyと頂点Alphaを同時に使っちゃう
投稿日 : 2008/01/16 05:05
投稿者 instemast
(2)どうやって頂点Alphaを使う?

頂点アルファの応用は多いです。例えば、UIで、頂点アルファを利用し、自由に透明度を調節できます。(4つの頂点のアルファ値を設定すればよいです)

方法は:頂点のdiffuse(色)にアルファ値を設定してから、
頂点のdiffuseの中のアルファチャンネルを使って、アルファ混合をすればいいです。

詳しくは:

同じようにアルファ混合の操作ですから、上記の(1)とは大層似てますから、コピペ可能です。

先ずは頂点定義を変更するのは必要です。
color値ていうかdiffuseを追加してください。

struct COLORVERTEX
{
FLOAT x, y, z, rhw; // The transformed position for the vertex
DWORD color;
FLOAT tu, tv;
};
const DWORD FVF = (D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE);

InitDeviceObjects()関数でテクスチャをロード、(1)と同じですからコピペしたらww

RestoreDeviceObjects()関数で、各々の頂点およびその頂点のアルファ値を設定してください。このためのコードは書く必要ないと思いますから。
例えば、私はcolorの最高バイト、つまりアルファチャンネルを0x88に設定しています。(50%透明)
(需要によって、インスタント的に頂点のアルファ値を変更するのが必要な場合もあります。これは自分で書いてください)

今、頂点たちには、0x88のアルファ値が含まれてます。(50%透明)
さて、頂点に含まれているアルファ値を利用してアルファ混合を使いましょう。こうしたら頂点アルファの半透明の効果は実現できます。

(1)のRender()関数を1行だけ改めればオッケーです。
m_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
っていう行を
m_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_DIFFUSE);
に変更すればいいです。引数を一つだけ変更するだけです。

実行してみると、確かに、半透明の効果を実現できました!


でも、このサンプルはカラーキーが付いていないのは大嫌いなんですけど、どうやったら実現できるのでしょうか。

編集 編集

フリーゲームライブラリ「ふりーむ!」へ

- WEB PATIO -