首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Direct3D9计算视图空间点光源位置

Direct3D9计算视图空间点光源位置
EN

Stack Overflow用户
提问于 2013-01-16 17:21:58
回答 2查看 676关注 0票数 3

我正在开发我自己的延迟渲染引擎。我将场景渲染到包含漫反射颜色、视图空间法线和深度的g缓冲区(目前)。我已经为第二个渲染阶段实现了平行光,它工作得很好。现在我想渲染一个点光源,这有点难。

我需要着色器在视图空间中的点光源位置,因为我在g缓冲区中只有深度,并且我负担不起每个像素的矩阵乘法。我得到了灯光的位置,并通过相同的矩阵变换它,通过它我变换着色器中的每个顶点,因此它应该与场景中的顶点对齐(使用D3DXVec3Transform)。但事实并非如此:变换后的位置几乎根本不代表视图空间的位置。它的x,y坐标超出了图表,它们通常超出(-1,1)范围。变换的位置在一定程度上与摄影机方向有关,但灯光移动太快,y轴反转。仅当摄影机位于(0,0,0)时,灯光才位于屏幕中心的(0,0)。下面是我在每一帧中执行的相关渲染代码:

代码语言:javascript
复制
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只是我在偷懒):

代码语言:javascript
复制
float dist=length(float2(IN.texture0*2-1)-float2(poslight.xy));
OUT.col=tex2D(Sdiff,IN.texture0)/dist;

我尝试过在没有投影的情况下仅通过matView变换灯光,但问题仍然是一样的。如果我在着色器中变换灯光,结果是相同的,所以问题出在矩阵本身。但它与变换顶点是同一个矩阵!顶点的处理方式有多大不同?

你能看一下代码并告诉我错误在哪里吗?在我看来,它应该可以工作,但它不是。提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-20 03:10:36

你不需要矩阵乘法来重建视图位置,这里有一个代码片段(来自andrew lauritzen deffered light示例)

tP是投影变换,position screen是-1/1像素坐标,viewspaceZ是从纹理采样的线性深度。

代码语言:javascript
复制
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;
}
票数 0
EN

Stack Overflow用户

发布于 2013-01-16 20:11:32

此变换的结果D3DXVec3Transform(&lpos,&lpos2,&vysl);是齐次空间中的向量(即投影向量,但不除以w)。但是在你的着色器中,你使用它的xy组件而没有遵守这个(w)。这(很可能)就是问题所在。您可以自己将vector除以w,或者使用D3DXVec3Project而不是D3DXVec3Transform

这对顶点很有效,因为(我想)你在顶点着色器中用相同的viewproj矩阵对它们进行mul,并将转换后的值传递给插值器,在插值器中,硬件最终将其xyz除以插值的'w‘。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14354895

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档