トップページ > 過去ログ > 記事閲覧
法線の取得
名前:wisteria 日時: 2009/11/01 20:28

BCC5.5でDXライブラリ3.00dを使用しています。 DrawPolygonIndexed3D()で第二引数は法線ということですが、これはどのように求めればいいのでしょうか。 描画したいポリゴンはすべて四角形なので、各頂点のワールド座標(3次元座標)は double x[4],y[4],z[4]; (つまり(x[0],y[0],z[0]),(x[1],y[1],z[1]),(x[2],y[2],z[2]),(x[3],y[3],z[3])の4つを頂点とする四角形を描画する場合です。) で渡されます。 数学は数Iや数Aの途中程度の知識しかないため、検索して出てきたものを見てもさっぱりに近いぐらいわかりませんでした・・・。

Page: 1 |

Re: 法線の取得 ( No.1 )
名前:管理人 日時:2009/11/05 12:44

法線はポリゴンの表( おもて )面に垂直な長さ1のベクトルで、ポリゴンの頂点から外積を使って算出することができます ちなみに DrawPolygonIndexed3D では法線をライティング計算に使用しているので、ライティングを行わない場合は 法線をセットしなくても大丈夫です( ライティングを行わない場合は SetUseLighting( FALSE ) ; を DrawPolygonIndexed3D を実行する前に呼んでおいてください ) 私もあんまり理解できていないので詳細は割愛しますが、 まず外積は3次元の値二つを使用して行います この3次元の値を原点から3次元の値の座標まで伸びるベクトルとみなした場合 外積の結果は掛け合わせる二つのベクトルに垂直なベクトルとなります( 外積の結果も3次元の値です ) なので、この仕組みを利用してポリゴンの三頂点を使って以下のような計算をします VECTOR v01, v02, outv ; // 頂点0から頂点1へのベクトルを算出 v01 = VGet( x[1] - x[0], y[1] - y[0], z[1] - z[0] ) ; // 頂点0から頂点2へのベクトルを算出 v02 = VGet( x[2] - x[0], y[2] - y[0], z[2] - z[0] ) ; // 二つのベクトルの外積を計算( 二つのベクトルに垂直なベクトルの算出 ) // outv.x = v01.y * v02.z - v01.z * v02.y ; // outv.y = v01.z * v02.x - v01.x * v02.z ; // outv.z = v01.x * v02.y - v01.y * v02.x ; outv = VCross( v01, v02 ) ; // 外積の値が長さ1とは限らないので、正規化( 長さを1にする )、これが法線です // float r = sqrt( outv.x * outv.x + outv.y * outv.y + outv.z * outv.z ) ; // outv.x /= r ; // outv.y /= r ; // outv.z /= r ; outv = VNorm( outv ) ; ちなみに外積は掛ける順番( VCross( v01, v02 ) か VCross( v02, v01 ) か )で結果のベクトルの方向が 180度反転しますので、計算結果がポリゴンの表( おもて )面の方向になる順番で掛ける必要があります
Re: 法線の取得 ( No.2 )
名前:wisteria 日時:2009/11/07 18:14

ありがとうございます。 もしかける順番を間違いベクトルが逆になっていたら、ライトは正しく反映されませんよね?
Re: 法線の取得 ( No.3 )
名前:管理人 日時:2009/11/14 22:18

はい、裏面にライトが当たった際と同じ計算結果になり、その部分が真っ黒になると思います

Page: 1 |