プロフィール

Na-7

Author:Na-7
SE(システムエンジニア)として約15年間システム系ソフト会社を勤めあげ、2008年3月退社。現在、ゲーム制作会社設立を目指して活動中。


アクセスカウンター


最新記事


最新コメント


最新トラックバック


月別アーカイブ


カテゴリ


DATE: CATEGORY:スポンサー広告
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
| BLOG TOP |
DATE: CATEGORY:XNA修得
ステンシルシャドウ14
ステンシルシャドウのテスト画面
一部のモデルだけ影に色が着いてしまうらしい。この問題は解消できるのか?



◎半透明の実装

Softimage付属エフェクトファイルに半透明機能を実装しました。(参考:BasicEffectのソースコード


ステンシルシャドウ10   ステンシルシャドウ11

成功です。影の半透明と、旗の右側の完全透明部分が期待通り透けました。

ただ、相変わらず黄色い境界線がチラチラ見えます。XNA4.0に移行するとこちらの乗算済みアルファ機能で自動的に解消されるかもしれないので、とりあえず放置。



◎ステンシルバッファの実装

ステンシルバッファを実装し、ディフューズカラーを黒にしました。

ステンシルシャドウ12   ステンシルシャドウ13

成功したと思ったのですが、他のモデルで確認すると…

ステンシルシャドウ14   ステンシルシャドウ15

ロボットだけ影に色が着きました。

ロボットはスペキュラカラーが設定されていたので、最初はこれが原因かと思ったのですが、いろいろ試しても変化しません。アンビエント(環境光)でもないし、頂点カラーでもなさそうだし…ブツブツ…。



◎原因調査

ロボットサンプルのシーンファイルからPublishした.xsiファイルを読み込むと、content.Loadでエラーになります(最初から用意された.xsiファイルは動きます)。このため‘コンテンツの一部を改修して動作を確認する’ことはできません。

そこで、C#でライトのディフューズカラーを黒、HLSLでモデルのディフューズカラーを黒にして試すと、ロボットモデルだけ黒になりません。何か他の要素があるのかと思って散々悩んだのですが、結局ディフューズカラーの問題でした。

エフェクトを一括置換する機能は‘BasicEffectであれば’という条件付きとしたのですが、ロボットサンプルはこの条件に該当せず、エフェクトが置換されません。このため、HLSLでモデルのディフューズカラーを黒くしたつもりだったのですが、別のHLSLを参照してました。(キャプテンサンプルは黒くなったので、なかなか気付けませんでした(ーー;)

というわけで‘BasicEffectであれば’という条件を外しても動くように改修しました。(モデルのディフューズカラーは変更せず、ライトのディフューズカラーのみ黒とした)

ステンシルシャドウ16   ステンシルシャドウ17

ロボットサンプルのアンビエントをそのまま渡すと本体や影が明るすぎた(左図)ので、アンビエントを黒にする(右図)と落ち着きました。

ステンシルシャドウとしては全モデルOKとなったので、HPのサンプルコードを更新しました。



◎環境光

環境光の元の値をそのまま受け渡すと、何故かミョーに明るくなってしまいます。これについて調べると、AmbientMapの‘texture2D’だけ渡して‘sampler2D’を渡してないことが原因でした。

しかし、テクスチャは
parameter.GetValueTexture2D()
でゲットできますが、サンプラーのゲットの仕方がわからない(前にいろいろ試したがNGだった)ので対処できません。

自作モデルにAmbientMapを使う予定は無いので、この件は保留ということで(^^;



◎次回予告

レンダーステートの勉強のために始めたステンシルシャドウですが、レンダーステートと関係無い所で苦戦しまくりでした(汗)

ステンシルシャドウは成功したので、次回は他の機能を修得します。

スポンサーサイト

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:XNA修得
ステンシルシャドウ09
投影行列の適用テスト
XNAViewerに投影行列を適用して、影が斜めに表示される状態になった。ワールド座標変換行列の渡し方にコツがあるらしい。



◎前回の補足

前回のACLステンシルシャドウは、下記A案で実装しました。

A案:モデル:複製、アニメーター:複製
B案:モデル:非複製、アニメーター:複製
C案:モデル:非複製、アニメーター:非複製

もしかしたら、B案C案でも動くかもしれません。
(やってみないとわかりません)

もし動くのであれば、C案が一番パフォーマンスが良さそうです。興味がある方は試してみてください。



◎投影行列の適用

さて、Softimageモデルへのステンシルシャドウ適用ですが、やはり最初の問題は投影行列の適用です。通常モデルやACLモデルで成功した投影行列を、再度適用してみましょう。

ステンシルシャドウ07

サンプルモデルなど複数のモデルで試したのですが、こんな感じでバラバラです。投影行列は正しいはずなのに、何が悪いのでしょうか?


私のXNAViewerは多少改造しているので、念のためXNAViewerを新規にセットアップして再度確認しました。

ステンシルシャドウ08

斜めに表示されて動きました。

…ということは、従来の改造のいずれかが投影行列の座標変換に悪影響をもたらしていた、ということです。ガーン!



◎原因判明

一番疑わしいのは、ボーン数増加改修です。「スケールを持つポーンアニメーションは非対応」という仕様ですが、ワールド座標変換行列のスケールはサポートするんじゃなかったっけ?

試しにスケールを変更して動かすと、スケールは変わらずにアニメだけ崩れました。ボーン数増加改修によって、ワールド座標変換行列のスケール変更が不可能な状態になっていた、というわけです。ガガーン!!!

改修後にスケール変更テストぐらいしとけって!!(>_<)


スケールに着目してソースコードをチェックすると、元のHLSL(Softimageランタイム付属HLSL)の特殊性に気付かなかったことが敗因でした。

このHLSLは、フローが2つに分岐します。スタティックのフローでは、エフェクトパラメータのワールド座標変換行列が反映されますが、スキンアニメのフローでは、エフェクトパラメータのワールド座標変換行列を無視します。

HLSLを改修せずにワールド座標変換行列を指定したい場合は、予め
Models[CurrentModel].CrosswalkModel.Root.Transform
にワールド座標変換行列をセットします。

つまり、ワールド座標変換行列をモデル情報の一部として受け渡す(エフェクトパラメータとしては渡されない)状態だったので、ボーン増加改修を行うと、ワールド座標変換行列のスケールも無視されることになった、というわけです。



◎旧方式に戻す

問題を解消するためには、ボーン増加改修を元に戻すか、ワールド座標変換行列の渡し方を変更する必要があります。リグ方式をやめたので、ボーン数を増やさなくても足りているのですが、問題が発覚したまま放置するのは気分が悪いですね…。

というわけで、ワールド座標変換行列の渡し方を昔の方式(こちらのB方式)に戻します。改修箇所が複数に及ぶ(しかもC#とHLSL両方)ので一度封印した方式ですが、ボーン増加改修を適用したい場合は仕方ありません。

ステンシルシャドウ09

スケールを含むSRTトランスレーションが正常に反映され、影がちゃんとアニメすることを確認しました。ようやく(ボーン増加改修済の状態で)投影行列が正常に反映されました。


それにしても、ランタイムシェーダの中途半端な設計思想がこんな所に影響するなんて…非スキンモデルのワールド座標変換行列はエフェクトパラメータで受け渡してるんだから、スキンモデルも同様に作って欲しかった(>_<)



◎次回予告

投影行列の適用に成功したので、次回は半透明とステンシルバッファです。

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:XNA修得
ステンシルシャドウ06
ACLステンシルシャドウテスト
ACLモデルはBasicEffect同等機能を実装済なので、ステンシルシャドウのサンプルコードがほぼそのまま流用できる。



◎クロスモデル連携手法

HPに、Softimageクロスモデル連携手法をまとめました。

SoftimageのシミュレーションモデルをXNAで動かす

詳細手順作成に時間がかかったのですが、クロスモデルを実装したい人の平均レベルを考えると、詳細手順は不要だったかなぁ?

でも、少しでも手順が抜けると動かなくて悩んだりするので、こうしてまとめておくと、数年後の自分に役立つかもしれません。



◎通常モデルへの適用

前々回は、ステンシルシャドゥをいきなりSftimage連携ライブラリに適用して失敗したので、今回はまず通常モデルに適用しましょう。

ステンシルシャドウ01

あれ?本体と影が離れてますね?うーん…。

試しに本体の表示位置をずらしてみると、影の表示位置が固定で本体に連動しないことに気が付きました。元のサンプルを確認すると、元のサンプルもやはり影の表示位置が本体の位置に連動しません。

ステンシルシャドウ02

元のサンプルの本体座標を原点(0,0,0)に表示するとこうなりました。

ソースを解析したら、サンプルコードの下記の部分が問題でした。

effect.World = World * Shadow;

この順番ではWorldのトランスフォームが反映されません。
下記のように修正すると影の表示位置が本体に連動するようになりました。

effect.World = Shadow * World;

ステンシルシャドウ03

木モデルの原点は足元なので、影が丁度良い位置に表示されました。

サンプルのハニワモデルは原点が中央なので、モデルの原点を足元にずらすか、コードを修正する必要があります。

// 投影行列を作成
Shadow = Matrix.CreateShadow(shadowLightDir, wallPlane)
* Matrix.CreateTranslation(wall.Normal / 100.0f)
* Matrix.CreateTranslation(new Vector3(-1, -1, -1));


ステンシルシャドウ04

実は上記コードではずらす位置が不正確なんですが、とにかく影が本体と連動するようになりました。


なんかテーマと違うことで手間取ってしまいましたが(汗)、通常モデルに対するステンシルシャドウの適用は成功です。



◎ACLへの適用

次はACLモデルです。まずは投影行列を適用してみましょう。

ステンシルシャドウ05

静止画ですが動いてます。
投影行列は無事に適用できました。さすがACL!


さて問題はここからです。レンダーステートを動的に変更する必要があるので、ACLを手動表示モードに切り替えてから、ステンシルと半透明を実装します。



おお、できました!


ACLの注意点としては、ワールド座標変換行列はアニメーターが管理するのでインスタンス毎に(複数)存在しますが、ビュー座標変換行列と斜影変換行列はエフェクトが管理するので、通常はインスタンス共通(単数)です。

…実は、上記を思い出すまでちょっと苦戦しましたw



◎技術資料

今回のサンプルコードをHPにUPしました。

ACLモデルに影(ステンシルシャドウ)を実装する

久々にACLを使いましたが、やはりSoftimageライブラリより数倍扱いやすいですねw



◎次回予告

通常モデル及びACLモデルへのステンシルシャドウ適用が成功したので、次回はSoftimageモデルへの適用に再チャレンジします。

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:XNA修得
ステンシルシャドウ公式サンプル01
シャドウのサンプルプログラム
ステンシルバッファやアルファブレンディングを利用してステンシルシャドウを描画する公式サンプルプログラム。筆者PCで実行すると上図の画面になったが、他の環境では異なる可能性がある。



◎レンダーステート

前回コメントでyohさんからアドバイスを頂いたので、今回は予定を変更して、レンダーステートを勉強します。さて、レンダーステートの何を勉強すれば良いのでしょうか?

まず半透明処理ですが、スプライトバッチ、BasicEffect(実体はHLSL)、ACLやSoftimageのライブラリ、カスタムエフェクト等を併用するとうまくいかないことがあります。これまでは、ろくな知識もなく試行錯誤だけで強引に突破してきました。

3Dテストプログラムのラストシーンでは、ACLとスプライトバッチ併用で半透明を実装するために何十通りもの組み合わせを半日かけて試しましたw

しかしこれは効率が悪い上に、組み合わせが変わると通用しないので、次のステップに繋がりません。まずXNAの半透明処理をきちんと理解した上で、他の機能がどのように影響するのか把握する必要がありますね。

また、レンダーステートに関しては、他にも知らない機能やプロパティが沢山あります。XNAの全ての描画は各プロパティの設定に影響を受けるので、レンダーステートの機能やプロパティは一通り知っておく必要がありそうです。



◎現状確認プログラム

まず、レンダーステートがどのように変化するのか確認するプログラムを作りながら、どんなプロパティがあるのかグループ分けしながら確認しました。

レンダーステート出力プログラム(デバッグ用)

ちなみに、私の理解度はこんな感じです。

○よく知らない機能
・カラーバッファーチャンネル関連
・ステンシル/ステンシルテスト関連
・カリング モード
・シザー テスト
・ポイントサイズ関連
・完全テクスチャ マッピング

○機能概要は知っているが、使いこなせないもの
・アルファ関連
・深度バイアス/深度バッファ関連
・マルチサンプリング関連

○ある程度使いこなせそうなもの
・塗りつぶしモード
・フォグ関連
・テクスチャラッピング関連

よく知らない機能について、機能概要を把握することから始めましょう。



◎ステンシルバッファ

よく知らない機能の中で、わりと頻繁に御目にかかるのはステンシルバッファです。ネットを探ると、こちらの記事がわかりやすかったので実際に試してみました。

ステンシルテスト01

ステンシルバッファ非公式サンプル解析メモ

ステンシルバッファは、描画領域を設定可能とする機能のようですね。全体の流れはある程度理解しましたが、疑問点もあります。



◎公式サンプル

しばらくパラメータをいじったりしましたが、それだけではよくわからなかったので、こちらの公式サンプルも解析することにしました。

ステンシルシャドウ公式サンプル01

このサンプルでは、ステンシルモードのアダプタチェックなどもやってます。ちなみに、
SurfaceFormat.Depth15Stencil1
SurfaceFormat.Depth24Stencil4

上記フォーマットはXbox360でサポートされないようです。ちょっと意外。

ソース内の各コードはさほど難しくないのですが、Quadクラスの実体が何なのか、いまいちよくわかりません。行単位で細かく解析すると時間がかかるので、他のサンプルを探すことにしました。



◎非公式サンプル

こちらに良さげなサンプルがありました。

公式サンプルをスマートに改修した感じです。コメントは当然日本語。HPの解説記事も図入りでわかりやすかったので、他の記事も見てみたいです^^

ステンシルシャドウ非公式サンプル01

あれ?影は表示されますが、地面が表示されませんね?
ひょっとして、公式サンプルも地面が表示されなかった??

こちらのテクスチャークワッドの公式サンプルを実行したら、何も表示されませんでした。ガーン!!

メインPCのオンボードGPUはイレギュラーなシロモノですが、まさか平面描画の公式サンプルがNGとは!(>_<)



◎ステンシル無しシャドゥ

ステンシル機能を無効化したらどうなるか試してみました。

ステンシルシャドウ非公式サンプル02

この画面を見て、ステンシルバッファの使用目的がようやくピンときました。影領域への描画を一回とする(均一化する)ためだったのですね。



◎回路は1つ

最初に挙げたように、XNAでアルファブレンディングを実装する手段は複数あります。どれか1つの手段で実装すれば単純で問題無いのですが、複数組み合わせた場合に「何がどう影響するのかよくわからん!」と悩んでました。しかし今回サンプルコードを解析する過程で、ようやく基本的なことに気が付きました。

・レンダリング用の回路(=半透明を処理する回路)は
 GPUに1つだけ
 →どの手法も同じ回路を使用している
 →ある手法で回路の一部を操作すると、
  他の手法に対してもそのまま影響が残る

各手法のコードはそれぞれ別次元のような感覚で認識していたのですが、全部同じ次元で処理される(描画される)のですね。

yohさんが『面倒でも毎フレーム、シェーダに参照される全てのステートを自力で設定するのが確実です。』とコメントされた真意を改めて認識しました。



◎サンプル解析まとめ

ステンシルシャドウの公式/非公式サンプルは、3つのテクニックで影を実装しています。

・Matrix.CreateShadow()を利用して、影を斜めにしている

・ステンシルバッファを利用して、影の濃さを均一化している

・アルファブレンディングを利用して、影を半透明化している

だいぶわかってきたと思うので、演習に入りましょう。



◎演習

前回(初期化目的で)挿入したspriteBatchを削除し、レンダーステート設定で初期化するようにしました。

半透明処理を改善した

境界線が目立たなくなって、殆ど気付かないレベルになりました。ここまではOKです。


次に、ステンシルシャドウの実装を考えたのですが、その半透明処理にはHLSLのさらなる改修が必要なので、とりあえず後廻し。一応ステンシルのコードは組み込みましたが、半透明が未実装なので確認できません。

で、影を斜めにする部分ですが、投影行列の値は正常(確認済)なのに、全然斜めにならなくて悩みまくりです(ーー;

行列を渡す所までは正しいはずだから、ライブラリやシェーダの中身が問題?でもオブジェクト全体にワールド座標行列は反映されてるんだよなぁ…。ひょっとして、ボーン増加改修でスケールが非サポートなのが敗因?でもオブジェクト全体のスケールは有効だし、スケール以外の変化も見られない。う~ん…。



◎次回予告

ステンシルシャドウをいきなりSoftimageライブラリに実装するのは無謀だったかもしれません。先にノーマルモデルやACLで演習した方が良さそうです。

11月になったので、次回は「10月の総括と11月の目標」です。

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

| BLOG TOP |

copyright © ゲーム制作の舞台裏 all rights reserved.Powered by FC2ブログ
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。