我正在开发我自己的延迟渲染引擎。我将场景渲染到包含漫反射颜色、视图空间法线和深度的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变换灯光,但问题仍然是一样的。如果我在着色器中变换灯光,结果是相同的,所以问题出在矩阵本身。但它与变换顶点是同一个矩阵!顶点的处理方式有多大不同?
你能看一下代码并告诉我错误在哪里吗?在我看来,它应该可以工作,但它不是。提前谢谢。
发布于 2013-01-20 03:10:36
你不需要矩阵乘法来重建视图位置,这里有一个代码片段(来自andrew lauritzen deffered light示例)
tP是投影变换,position screen是-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-16 20:11:32
此变换的结果D3DXVec3Transform(&lpos,&lpos2,&vysl);是齐次空间中的向量(即投影向量,但不除以w)。但是在你的着色器中,你使用它的xy组件而没有遵守这个(w)。这(很可能)就是问题所在。您可以自己将vector除以w,或者使用D3DXVec3Project而不是D3DXVec3Transform。
这对顶点很有效,因为(我想)你在顶点着色器中用相同的viewproj矩阵对它们进行mul,并将转换后的值传递给插值器,在插值器中,硬件最终将其xyz除以插值的'w‘。
https://stackoverflow.com/questions/14354895
复制相似问题