3

私は自分のdefferedレンダリングエンジンに取り組んでいます。拡散反射光カラー、ビュースペースの法線、および深度(今のところ)を含むg-bufferにシーンをレンダリングしています。私は第2レンダリング段階に指向性ライトを実装しましたが、それはうまく機能します。ここで、少し難しいポイントライトをレンダリングしたいと思います。

g-bufferには深さしかなく、すべてのピクセルで行列を乗算する余裕がないため、ビュースペースのシェーダーのポイントライトの位置が必要です。ライトの位置を取得し、同じマトリックスで変換しました。これにより、シェーダーですべての頂点を変換し、シーン内の頂点と整列するようにします(D3DXVec3Transformを使用)。しかし、そうではありません。変換された位置は、ビュースペースの位置をほとんど表していません。x、y座標がチャートから外れているため、(-1,1)の範囲から大きく外れていることがよくあります。変換された位置はカメラの向きをいくらか尊重しますが、ライトの動きが速すぎて、y軸が反転します。カメラが(0,0,0)にある場合にのみ、ライトは画面中央の(0,0)にあります。フレームごとに実行される関連するレンダリングコードは次のとおりです。

D3DXMATRIX matView;    // the view transform matrix
D3DXMATRIX matProjection;    // the projection transform matrix

D3DXMatrixLookAtLH(&matView,
                   &D3DXVECTOR3 (x,y,z),    // the camera position
                   &D3DXVECTOR3 (xt,yt,zt),    // the look-at position
                   &D3DXVECTOR3 (0.0f, 0.0f, 1.0f));    // the up direction

D3DXMatrixPerspectiveFovLH(&matProjection,
                           fov,    // the horizontal field of view
                           asp,    // aspect ratio
                           znear,    // the near view-plane
                           zfar);    // the far view-plane

D3DXMATRIX vysl=matView*matProjection;

eff->SetMatrix("worldViewProj",&vysl); //vertices are transformed ok ín shader

//render g-buffer

D3DXVECTOR4 lpos; D3DXVECTOR3 lpos2(0,0,0);

D3DXVec3Transform(&lpos,&lpos2,&vysl); //transforming lpos into lpos2 using vysl, still the same matrix
eff->SetVector("poslight",&lpos); //but there is already a mess in lpos at this time

//render the fullscreen quad with wrong lighting

関連するシェーダーコードではありませんが、それでも、このように明るい位置が表示されます(IN.textureを渡すと、私は怠惰になります):

float dist=length(float2(IN.texture0*2-1)-float2(poslight.xy));
OUT.col=tex2D(Sdiff,IN.texture0)/dist;

投影せずにmatViewだけでライトを変換しようとしましたが、問題は同じです。シェーダーでライトを変換すると、同じ結果になるため、問題はマトリックス自体にあります。しかし、それは頂点を変換するのと同じ行列です!頂点の扱いはどのように異なりますか?

コードを見て、どこに間違いがあるのか​​教えていただけますか?私にはそれはうまくいくはずですが、そうではありません。前もって感謝します。

4

2 に答える 2

0

この変換の結果はD3DXVec3Transform(&lpos,&lpos2,&vysl);、等質空間のベクトルです(つまり、投影されたベクトルですが、で除算されませんw)。ただし、シェーダーでは、xythis()を尊重せずにそのコンポーネントを使用しますw。これは(おそらく)問題です。ベクトルをw自分で分割するか、D3DXVec3Projectの代わりに使用することができますD3DXVec3Transform

mul頂点シェーダーの同じviewproj行列で頂点を処理し、変換された値を補間器に渡し、ハードウェアが最終的にxyz補間された「w」で分割するので、頂点は正常に機能します。

于 2013-01-16T12:11:31.780 に答える
0

ビューの位置を再構築するために行列の乗算は必要ありません。これがコードスニペットです(andrew lauritzen deffered lightの例から)

tPは投影変換、位置画面は-1/1ピクセル座標、viewspaceZはテクスチャからサンプリングした線形深度です。

float3 ViewPosFromDepth(float2 positionScreen,
                            float viewSpaceZ)
{
    float2 screenSpaceRay = float2(positionScreen.x / tP._11,
                               positionScreen.y / tP._22);

    float3 positionView;
    positionView.z = viewSpaceZ;
    positionView.xy = screenSpaceRay.xy * positionView.z;

    return positionView;
}
于 2013-01-19T19:10:35.857 に答える