(注:【D3D11游戏编程】学习笔记系列由优快云作者BonChoix所写,转载请注明出处:http://blog.youkuaiyun.com/BonChoix,谢谢~)
在前面两篇介绍Cube Mapping的文章中,我们所使用到的Cube Map都是事先制作好的,这样的一个好处就是运行时效率很高,适合于大多数情形。但如果对于即时动态变化的场景来说,依靠静态图来实现反射效果就不再适用了。因为在不同时刻,一个物体周围的场景是不断变化的,想要把这些变化在物表的反射中体现出来,就需要一张动态的环境图。
1、Cube Map相关参数
动态的环境图显然是不可能事先制作出来的,而需要在运行时实时的计算得出。在前面我们也不止一次地提到过环境图的获得方法:即把照相机放置于物体中心,视角调整为90度,向其正X、负X、正Y、负Y、正Z、负Z六个方向上拍摄对应的六张照片,这样得到的六张图即组成了当前时刻该物体周边的环境图。此外,这里还要指出下,仅仅拥有的这六张图是不够,六张图的顺序、相机摆放也很重要,这样才能被正确地映射(至少在使用HLSL中的Sample函数时是这样)。
在前面我们仅仅是用到了已经制作好的cube map,因此这些因素就不需要再去关注了。但现在我们需要自己来生成环境图,因此必须要搞清楚。在拍摄环境图时,我们遵循的顺序为:正负X、正负Y、正负Z。如下图为一张环境图的展开图及其对应的序号:(这里针对的是左手坐标系)
关于相机摆放,从上图的展开情形应该也能看得出来:默认情形下相机面朝Z+方向。因此对于正负X面的两张图,只需要相应地让相机水平旋转到正X和负X面上即可;对于正负Y面,需要把相机沿X轴旋转使其仰面朝天、低头朝下摆放;正负Z面同正负X面类似,水平旋转使其对准Z+和Z-即可。
涉及到程序中对相机摆放的设置,我们需要指定的基本参数依然是:位置、观察点、相机对应的up向量。假设一个物体位于(x, y, z)处,现在拍摄它的环境图,相机的设置相关代码如下:
XMFLOAT3 ups[6] =
{
XMFLOAT3( 0.f, 1.f, 0.f),
XMFLOAT3( 0.f, 1.f, 0.f),
XMFLOAT3( 0.f, 0.f,-1.f),
XMFLOAT3( 0.f, 0.f, 1.f),
XMFLOAT3( 0.f, 1.f, 0.f),
XMFLOAT3( 0.f, 1.f, 0.f)
};
XMFLOAT3 targets[6] =
{
XMFLOAT3( x + 1.f, 0.f, 0.f),
XMFLOAT3( x - 1.f, 0.f, 0.f),
XMFLOAT3( 0.f, y + 1.f, 0.f),
XMFLOAT3( 0.f, y - 1.f, 0.f),
XMFLOAT3( 0.f, 0.f, z + 1.f),
XMFLOAT3( 0.f, 0.f, z - 1.f)
};
for(UINT i=0; i<6; ++i)
{
m_dynamicCameras[i].LookAt(XMFLOAT3(x, y, z), targets[i], ups[i]);
m_dynamicCameras[i].SetLens(XM_PI*0.5f,1.f,1.f,1000.f);
m_dynamicCameras[i].UpdateView();
}
这里六个ups向量分别对应拍摄六张图时相机对应的上方向, targets为对应的六个观察点,通