楽天モバイル[UNLIMITが今なら1円] ECナビでポインと Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!


無料ホームページ 無料のクレジットカード 海外格安航空券 解約手数料0円【あしたでんき】 海外旅行保険が無料! 海外ホテル

log

2010.04.11 C++:トゥーン修正

ファイル 265-1.jpg

今回はトゥーンシェーダの細かい調整をしていました。
僕のプログラムでは、トゥーンは放物変換で求めたUVとトゥーン用の
テクスチャを用いて表現していて、この放物変換でUVを求めると
1次元でトゥーンUVを求めずに2次元でトゥーンUVを求めるので、
より綺麗に表現できるようになるんですが。実はこれには一つ
やっかいな問題があって。ライトの裏側がなっている部分は
UVの明るい部分をまたいでしまうため明るくなってしまう訳です。
これの解決方法がt-potさんのサイトにのっていたので、
さっそく試してみたのが画像の右半分のものです。

左半分の画像はキャラの左腕が不自然に明るくなっていますが
右半分の画像ではライトの裏面の部分でもきちんと暗くなってます。
画像だとあまり目立たないと思うかもしれませんが、動いていると
ちらちらして見えて結構気になるんです、これ。

それで一応t-potさんのサイトにのっている方法を試してみて
無事解決できたものの、実はこの方法もまた限定な解決方法
でしかないんです。。t-potさんのサイトに載っていたのは、
分かりやすくいえば、「裏面だから暗くすればいいじゃない」的な
アプローチなんですが、それだと例えばテクスチャの暗い部分を
明るい色に変更してリムライティングのような表現をしようとすると
おかしなことになるわけです。ただ、リムライティング的なトゥーンを
やりたい場合はリムライティングのシェーダとトゥーンを併用して
組めばいいので別に問題ないかもしれないですね苦笑。

あとはHSV変換を使って影の色表現をしていたのを、単純な
式で表現したりしてました。というか、これをやらなかったら、
命令レジスタがいっぱいで放物変換の修正処理が入れれませんでした笑。

2010.04.10 C++:カラーテスト

ファイル 264-1.jpg

今日はひさしぶりにテクスチャに描きこみしておりました。
モニタによってはテクスチャの色が飛んで見えたりしたので
それをモニタ2つ使って確認しながら作業していた訳です。
といっても、もうひとつのモニタはむかーし買ったテレビデオですが苦笑。

今回の画像は、たまたまデバッグ中にみんなでかけっこをしている
かのような面白い1枚が出来上がったので、思わず撮ってみました。

2010.04.09 考察:トゥーン&色空間の相互変換式

ファイル 263-1.jpg

トゥーンシェーダを試してみました!

今回はトゥーンシェーダと平行して、影の色処理にHSV-RGB変換を
やっていたんですが、中身がよく分からない状態で使用している上に
シェーダ命令が限界突破してしまったので、少し頭を冷やして
色空間の変換式をちょっくら研究してみることにしました。
さっそくですが、以下に色空間の変換式をメモしておきます。

RGB to YUV
Y = 0.299 * R + 0.587 * G + 0.114 * B
U = -0.169 * R - 0.331 * G + 0.500 * B
V = 0.500 * R - 0.419 * G - 0.081 * B

YUV to RGB
R = 1.000 * Y + 1.402 * V
G = 1.000 * Y - 0.344 * U - 0.714 * V
B = 1.000 * Y + 1.772 * U

RGB to YCbCr
Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B
Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B

YCbCr to RGB
R = Y + 1.40200 * Cr
G = Y - 0.34414 * Cb - 0.71414 * Cr
B = Y + 1.77200 * Cb

RGB to YIQ
Y = 0.2990 * R + 0.5870 * G + 0.1140 * B
I = 0.5959 * R - 0.2750 * G + 0.3210 * B
Q = 0.2065 * R - 0.4969 * G - 0.2904 * B

YIQ to RGB
R = Y + 0.9489 * I + 0.6561 * Q
G = Y - 0.2645 * I - 0.6847 * Q
B = Y - 1.1270 * I + 1.8050 * Q

RGB to HSV
(H:0~360,S:0~1,V:0~1,R,G,B:0~1)
V = max( R, G, B )
diff = V - min( R, G, B )
S = diff / V
if(R == V): H = 60 * (B - G) / diff
if(G == V): H = 60 * (R - B) / diff + 120
if(B == V): H = 60 * (G - R) / diff + 240

HSV to RGB
H(i) = (H/60)mod6
f = H / 60 - H(i)
p = V * (1 - S)
q = V * (1 - f * S)
t = V * (1 - (1 - f) * S)
if(H(i) == 0): R = V, G = t, B = p
if(H(i) == 1): R = q, G = V, B = p
if(H(i) == 2): R = p, G = V, B = t
if(H(i) == 3): R = p, G = q, B = V
if(H(i) == 4): R = t, G = p, B = V
if(H(i) == 5): R = V, G = p, B = q

それにしても、HSVだけ変換が面倒くさいですね。。
シェーダでHSV-RGB変換をやってしまうとif文判定がかなりかさばって
しまうので、正直やめたほうがいいなと思いました(スキップ自体は
いいことなんですが、命令レジスタ自体が圧迫されるので)。
それと研究してみて、ふとHSV-RGB変換をやらなくても影の色処理が
できる方法を思いついたので、今度はそちらを試してみようかと思います。

2010.04.07 C++:フレネル反射!

昨日ふと、手動ミップマップを使うことで水面のフレネル反射が
表現できるんじゃないかなと思いつき、さっそく導入してみることにしました。

結構サクサクっと導入できました!実際に試してみると
カメラの角度によっては結構不自然な感じになってしまいましたが
上からみた感じだとそれなりにそれなりな感じです笑。
動画を録画してみて思いましたが、そういえば”どうぶつの森”の
水面の表現もカメラから水平ラインで反射していたので、
ひょっとしたら同じテクニックで表現しているのかもしれません。

考察としては、あくまで擬似的なものですが手動ミップマップで
表現することで元々のミップマップテクスチャを別のテクスチャと
差し替えているだけなので、コストパフォーマンス0でフレネル反射を
表現できてしまうのが素晴らしいなと思いました。

2010.04.07 C++:今度は視錐台カリング

さっそく視錐台カリングを試してみました。実はまだ視錐台カリングの
ビューポート行列の生成がおかしいのか、視錐台よりも一回り
二回りくらいおおきく判定されているんですが、キャラの描画
スキップ時にスキニング行列の計算もスキップすることでだいたい
平均で60fps近くでるようになりました。というより、前回の
速度の問題はどうやらHDDの容量不足が原因みたいでした。

それと試しにオクルージョンカリングと併用したりもしてみましたが、
カリングできるときは早くなりますが、カリングできないときは
結構遅くなりますね、やっぱり。とりあえず、僕の中では
オクルージョンカリングは諸刃の剣のイメージです。

以下、結論を少しばかりまとめてみます。
・カリングするほどシーンが大きくない場合は、そもそも
 カリング判定処理をしない方が早い。
・シーンが視野より十分に大きい場合は、視錐台カリングで
 Zカリングを検討する。
・FPSゲームのように複雑に入り組んだシーンではさらに
 オクルージョンカリングを行うことでスキップ回数が向上する。

実は自作の算術計算回りも除々にSSE等を利用し始めてます。
早くなっているかどうかはほとんど分からない程度なんですけどね笑。

2010.04.05 C++:オクルージョンカリングてすと

視錐台カリングを実装するくらいならオクルージョンカリングを
実装したほうがいいのではないかと思い、試しに実装してみたのですが。。

うーん。早くなるどころかなぜか不思議なことになりました苦笑。

一応説明すると、オクルージョンカリングというのはバウンディング
ボックスもしくはバウンディングスフィアのような単純モデルを利用して、
あらかじめモデルが画面に何ピクセル描画されるかを計算して
描画ピクセル数が0なら描画のスキップを行うという技術です。
で、バウンディングボックスを用いてオクルージョンカリングを
試してみたんですが、なぜか画面に描画されるモデル数が
多いときのほうがフレームレートが上がるんですよ、これが。
・画面内にモデル0~3体:33FPS
・画面内にモデル4~10体:40FPS

自分でも訳が分からないのですが。。おそらくオクルージョンカリングで
ピクセル数をCPUに取得するためにはオクルージョン用プリミティブの
描画終了を待たなければならないので、この描画待ち時間が
描画しているときより描画していないときの方が長くなるのかなと
いうのが今のところの僕の仮説。けど、実際は何ともいえません笑。

それにオクルージョンカリングをするためにオクルージョン
プリミティブを余分に描画しているので、結局Drawコストが
モデル数倍になってしまい、僕の環境ではオクルージョン
カリングしないほうが処理が早くなってしまいました(なんだそりゃ)。

ただ、これはオクルージョンカリング前に視錐台カリングを
行い、視錐台に入っている場合はオクルージョンカリングの
チェックを行うことで対処できるのかな、と思ったのですが
なんだか2度手間のような感じです。。

まあオクルージョンカリング自体はZカリングのアプローチ以外にも
例えば敵キャラの視野用のオクルージョンカリングを用いて
敵の視線にプレイヤーがいるかどうかの正確な処理が行えたり
するので、結構有用なんじゃないかと思う訳です。

結局、まとめとしては色々試してみるのはいいことです、ということでした。

2010.04.03 C++:BGM切り替え

今までBGMを1曲ずっと流しているだけでしたが、新しくBGM切り替えが
できるようになりました。そろそろメニュークラスや本格的にシーン管理
部分に入りたいので、軽い下積みというやつです。

視錐台カリングをやろうかなとも思ったんですが。今のところ
GPUは余裕があって、CPU処理がパーティクル等の処理で重たく
なっているので、視錐台カリングをやるとGPUの負荷は減っても
CPUの負荷が増えるため、逆に重くなるんじゃないかなということで、
とりあえず保留にすることにしました。PCの性能を限界を見極めて
プログラムを組むのは色々と難しいなと思います。

2010.04.01 C++:プレイ動画

ようやく実際のプレイ画面をキャプチャして動画にしてみました。
ただ実際プレイしているときは音声がついてますが、一応
音声の方は版権うんぬんがあるのでカットしています。

4月1日なので、動画くらいなら。。いいですよね苦笑。
ちなみに実際の音声は、試験的にまやろーやるさんの曲
流していたりします。透き通った歌声がとても心地いい感じです。
リンクから各自脳内補完でよろしくお願いします笑。

実をいうと、本当はもっとクオリティをあげたかったんですが、
やっぱり色々やることが多くて大変ですね。なので、ちょっとずつ、
自分の思い通りのクオリティに近づけていこうかと思います。

2010.03.30 C++:背景クラス完成!

ファイル 256-1.png

長い間苦戦していた背景クラスがようやく完成というところまで来ました。

時間がかかったのは、今まで勉強してこなかった衝突判定を山のように
使用することになったからなのですが、おかげで以前より大分衝突判定に
強くなったので、とりあえず良しとしよう笑。

今回は簡単な動画を用意しようかと思ったけど、まだモーション
切り替えやモデルの半透明描画を実装してないんですよね。他には
モデル間の衝突判定や、メニュークラスも手すらつけていない状態なので。。

やればやるほど先が長いのが見えてくるなあ苦笑。

2010.03.20 C++:背景クラスをぼちぼち

最近になって、ようやくある程度見栄えがいい感じになりつつあるので、
そろそろ動画でも作って公開してみようかなと思ったんですが。
背景クラスを作成しないと、ニッチもサッチもいかない感じでしたので
現在はもっぱら背景クラスの制作中です。

とりあえずとっかかりとして指定したポリゴン内にオブジェクトが
存在しているかどうかをできるようにしてみました。これを利用して
そのポリゴンから高さを求めたり、頂点カラーを取得して
場所によって明るくしたり暗くしたりできるわけです。

まあ、やってること自体はすごく単純なことなんですが。
一番問題になってくるのが、当たり判定用のメッシュのポリゴン数が
多い場合、モデル位置のポリゴンを検出する時間がどんどん
大きくなってしまうので、どうしようかなと色々考えた末、一定区間ごとに
当たり判定用メッシュのインデックスをデータベース化する
ことにしました。

今のところは当たり判定用メッシュ読み込み時のデータベース化の
プログラムが組み終わったかなというところです。それと実は
もう一つ、ポリゴンの検出回数を減らすための工夫を追加する予定
なんですが、これは話が長くなりそうなので今は秘密にしておきましょう笑。

早く動画まで行けるといいなあ。