分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
一个pixel shader是在每一像素光栅化处理期间物理卡的GPU上执行的一种程序。(不像vertex shader,Direct3D不会用软件方法仿效pixel shader的功能。)。它本质上代替了固定管道功能中的多重纹理阶段并给了我们直接操作单独像素和访问每一个像素纹理坐标的能力。这种直接访问像素和纹理坐标允许我们完成多种特殊效果,比如多重纹理、逐像素光照、视野深度、云层仿真、火焰仿真和复杂阴影技术。
你可以通过检查D3DCAPS9结构体的PixelShaderVersion成员和D3DVS_VERSION宏来检测你的物理卡支持的pixel shader版本。下面的代码片断举例说明了这个:
// If the device's supported version is less than version 2.0
if( caps.PixelShaderVersion < D3DPS_VERSION(2, 0) )
// Then pixel shader version 2.0 is not supported on this device.
Objectives
· 获得关于多重纹理概念的基本理解
· 学习如何写、创建并应用pixel shaders
· 学习如何应用pixel shader执行多重纹理
一、多重纹理概述(Multitexturing Overview)
多重纹理可能是用pixel shader可以执行的最简单的技术。此外,由于pixel shader替换了多重纹理阶段,接下来我们需要对多重纹理阶段是什么和如何做具有一些基本的理解。这一节简单概述一下多重纹理。
当我们最初在以前的章节揭示纹理时,我们有两个原因在固定功能管道中省略讨论多重纹理:第一,multitexturing是有点棘手的,并且我们当时考虑它为一种高级话题。另外,固定功能多重纹理阶段被新的更强大的pixel shader代替了。因此有意不花时间在过时的固定功能多重纹理阶段。
多重纹理背后的思想是有些方面代替混合(blending)。在前面讲混合的章节中我们学到用先前已写入后台缓冲的像素混合正被光栅化的纹理以完成一个特殊效果。我们扩展这个同样的思想到多重纹理。即,我们一次开启几个纹理并定义这些纹理如何混合到一起以完成一种特殊效果。多重纹理的一个普通应用是做光照(lighting)。代替应用Direct3D的在顶点处理阶段的光照模式,我们应用被称为光图(light map)的特殊的纹理图,它编码了一个表面如何被照明。例如,假设我们想用一个点光照亮一个很大的箱子。我们可以定义一个D3DLIGHT9结构的点光源,或者我们可以把一个表现箱子的纹理图与一个表现点光的光图混合在一起,如图Figure 18.1所示。
Figure 18.1: Rendering a crate lit by a spotlight using multitexturing. Here we combine the two textures by multiplying the corresponding texels together.
|
Note |
如“混合”那一章所介绍的,结果图形依赖于纹理如何混合。在固定功能多重纹理阶段,混合方程式控制了整个纹理混合阶段。通过pixel shader我们可以把混合函数编程在代码中成为一种简单表达式。这允许我们用任何我们想要的方法混合纹理。在我们讨论这一节的例程中我们详细说明混合纹理。 |
混合纹理(这一例子中是两个)以照明箱子有两个比Direct3D光照的益处:
· 光照是在点光光图中预先计算好的。因而,光照不需要在运行时被计算,这节省了处理时间。当然,光照只能预先计算静态物体和静态光。
· 因为光图是预先计算的,我们就能比Direct3D模式应用更精确更变化多样的光照模式。(在很多现实场景中更好的光照结果)
|
Remark: |
多重纹理阶段的一个代表性应用是实现一个对静态物体的完全光照引擎(full lighting engine for static objects)。例如,我们可能有一个存贮物体颜色的纹理图,如一个箱子纹纹理图。然后我们可能有一个漫反射光图以保存漫反射表面阴影,并有一个细节图保存表面上小的、高发生率的细节。当这些所有纹理组合在一起时,它仅仅应用查找预先计算好的纹理表现场景的光、颜色和细节。 |
|
Note |
The spotlight light map is a trivial example of a very basic light map. Typically, special programs are used to generate light maps given a scene and light sources. Generating light maps goes beyond the scope of this book. For the interested reader, Alan Watt and Fabio Policarpo describe light mapping in3D Games: Real-time Rendering and Software Technology. 点光光图是一个对非常基本的光图中价值不高的例子。代表性的,特殊的程序被用于当给定一个场景和一个光源时产生光图。产生光图超出了教程的范围。对于感兴趣的学生。Alan Watt和Fabio Policarpo 描述了3D游戏中的光图:Real-time Rendering and Software Technology. |
1.1开启多重纹理(Enabling Multiple Textures)
回忆一下纹理通过IDirect3DDevice9::SetTexture方法设置并且取样器阶段通过IDirect3DDevice9::SetSamplerState方法设置,原形如下:
HRESULT IDirect3DDevice9::SetTexture(
DWORD Stage, // specifies the texture stage index
IDirect3DBaseTexture9 *pTexture
);
HRESULT IDirect3DDevice9::SetSamplerState(
DWORD Sampler, // specifies the sampler stage index
D3DSAMPLERSTATETYPE Type,
DWORD Value
);
|
Note |
一个特殊的采样器阶段索引i是关联到第i纹理阶段。即,第i采样阶段指定采样阶段为第i次设置纹理。 |
texture/sampler 阶段索引识别我们想设置texture/sampler的texture/sampler阶段。因而,我们能开启多重纹理并且用不同的阶段索引设置它们的相应采样阶段。在以前的讲解中,我们通常指定0,表示第一阶段,因为我们在一个时间只使用一层纹理。所以举个例子,如果我们需要开启三层纹理,我们用阶段0、1、2象这样:
// Set first texture and corresponding sampler states.
Device->SetTexture( 0, Tex1);
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
Device->