ページ 11

フォグ

Posted: 2007年2月08日(木) 18:40
by キ選
どうも、こんばんは。
ABDX(4.24)で3Dプログラムを作っているのですが、フォグ(遠くに行くほど霧がかったようになる)がうまくいかず、困っています。

コード: 全て選択

Dim StartR=300 As Single
Dim EndR=1000 As Single
'フォグの設定
dx_lpD3DDEV -> SetRenderState(D3DRS_FOGENABLE,TRUE)
dx_lpD3DDEV -> SetRenderState(D3DRS_FOGCOLOR,D3DCOLOR_ARGB(0,255,255,255))
dx_lpD3DDEV -> SetRenderState(D3DRS_FOGSTART,StartR As Dword)
dx_lpD3DDEV -> SetRenderState(D3DRS_FOGEND,EndR As Dword)
dx_lpD3DDEV -> SetRenderState(D3DRS_FOGVERTEXMODE,D3DFOG_LINEAR)
初期化部分に上記のような記述をしているのですが、実際実行させると、2Dスプライト及びメッシュが全て、フォグに設定した色に染まってしまいます。
グラボ依存の機能のようなので、頂点フォグ、ピクセルフォグ、また指数フォグも試して見たのですが、どれもほぼ同じ状況になってしまいます。
どなたか知識をお貸しください。

Re: フォグ

Posted: 2007年2月08日(木) 20:44
by MML
自分はABでDirectXを使っていないのでよくはわかりませんが、
HSPでDirectXを使用しているのでそこの知識からちこっと

グラフィックボードのバージョンが古いとフォグは単なる邪魔ものになってしまいます。(半透明ではなく「完全な不透明」)
多分。

ちなみに、
半透明のものにはフォグはかかりません。はい。

Posted: 2007年2月08日(木) 21:39
by キ選
返信ありがとうございます。
人が作ったゲーム(DirectX9)などをプレイする限りフォグ効果は行われているようなので、恐らく自分のPCでは一応使えると思います。(根拠は無いけど(ぁ

それと、一つ気になったのですが、フォグというものは半透明とかではなく、距離に応じてあらかじめ設定しておいた色に、その物体の色を近づけていくものではないのでしょうか?

あれから、いろいろ試行錯誤してみてるのですが、状況は変わらず、まったくの手詰まりですorz

遠くのものをいつまでも表示しておくのはもったいないので、それを一定の距離から描画しないようにする前の誤魔化しに使おうと思っているのですが。。。

Posted: 2007年2月08日(木) 21:49
by MML
> それと、一つ気になったのですが、フォグというものは半透明とかではなく、距離に応じてあらかじめ設定しておいた色に、その物体の色を近づけていくものではないのでしょうか?
そうです。だからかなり処理が重いのかも(爆

> あれから、いろいろ試行錯誤してみてるのですが、状況は変わらず、まったくの手詰まりですorz
自分がお役に立てなくてすいません。

Posted: 2007年2月08日(木) 22:01
by キ選
ああ、もしかしたら私の文章の書き方がまずかったかもしれません。
「2Dスプライト及びメッシュが全て、フォグに設定した色に染まってしまう」というのは、距離に関係なく映っているもの全てが、設定した色に塗りつぶされてしまうということなんです。

最初にかいたソースだとフォグ色が[0,255,255,255](アルファ値は無視される)なので、映っているものが距離に関係なく全て真っ白になってしまっています。

Re: フォグ

Posted: 2007年2月09日(金) 22:09
by NoWest
> どうも、こんばんは。
> ABDX(4.24)で3Dプログラムを作っているのですが、フォグ(遠くに行くほど霧がかったようになる)がうまくいかず、困っています。
>
>

コード: 全て選択

Dim StartR=300 As Single
> Dim EndR=1000 As Single
> 'フォグの設定
> dx_lpD3DDEV -> SetRenderState(D3DRS_FOGENABLE,TRUE)
> dx_lpD3DDEV -> SetRenderState(D3DRS_FOGCOLOR,D3DCOLOR_ARGB(0,255,255,255))
> dx_lpD3DDEV -> SetRenderState(D3DRS_FOGSTART,StartR As Dword)
> dx_lpD3DDEV -> SetRenderState(D3DRS_FOGEND,EndR As Dword)
> dx_lpD3DDEV -> SetRenderState(D3DRS_FOGVERTEXMODE,D3DFOG_LINEAR)
>
> 初期化部分に上記のような記述をしているのですが、実際実行させると、2Dスプライト及びメッシュが全て、フォグに設定した色に染まってしまいます。
> グラボ依存の機能のようなので、頂点フォグ、ピクセルフォグ、また指数フォグも試して見たのですが、どれもほぼ同じ状況になってしまいます。
> どなたか知識をお貸しください。

コード: 全て選択

dx_lpD3DDEV -> SetRenderState(D3DRS_FOGSTART,VarPtr(StartR))
dx_lpD3DDEV -> SetRenderState(D3DRS_FOGEND,VarPtr(EndR) )
としてみてはどうですか?
試してませんけど。。。

Posted: 2007年2月10日(土) 13:16
by ゲスト
NoWestさん返信ありがとうございます。試してみましたが、やはり距離とは関係なく真っ白になってしまいます。
SetRenderStateメソッドの第二パラメータはDWord型でしか受け取ってくれないらしく、浮動小数点のアドレスをDWordポインタにキャストしてやる必要があるそうなのですが、どうもそこでうまく行っていない気がします。

Posted: 2007年2月10日(土) 17:56
by 小千谷太郎
英語版のDirectXヘルプしか持っていないのであってるかどうかわかりませんが、
「頂点フォグはDirect3Dのライティングおよびトランスフォームエンジンによって計算される。」と書かれています。
ちゃんとライティングされているかどうか、メッシュのFVFにD3DFVF_NORMALが含まれているかどうか調べてみてはどうでしょうか?
ピクセルフォグというものもあるみたいですよ。

Posted: 2007年2月10日(土) 21:40
by ゲスト
すみません。ピクセルフォグはもう試されたんですね。

Posted: 2007年2月13日(火) 22:19
by キ選
小千谷太郎さんありがとうございます。
調べてみたんですが、ライティングはちゃんとされていますし、メッシュ及びデバイスのFVFにD3DFVF_NORMALフラグは設定されていました。

しかし、相変わらず状況は変わらず手詰まり状態ですorz

Posted: 2007年2月13日(火) 23:44
by NoWest
> NoWestさん返信ありがとうございます。試してみましたが、やはり距離とは関係なく真っ白になってしまいます。
> SetRenderStateメソッドの第二パラメータはDWord型でしか受け取ってくれないらしく、浮動小数点のアドレスをDWordポインタにキャストしてやる必要があるそうなのですが、どうもそこでうまく行っていない気がします。
先ほどネットを流離いつつ、フォグを調べてきました。

どうやら単純にキャストするだけではうまくいかないみたいですね。

C言語でいうところの*((DOWRD*)&StartR)は実際には
Single->*Single>>*DWord->DWord
ここで>>はキャスト、->はポインタ・アドレス操作です。

無理にABに置き換えようとすれば、
(VarPtr(StartR) As *DWord)[0]
ですが、こいつは現在のABではできません。

いろいろ思案しましたが、スマートな方法が思いつかないので
下の関数を使ってみてください。

コード: 全て選択

Function SingleToDWord(Data As Single) As DWord
	memcpy(VarPtr(SingleToDWord),VarPtr(Data),SizeOf(DWord))
End Function

コード: 全て選択

dx_lpD3DDEV -> SetRenderState(D3DRS_FOGSTART,SingleToDWord(StartR))
dx_lpD3DDEV -> SetRenderState(D3DRS_FOGEND,SingleToDWord(EndR) )

Posted: 2007年2月14日(水) 12:49
by イグトランス
> (VarPtr(StartR) As *DWord)[0]
GetDWord(VarPtr(StartR) As *DWord)でどうでしょう?

#DirectXはわからないのでこういうことだけ

Posted: 2007年2月14日(水) 12:56
by NoWest
> > (VarPtr(StartR) As *DWord)[0]
> GetDWord(VarPtr(StartR) As *DWord)でどうでしょう?
>
> #DirectXはわからないのでこういうことだけ
おぉ!

GetDWordってなものも在りましたね。すっかり忘れていました。(笑

Posted: 2007年2月16日(金) 01:04
by キ選
おお!その方法で見事できました!!
皆さん本当にありがとうございましたm(_ _)m