テレワークならECナビ Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!
無料ホームページ 無料のクレジットカード 海外格安航空券 海外旅行保険が無料! 海外ホテル


log

2011.02.20 C++:デカールとシザリングについての話


今回はひさしぶりにプログラムの更新して、デカールプロジェクションという技術を
実装をしてみました。ちなみにデカールという言葉はプラモでも使われているようで、
3Dの間でもカラーマップのことをデカールと呼んだりもするので、実は結構定義が
あやふやだったりしますが。。今回実装したデカールプロジェクションというのは
壁やキャラクターにぺたっとシールを貼り付ける技術のことです。動画では青い
四角部分がデカールで実装しています。

処理部分はCPU計算で実装したのですが、技術的には以前実装したシェーダに
よる丸影とほとんど同じなので、実はそのシェーダを少し改良しただけでGPUで
実装できるんですけどね。。なぜあえてCPUで実装したかといえば、デカールの
処理内で使われるシザリングという技術を導入したかったからなのです。

このシザリングというのは、ポリゴンを任意の平面で分断して切り取るという至って
シンプルなテクニックで、DirectXではありがたいことに描画時のニアクリップ面に
対して自動的にシザリングを行ってくれます。ちなみにこれが行われないと
どうなるかといえば、、説明は行列計算の話になってくるので省きますが。
これだとカメラの後ろ側のポリゴンまで描画されてしまいます笑。

このシザリングをわざわざ自前でやる必要があるのかといえば、"背景モデルを
自動で分割できるから"というのが今回の本当の狙いだったりします。
モデリング制作において、毎回背景を手動で最適化されるように分割するのは
しんどいのですが。これによって気軽にぐりぐりと背景が作れるようになる訳です!

久しぶりに日記を更新したせいか、今回はやや記事が長くなりました。
技術的な話でも少し書こうかと思いましたが、、あまり有益な情報の無い、
ただの長文になってしまいました苦笑。

2010.11.04 C++:深度法線エッジ

ファイル 308-1.jpg

サイト改装もひと段落したので、最近ぼちぼち制作を再開しています。

今回は前から実装してみたかった深度法線エッジを実装しました。これはt-potさんの
サイトに詳しい解説が載っていますが、アセンブリコードで書かれているため個人的には
なんだかよく分かりません苦笑。なのでエッジ取得部分は独自の方法での実装です。

それにレンダーターゲット周りも少しだけ工夫してみました。具体的にいうと、法線と
深度を別々のバッファに生成すると、いくらピクセルシェーダをほとんど使っていないから
といっても負荷が多そうな気がしたので、ひとつのバッファにまとめるようにしています。
さて、問題の速度のほうですが。。予想通り、キャラが沢山表示されても常時30FPSが
でるようになりました!!

ただ、この深度法線エッジは頂点シェーダによるエッジと比べていくつか問題もあります。
まずひとつは、エッジがいくつか入らない部分が存在したり、不必要な部分までエッジが
入る可能性があることです。もちろんある程度パラメータで調節可能なのですが、
結構頑張ってみてようやく上の画像の感じなので難しいところです。それともうひとつの
問題は、見え方が画面の解像度によって異なってくるということです。頂点シェーダによる
実装の場合、実際に3次元空間を配慮して線が描画されるのに対し、今回の手法は
スクリーンスペースによる計算なので、任意のピクセル単位の線しか引けないのです。

なかなかにやっかいな深度法線エッジですが、鳥瞰視点の場合だとそれほど問題なく
見られる様子なので、カメラからの距離に応じて使い分けるようにしようかなと思います。

そうそう、この日誌にブログパーツをいくつかつけてみました。軽めのもので便利なものを
選んでみたのですが、環境によっては重くなって見づらいかもしれないですね;

2010.10.17 C++:ようはくポストエフェクトことはじめ

ファイル 302-1.jpg

今日はとっても鼻水がでる一日でした。ずるずる。

今までなぜか背景をHLSLで描画すると途端にFPSが下がって
しまっていたので、しかたなく固定機能パイプラインで描画して
いたのですが、ふとFXファイル内を見てみるとミップフィルタが
OFFになっていることに気がつき、設定後再び背景をHLSL
描画で試してみると無事FPSが落ちることなく描画できました。
どうやらHLSLによる速度低下ではなく大容量のテクスチャへの
アクセスによる速度低下だったみたいですね。

それで今日は背景のシェーダ周りと、新しくポストエフェクトに
向けてのマルチターゲットレンダリングの導入を行っていたんですが、
肝心のマルチターゲットが何故かなかなかうまくいきません。。

調べてみると、複数設定したレンダーターゲットのサイズやフォーマット、
サンプリング数は同じでなければならないらしく、設定してみても
なんだか微妙に違う。で、ちょっと気がついたことがあったので
アルファテストのAlphaREFの値を上げてみるとなぜかうまく
描画されました。…うーん、何故??アルファは全然弄っていない
のですが、一体全体どこから来たのやら。。謎です。

2010.10.12 C++:頂点カラー

ファイル 301-1.jpg

少し時間がかかりましたが、背景に頂点カラーを実装してみました。

今までテクスチャのみによる色づけだけだったのが、今回の実装で
同じテクスチャの部分でも頂点によって色が変えられるように
なったので、なんだかバリエーションが広がった感じ!

ちなみに実装方法は乗算だけではなく、明るい部分は明るく
暗い部分は暗くといった、いわゆるオーバーレイ風味になるように
設計しています(ただ、背景は固定機能パイプライン描画なので
正確なオーバーレイ描画は実装できないのですが)。プログラムは
割とすんなり組めたのですが、ところがどっこい3Dソフト内で
頂点カラーを設定する際には乗算表示しか対応していないので、
一旦フォトショップでオーバーレイ処理後の色を確かめた後に
その色を3Dソフト内で数値入力するといった面倒な処理をすることに
なってしまいました苦笑。

特殊なことをやろうとすると色々と作業が細々としてしまい、大変です。

2010.10.08 C++:固定機能でモノクロシェーダ

ファイル 300-1.jpg

背景を固定機能パイプラインでモノクロにしてみました。
本来ピクセルシェーダを使えば、ものすごく簡単に実装できるん
ですけどね。。GPUが「もう無理もう無理!絶対無理!!」と
悲鳴を上げてしまうわけです…;そこで仕方なく固定機能で
描画してみることにしました。

Vista以降のPCとGPUならば固定機能パイプラインなんて
シェーダでエミュレーションされるので関係無いんですが、
色々な環境でも動作することを視野に入れるとXP以前の環境も
考えないといけないですからね。という自身もXPな訳で苦笑。
それにしても、ピクセルシェーダで実装したときと比べて色が
随分と飛んでしまっています。キャラクタも試しに固定機能で
モノクロにしてみましたが、、見事にディテールがふっ飛んだ!

そういえば、固定機能でモノクロシェーダをやってみてようやく
気がつきましたが。DDSとPNGでは半透明時の色部分の扱いが
違うみたいですね。まだ今ひとつ分かりませんが、おそらくPNGは
透過色を白として扱い、DDSは透過色を隣接不透明部分の
色として扱う、ということでいいのかな?

2010.10.07 C++:カラーVSモノクロ


動くキャラ同士の衝突判定を実装してみました!

動くキャラと動かないキャラ・壁との衝突判定はあまり深く考えずに
実装できたのですが(といっても壁沿い移動は難しかった…苦笑)。
動くキャラ同士の場合だと”お互いの動きを考慮に入れた後、
衝突判定を行い、その結果を元に壁沿い移動して、またその
壁沿い後の座標で他のキャラと衝突していないか”…などなど。
途端にロジックが難しくなることが分かりました。これ、本当に
正確な衝突判定を行おうとした場合、下手すると衝突判定が
無限大に続いてしまうので、物理演算なんかでよく設定される
”ステップ数”っていうのはこの1フレーム当たりの衝突判定回数を
制限しているんだろうなと思いました。

そういえば、今回の処理でCPU負荷が結構かかってしまったかなと
思いましたが、まだ最大で50%程しか使用していませんでした。
GPUは思いきりこき使ってますが苦笑。余力が残っているのは嬉しいな。

2010.10.06 C++:お手軽影生成


新しく影表示を追加してみました。

本当はステンシルシャドウ等の影生成をやりたかったのですが、スペック上の都合で丸影で
実装しました苦笑。まあこれはこれで、ただ板状の影を置く手法ではなくピクセルシェーダを
使って丸影を生成していたりと割と工夫していたりします。デカールによるCPU生成の実装も
考えましたが。。大変そうだったので保留にしました笑。どんな技術でも物は使いようですね。

そういえば、今回はYouTubeの方にも音楽つきで投稿したのですがこちらはなぜかコマ落ちしてます。うむ、よく分かりません。。エンコードの勉強とか少しした方がいいのかもしれない。

2010.10.02 C++:頂点シェーダ処理を稼ぐ単純な方法

とりあえずいくらピクセル負荷を軽減しても一定以上下がらなかったので
頂点シェーダがFPS低下の根本になってることが分かりました。

それで、どうしたもんかと色々頭を悩ませた末、一度本家スーファミの
方ではどうやっているのかと色々調べてみましたが。。どうやら敵は
画面内に3体までしか表示してできないようにしていたらしいんです。
子供の頃にプレイしてたときは全然気づきませんでしたよ苦笑。

それでさっそく自身の方でも導入してみましたが。これが意外と
違和感無くプレイできます。ただこの手法、例えばFPS視点で
使用すると今まで後ろにいた敵が振り返ってみるとパッと消えて
いた!なんてことになったりするので、鳥瞰視点の操作に
限定したほうがよさそうです。しかしこれでようやく30FPSが
無事に持続できるようになりました。よかったよかった。

そういえば、後から宝箱を取ろうと思って後から取りに行ったら
無くなってた、、なんてこともあったっけ笑。プレイヤーが突然
いなくなってそのまま現れないバグとかあるらしいですが、
それもおそらくこのカリング手法が原因なんだろうなと、ふと思いました。

2010.10.01 C++:if文を使わないHLSLの計算方法

今まで速度を計らずにトゥーンインクを使用していたんですが、
実はトゥーンシェーディングよりもトゥーンインクの方が重かった
のでした。。(といっても、これはもちろん環境に依るんですけど;)

そこで、ちょっとくらい早くなるかなと思い、if文の部分をif文を
使わずに記述してみましたが、、うーんほとんど変わらないなあ。
現在トゥーンインクを使用した状態で6体以上表示させると一気に
25fpsまで下がってしまうのですが。せいぜい1fps程度向上して
いるような、していないような。まぁ、if文はまだ1つしか使用して
いないので微妙な感じです。

とりあえず、if文を使わない書き方を少しだけメモしてみます。
・aを1.0以上の場合は0.0にループ丸めしたいとき
→端数丸めを使う:a -=trunc(a);
・ブールbによる値切り替えb ? z=c : z=dをしたいとき
→z = b*c + (1-b)*d;

if文くらいだったら使わずに記述できるのかもしれないですね。
というか、そろそろ日記の分類がいい加減になってきました。
今回の分類をC++にしたけど、全くC++と関係ないからなあ苦笑。

2010.09.28 C++:モノトーンとトゥーンインク

ファイル 295-1.jpgファイル 295-2.jpg

モノトーン表示とトゥーンインク機能を新しく追加してみました。

線が入ったことで、ちょっと独特なよさがでたような気がします!
ちなみに線の実装は処理速度を考えて、法線方向押し出しという
一番単純な実装でやってみたのですが。それだけだとカメラからの
距離が遠くなるほど線が細くなってしまうので、今回はカメラからの
距離にあわせて線の太さを一定になるようにひと工夫しています。

それと、今まで導入していたトゥーンシェーディングは重い割に
あまり見た目が変わらないということもあったので…苦笑。
一旦トゥーンシェーディングの機能をOFFにしてみました。画像では
トゥーンシェーディングOFFですが、おそらくトゥーンインクだけで
大分それらしく見えてると思うので、それほど必要でもないかなと
思いました。環境に応じてON/OFFできるようになればいいかな。