我正在开发自己的延迟渲染引擎。我将场景渲染到包含漫反射颜色、视图空间法线和深度的 g 缓冲区(目前)。我已经为第二个渲染阶段实现了定向光,效果很好。现在我想渲染一个点光源,这有点难。
我需要视图空间中着色器的点光源位置,因为我在 g 缓冲区中只有深度,而且我无法在每个像素中进行矩阵乘法。我采用了光照位置并通过相同的矩阵对其进行了转换,通过该矩阵我在着色器中转换了每个顶点,因此它应该与场景中的顶点对齐(使用 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 不投影来变换灯光,但问题仍然是一样的。如果我在着色器中变换光线,结果是一样的,所以问题出在矩阵本身。但它与变换顶点的矩阵相同!顶点的处理方式有何不同?
你能看一下代码并告诉我错误在哪里吗?在我看来,它应该可以正常工作,但事实并非如此。提前致谢。