DirectX下天空盒子的实现

来源:互联网 发布:sql 存储过程 表变量 编辑:程序博客网 时间:2024/04/29 13:30
概述
三维场影里的天空并不是“真正”的天空,而是用图片拼起来的,欺骗我们眼睛。通常把大家所在的场景用一个几何体包裹起来,再在里面贴上从各个角度的风景图,就好像一个真正的环境一样。想想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 = normalizemul(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

0 0