1 :
デフォルトの名無しさん:
3Dプログラミング一般。
質問、テクニックなど。
2 :
デフォルトの名無しさん:2001/02/09(金) 17:12
ハイトフィールドから頂点の法線を求める効率的なアルゴリズム教えてください。
単に注目頂点に接続している面の法線の平均ではいけないの?
ところでハイトフィールドって一般的な用語なの? ハジメテキイタヨ
>単に注目頂点に接続している面の法線の平均ではいけないの?
法線の平均って外積で良いんですよね。
下のようにしてみたのですが、どうにもうまくいきません。
m_pHightFieldは各位置での高さを収めた行列です。
D3DXVECTOR3 getPointNormal(int x, int z)
{
D3DXVECTOR3 triNorm[6], ptNorm;
float hight[7];
hight[0] = (m_pHightField[(z - 1) * w + x ] - 192) / 4;
hight[1] = (m_pHightField[(z - 1) * w + x - 1] - 192) / 4;
hight[2] = (m_pHightField[ z * w + x - 1] - 192) / 4;
hight[3] = (m_pHightField[ z * w + x ] - 192) / 4;
hight[4] = (m_pHightField[ z * w + x + 1] - 192) / 4;
hight[5] = (m_pHightField[(z + 1) * w + x - 1] - 192) / 4;
hight[6] = (m_pHightField[(z + 1) * w + x ] - 192) / 4;
if(x < 0) hight[2] = hight[5] = 0.0f;
if(z < 0) hight[0] = hight[1] = 0.0f;
if(x >= w) hight[1] = hight[4] = 0.0f;
if(z >= h) hight[5] = hight[6] = 0.0f;
D3DXVec3Cross(&triNorm[0], &D3DXVECTOR3(x , hight[0], z - 1), &D3DXVECTOR3(x , hight[3], z ));
D3DXVec3Cross(&triNorm[0], &triNorm[0] , &D3DXVECTOR3(x - 1, hight[2], z ));
D3DXVec3Cross(&triNorm[1], &D3DXVECTOR3(x + 1, hight[1], z - 1), &D3DXVECTOR3(x , hight[3], z ));
D3DXVec3Cross(&triNorm[1], &triNorm[1] , &D3DXVECTOR3(x , hight[0], z - 1));
D3DXVec3Cross(&triNorm[2], &D3DXVECTOR3(x + 1, hight[4], z ), &D3DXVECTOR3(x , hight[3], z ));
D3DXVec3Cross(&triNorm[2], &triNorm[2] , &D3DXVECTOR3(x + 1, hight[1], z - 1));
D3DXVec3Cross(&triNorm[3], &D3DXVECTOR3(x - 1, hight[2], z ), &D3DXVECTOR3(x , hight[3], z ));
D3DXVec3Cross(&triNorm[3], &triNorm[3] , &D3DXVECTOR3(x - 1, hight[5], z + 1));
D3DXVec3Cross(&triNorm[4], &D3DXVECTOR3(x - 1, hight[5], z + 1), &D3DXVECTOR3(x , hight[3], z ));
D3DXVec3Cross(&triNorm[4], &triNorm[4] , &D3DXVECTOR3(x , hight[6], z + 1));
D3DXVec3Cross(&triNorm[5], &D3DXVECTOR3(x , hight[6], z + 1), &D3DXVECTOR3(x , hight[3], z ));
D3DXVec3Cross(&triNorm[5], &triNorm[5] , &D3DXVECTOR3(x + 1, hight[4], z ));
D3DXVec3Normalize(&triNorm[0], &triNorm[0]);
D3DXVec3Normalize(&triNorm[1], &triNorm[1]);
D3DXVec3Normalize(&triNorm[2], &triNorm[2]);
D3DXVec3Normalize(&triNorm[3], &triNorm[3]);
D3DXVec3Normalize(&triNorm[4], &triNorm[4]);
D3DXVec3Normalize(&triNorm[5], &triNorm[5]);
D3DXVec3Cross(&ptNorm, &triNorm[0], &triNorm[1]);
D3DXVec3Cross(&ptNorm, &ptNorm , &triNorm[2]);
D3DXVec3Cross(&ptNorm, &ptNorm , &triNorm[3]);
D3DXVec3Cross(&ptNorm, &ptNorm , &triNorm[4]);
D3DXVec3Cross(&ptNorm, &ptNorm , &triNorm[5]);
D3DXVec3Cross(&ptNorm, &ptNorm , &triNorm[6]);
D3DXVec3Normalize(&ptNorm, &ptNorm);
return ptNorm;
}
>>1=2
このコード滅茶苦茶じゃねーか
なぁ、これネタなんだろ?
>>4 >法線の平均って外積で良いんですよね。
ちゃうだろ。単にベクトルの総和を正規化すればよし。
数学的には意味不明な操作だけど、グラフィック屋さんの常套手段だね。
(普通は注目頂点に接続している角度で重み付け平均するけど、メッシュだから
あんまり差はないでしょう。たぶん)
コードはダメなニオイがするので見てません。
>>2 >ハイトフィールドから頂点の法線を求める効率的なアルゴリズム教えてください。
「効率的な」と書いたら、非効率的なアルゴリズムは実装できていると
思われるよ。4を見ると効率云々の問題ではないのでは?
正確にことばを使ってね。
>>5 さんきゅー
#ネタだったら笑って許して
すみません。
ネタじゃないんですが、、、
ダメなのはわかってます。
正常に出来てないんですから。
とりあえず、こんなレベルでわかるように説明して欲しいな、と思ったので。
おかしな所が多すぎるんで、とりあえず主な箇所だけ指摘するよ。
その前に、コード中の height field 想像図。
表示がずれるのでエディタにコピペとかして。
Z
↑
| FG
|----CDE
| BA
| |
◎------------→X
Y(手前方向+)
原点(0,0,0)をO
点ABCDEFGの座標値はそれぞれコード中の
(x ,height[0],z-1)
(x-1,height[1],z-1)
(x-1,height[2],z )
(x ,height[3],z )
(x+1,height[4],z )
(x-1,height[5],z+1)
(x ,height[6],z+1)
と対応する。
10 :
5:2001/02/10(土) 00:01
あれ。半角スペースは省かれるのか(鬱だ
Z
↑
| FG
|----CDE
| BA
| |
◎------------→X
Y(手前方向+)
11 :
5:2001/02/10(土) 00:10
さて、一発目の外積
D3DXVec3Cross(&triNorm[0],&D3DXVECTOR3(x,height[0],z-1),&D3DXVECTOR3(x,height[3],z));
は何をやってるのかというと、これは OA×OD だよね?
つまり、三角形OADの法線を求めてることになるけど、
本当にこれでいいのかい?
12 :
4:2001/02/10(土) 05:46
根本的に間違っているようでした。
外積とか全然関係なかったです。
現在とりあえず用意しているハイトフィールドは64x64です。
それで、ソースを書き直してみました。
何度も紙に図を書きながら書いて、おおむねうまく表示されているようなのですが、
ちょっと一部おかしいところがあるんです。
ソースばかり貼ってウザイと思いますが、時間が空いたらで良いのでよろしくお願いします。
D3DXVECTOR3 v1, v2, triNorm[6], ptNorm;
// とりあえず、淵の処理は保留
if(x == 0 || z == 0 || x == w - 1 || z == h - 1)
{
return D3DXVECTOR3(0.0f, 1.0f, 0.0f);
}
D3DXVec3Normalize(&v1, &D3DXVECTOR3( 0, m_pHeightField[ x + (z - 1) * w], -1));
D3DXVec3Normalize(&v2, &D3DXVECTOR3(-1, m_pHeightField[(x - 1) + (z - 1) * w], -1));
D3DXVec3Cross(&triNorm[0], &v1, &v2);
D3DXVec3Normalize(&triNorm[0], &triNorm[0]);
v1 = v2;
D3DXVec3Normalize(&v2, &D3DXVECTOR3(-1, m_pHeightField[(x - 1) + z * w], 0));
D3DXVec3Cross(&triNorm[1], &v1, &v2);
D3DXVec3Normalize(&triNorm[1], &triNorm[1]);
v1 = v2;
D3DXVec3Normalize(&v2, &D3DXVECTOR3( 0, m_pHeightField[ x + (z + 1) * w], 1));
D3DXVec3Cross(&triNorm[2], &v1, &v2);
D3DXVec3Normalize(&triNorm[2], &triNorm[2]);
v1 = v2;
D3DXVec3Normalize(&v2, &D3DXVECTOR3( 1, m_pHeightField[(x + 1) + (z + 1) * w], 1));
D3DXVec3Cross(&triNorm[3], &v1, &v2);
D3DXVec3Normalize(&triNorm[3], &triNorm[3]);
v1 = v2;
D3DXVec3Normalize(&v2, &D3DXVECTOR3(+1, m_pHeightField[(x + 1) + z * w], 0));
D3DXVec3Cross(&triNorm[4], &v1, &v2);
D3DXVec3Normalize(&triNorm[4], &triNorm[4]);
v1 = v2;
D3DXVec3Normalize(&v2, &D3DXVECTOR3( 0, m_pHeightField[ x + (z - 1) * w], -1));
D3DXVec3Cross(&triNorm[5], &v1, &v2);
D3DXVec3Normalize(&triNorm[5], &triNorm[5]);
D3DXVec3Add(&ptNorm, &triNorm[0], &triNorm[1]);
D3DXVec3Add(&ptNorm, &ptNorm , &triNorm[2]);
D3DXVec3Add(&ptNorm, &ptNorm , &triNorm[3]);
D3DXVec3Add(&ptNorm, &ptNorm , &triNorm[4]);
D3DXVec3Add(&ptNorm, &ptNorm , &triNorm[5]);
D3DXVec3Normalize(&ptNorm, &ptNorm);
13 :
4:2001/02/10(土) 05:49
で、正解に近づいたとは思うのですが、どうでしょうか。
m_pHeightField[]はfloat型のハイトフィールドです。
で、求めたい頂点を含むポリゴン6つの法線を求めて、
その平均値を点の法線としています。
14 :
4:2001/02/10(土) 05:58
15 :
4:2001/02/10(土) 22:30
5さん、ありがとうございました。
どうにか、できたようなので結果を報告します。
|// ポリゴンの法線を求める
|D3DXVec3Normalize(&v1, &D3DXVECTOR3( 0.0f, m_pHeightField[x + (z - 1) * w] - m_pHeightField[x + z * w], -1.0f));
|D3DXVec3Normalize(&v2, &D3DXVECTOR3(-1.0f, m_pHeightField[x - 1 + (z - 1) * w] - m_pHeightField[x + z * w], -1.0f));
|D3DXVec3Cross(&triNorm[0], &v1, &v2);
|D3DXVec3Normalize(&triNorm[0], &triNorm[0]); (*1)
|(各ポリゴンにつき繰り返し)
|
|D3DXVec3Add(&ptNorm, &triNorm[0], &triNorm[1]);
|(各法線につき繰り返し)
|
|D3DXVec3Normalize(&ptNorm, &ptNorm);
このような感じでできるようになりました。
しかし、ひとつだけまだわからないことがあります。
*1の時点で、正規化するのが正しいのでしょうか?
oct.2000のCマガ47ページには
>・ベクトルの外積
>(中略)
>もしAとBがともに正規化されている場合、
>この間の外積で求めたベクトルも大きさが1となります。
とあるのですが、正規化しないと大きさが1ではないようなのですが。
どうか、知恵をお貸しください。
16 :
5:2001/02/11(日) 00:48
外積の大きさ
|x×y|=|x||y|sinθ
だから2ベクトルのなす角で大きさは変わるね
θ≒0 や θ≒π のときの計算結果には注意したほうがいい
※そのCマガ10月号の記事は大ウソ
常に θ=π/2 という条件ならば大きさは常に 1 だけれど。
その雑誌が手元にないので何ともいえない
18 :
デフォルトの名無しさん:2001/02/11(日) 10:12
参考書ageてください。
19 :
デフォルトの名無しさん:2001/02/11(日) 11:11
なんでレイトレの話題って出ないんでしょ。
と、いうことで。
Cook-Torranceのモデルがよくわからないので
詳しい人教えてくれage
21 :
5:2001/02/11(日) 17:21
>>1 同じようなスレを幾つも立てるのはどうかと思う。
1自身にスレを育てようとする態度もあまり感じられないし
クレクレ君ばかりの駄スレになる予感がするので
sage
22 :
デフォルトの名無しさん:2001/02/11(日) 21:26
>>1自身にスレを育てようとする態度もあまり感じられないし
頭悪そう・・・。
23 :
くだらない質問:2001/02/11(日) 23:54
むちゃくちゃ厨房な質問ですみませんが、
みなさんはIM・RMどっち使ってますか?
理由もお聞かせ下さい。
また、3DCGをDrawPrimitiveで書くとき
どんなコンバートツール使ってますか?
自分はIMでPGし始めたのですが、ここで詰まってます。
ちなみにLightWaveは高くて買えません。
24 :
デフォルトの名無しさん:2001/02/12(月) 00:07
23です。
今、他のスレ読んでて気づきました。
駄レスしてごめんなさい。
もうちょい自分で調べます。
以上、2chプログラム板初心者でした。
26 :
くだらない質問:2001/02/12(月) 00:10
>24
・・・と、いきなりのレス。
ありがとうございます。
29 :
28:2001/02/12(月) 01:53
あ、24へのレスね。
OpenGLスレの人たちに聞けばちゃんとした反応があると思う
>>19 分からない箇所を具体的に書いたほうが良いと思う。
31 :
デフォルトの名無しさん:2001/02/12(月) 02:13
せっかくスレあるから聞きたいんですけどいいでしょうか?
「XZが平面」で「Yが標高」という3Dのマップで
人を歩かせたいのですがXZ平面での移動量と標高データで
高さをわりだして位置を決めるやり方だと高い山に登るとき
足が速くなってしまうのですが、他に何かいいやり方って
ないでしょうか?ちなみにポリゴンの頂点はXZ平面でみると
等間隔に並べてあります。Yの標高とはその頂点の高さを表して
います。
>Cook-Torranceのモデル
Blinnのモデルと同じじゃん
■■■■■■■■■■■■ 終了 ■■■■■■■■■■■■
35 :
デフォルトの名無しさん:2001/02/12(月) 04:07
>>33 じゃあ、33ならどう作るの?
これって高校数学程度じゃできないと思うけど。
>31=35
おいおい、速度ベクトルの大きさを一定して解決するじゃねーか。
ジサクジエンウザイネ
35=可哀想ドキュソ
このスレ終わってるな
まともな書き込みする奴もみんなsageてるよ
40 :
デフォルトの名無しさん:2001/02/12(月) 09:34
>>36 だからそれができないんだって。
っていうかプログラム組んでみてくれよ。
一定の速度ベクトルぶんだけその方向に進んでも、
標高データから登り坂だったり下り坂だったりするだろ。
そうするとポリゴンを複数挟んで移動してしまったとき?????
になるんだよ。わっかんねーかなー。