Direct3D学习(七):DirectX下天空盒子的实现

长平狐 发布于 2012/11/12 11:50
阅读 1K+
收藏 0
概述
三维场影里的天空并不是“真正”的天空,而是用图片拼起来的,欺骗我们眼睛。通常把大家所在的场景用一个几何体包裹起来,再在里面贴上从各个角度的风景图,就好像一个真正的环境一样。想想CS之类的天空,是不是有点印象?


原理
现在的游戏里可能半球用的较多吧?不过原理上一样,我们这里以立方体为例。最简单的方法,莫过于画6个正方形,分别为它们贴上纹理。(要是真这样,我就不用写了-_-)这里我们只用一个正方形,也只用一个纹理,HOHO~想知道怎么回事?住下看吧(欠扁)

立方体环境贴图(Cubic Environment Mapping),也叫立方体贴图,就是一个纹理包含了包围物体场景的图像数据, 就像一个物体在立方体中心一样.每个面包含横竖各90度的视野,每个立方体贴图共6个面. 面的方向如下面左图所示:

右图呢,就是立方体贴图的UV坐标纹理的等价形式,说到底,就是把6张图片拼到一块儿去了而已。不过一般情况下,立方体贴图是映射到一个曲面上,而且,它跟本不使用UV坐标。代替它的是一个3D向量,在DirectX中是D3DFVF_TEXCOORDSIZE3类型。这样就很易的根据表面法向量将周围环境映射到物体表面,实现反射效果(激动人心呢)。

制作立方体贴图
看起来立方体贴图挺麻烦的,其实DirectX自己的纹理格式.dds就支持Cubemap Texture。创建也不需要什么复杂的工具,用SDK带的DxTex.exe就可。
1.       新建一个立方体贴图

2.       选择一个表面

3.       为当面表面添加纹理

在这之前可要把各个方向的贴图准备好哦

4.       重复23,直到6个面全部完成
5.       保存

绘制天空盒子
既然有了立方体贴图,那么是不是画个立方体把图贴上就行了?道理是不错,只不过还有更简单的办法:在面前画个矩形,你往哪看,就画哪个角度的天空!(太贱了,这样的鬼点子是谁想的?)
还记得D3DFVF_XYZRHW不?当顶点结构体中有RHW时,表示这个顶点已经在屏幕坐标系上,不用再进行什么世界变换、视图变换、投影变换,也不用进行光线计算了。不过这时的原点就在客户区的左上角了,其中x向右为正,y向下为正,而z的意义已经变为z-buffer的象素深度。那么我们就在z=1.0f处画这个矩形就行了,没有比1.0f更远的了!

有矩形了,那么怎么把环境贴图映射到上面呢?用HLSL一句搞定!(GPU编程不是盖的)。
不过别记了把纹理坐标向量先算出来:
Output.Tex = normalize( mul(Input.Pos, g_mInvWorldViewProjection) );
至于映射嘛,用texCUBE 就行了

语法

ret texCUBE(s, t)

Name

In/Out

Template Type

Component Type

Size

s

in

object

samplerCUBE

1

t

in

vector

float

3

ret

out

vector

float

4

代码:
float4 color = texCUBE( EnvironmentSampler, Input.Tex );
注意:texCUBE需要显卡支持PixelShader1.1,如果用到偏导数则需要PixelShader2.0
查了一下我的显卡(Intel集成的GMA900),刚好支持PS2.0,我心里那个激动呀……激动的我都不知道该怎么表达我的感情了
看看我做的效果吧:

References
The DirectX Software Development Kit
 
原文链接:http://blog.csdn.net/xoyojank/article/details/1628932
加载中
返回顶部
顶部