着色器和效果——3.1 多纹理化概览

原创 2004年06月11日 10:23:00

3.1 多纹理化概览

阅读此文表明您已同意文末的声明

多纹理化Multitexturing)可能是能用像素着色器实现的最简单的技巧了。此外,因为像素着色器替换多纹理化阶段,那么接下来我们应该对多纹理化“是什么”和“做什么”有一个最基本的理解。本节介绍多纹理化的简明概览。

当我们一开始讨论纹理化texturing)的时候(译者注:对纹理化的讨论不在译文范围内,具体可参照原书第六章,本文是原书“第四部分:着色器和效果”的第三章),我们忽略了固定功能管线中对多纹理化的讨论,这有两个原因:第一,多纹理化是有一点棘手的过程,我们考虑到这在当时是一个高级话题;此外,固定功能多纹理化阶段被新的和更强有力的像素着色器替换掉了。因此花时间在已经过时的固定功能纹理化阶段上是无意义的。

多纹理化后面的思想有一点和混合blending)相关。在第七章中(译者注:原书第七章不在译文范围内)我们了解到:可以将正要被光栅化的像素与之前写入后台缓冲的像素进行混合来达成一种特效。我们推广这种相同的思想到多个纹理multiple texture)。也就是说,我们一次允许几个纹理,然后定义这些纹理如何被混合在一起以到达一种特殊效果。多纹理化的一个通常的用法是执行光照。作为在顶点处理阶段使用Direct3D的光照模型的替代,我们使用一种叫做“光照贴图”(light map)的特殊纹理贴图texture map),它编码encode)表面是如何被光照的(译者注:这句话的意思是“它定义表面是如何被光照的”)。例如,假设我们希望一盏聚光灯spotlight)照在一个大木箱上,我们要么可以定义一个D3DLIGHT9结构的聚光灯,要么可以将代表木箱的纹理贴图与代表聚光灯的光照映射混合在一起,如图3.1所示。

18.1:使用多纹理化渲染一个通过聚光灯照亮的木箱。这里我们通过将相应的纹理像素(texels)相乘来将这两个纹理组合起来。

注意:用第七章里的混合,结果图像依赖于纹理被混合的方式。在固定功能管线的多纹理化阶段,混合方程式被纹理渲染状态texture render state)控制。用像素着色器,我们可以以可编程的方式在代码中写出混合函数的简单表达式。这使我们可以以任何我们想要的方式混合纹理。我们将在讨论为本章准备的样例应用程序时详细讨论纹理混合。

混合多个纹理(本例中是两个)来照亮木箱比起Direct3D的光照来有两个好处:

n        光照是是预先在聚光灯的光照贴图里计算好的。因此,光照不需要在运行时被计算,这节省了处理时间。当然,只有静态对象和静态灯光的光照可以被预先计算。

n        因为光照贴图是预先计算好的,我们能够使用比Direct3D的(光照)模型多的多的更加精确的和复杂的光照模型。(在更加真实的场景中的更好的光照结果。)

备注:多纹理化阶段典型的用于实现静态对象的完全光照引擎(full lighting engine)。例如,我们可以用一个纹理贴图保存对象的颜色,比如木箱的纹理贴图。然后我们可以用一个散射光照贴图diffuse light map)保存散射表面着色diffuse surface shade),一个单独的镜面光照贴图保存镜面表面着色,一个雾状物贴图(fog map)保存覆盖在表面的雾状物的总量,还有可以用一个详细贴图(detail map)保存小的、高访问率的表面的细节。当所有这些纹理被组合起来,只需到这些预先计算的纹理中检索,就可以有效的照亮、着色并且增加细节到场景中去。

注意:聚光灯光照贴图是最基本的光照贴图的一个微不足道的例子。典型的,特定的程序用于在给定的场景和光源下生成光照贴图。生成光照贴图超越了本书的范围。有兴趣的读者可以参考Alan WattFabio Policarpo3D Games: Real-time Rendering and Software Technology中描述的光照贴图。

3.1.1 允许多个纹理

回忆一下,纹理是用IDirect3DDevice9::SetTexture方法设置,而采样器状态(sampler state)是用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

);

注意:一个特定的采样器阶段索引i与第i个纹理阶段(texture stage)相关联。也就是说,第i个采样器阶段指定了第iset)纹理的采样器状态。

纹理/采样器阶段索引标识了我们希望设置的纹理/采样器的纹理/采样器阶段。因此,我们可以允许多个纹理并通过使用不同的阶段索引设置其相应的采样器状态。在本书前面的部分中,我们总是指定0,来指示第一个阶段,因为我们一次仅使用一个纹理。所以例如,假设我们要允许三个纹理,我们像这样使用阶段0,12

// 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->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

 

// Set second texture and corresponding sampler states.

Device->SetTexture(     1, Tex2);

Device->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

Device->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

Device->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

 

// Set third texture and corresponding sampler states.

Device->SetTexture(     2, Tex3);

Device->SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

Device->SetSamplerState(2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

Device->SetSamplerState(2, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

这段代码允许Tex1, Tex2Tex3,并设置每个纹理的过滤模式。

3.1.2 多纹理坐标

回忆一下第六章,对于每个3D三角形,我们要在纹理上定义一个相应的三角形以映射到该3D三角形。我们通过对每个顶点增加纹理坐标完成这一点。因此,构成一个三角形的每三个顶点定义了一个在纹理上的对应的三角形。

因为我们现在需要使用多个纹理,对于每三个顶点定义的一个三角形,我们需要在每个被允许的纹理上定义一个相应的三角形。我们做这件事通过增加额外的纹理坐标的集合到每个顶点——每个顶点一集,而且相应地,每个允许的纹理。举个例子,如果我们混合三个纹理到一起,那么每个顶点必须有三集纹理坐标以索引到三个允许纹理。因此,一个三纹理的多纹理化顶点结构看起来可能像这样:

struct MultiTexVertex

{

     MultiTexVertex(float x, float y, float z,

                    float u0, float v0,

                    float u1, float v1,

                    float u2, float v2)

     {

          _x =  x;   _y = y; _z = z;

          _u0 = u0;  _v0 = v0;

          _u1 = u1;  _v1 = v1;

          _u2 = u2;  _v2 = v2;

     }

 

     float _x, _y, _z;

     float _u0, _v0; // Texture coordinates for texture at stage 0.

     float _u1, _v1; // Texture coordinates for texture at stage 1.

     float _u2, _v2; // Texture coordinates for texture at stage 2.

 

     static const DWORD FVF;

};

const DWORD MultiTexVertex::FVF = D3DFVF_XYZ | D3DFVF_TEX3;

注意,指定自由顶点格式标记D3DFVF_TEX3表明顶点结构包含三集纹理坐标。固定功能管线支持最多八集纹理坐标。要使用多于八集,你必须使用顶点声明和可编程顶点管线。

注意:在较新的像素着色器版本中,我们可以使用一集纹理坐标以索引到多个纹理,并因此消除了对多个纹理坐标的需要。当然这得假设每个纹理阶段使用相同的纹理坐标。如果每个阶段的纹理坐标不同,则我们仍然需要多纹理坐标。

[声明]:本文译自Frank Luna的《Introduction to 3D Game Programming with DirectX 9.0》,限于译者水平,文中难免错漏之处,欢迎各位网友批评指正;本文仅用于学习交流与参考用途,不得用于任何形式的商业用途;如需转载需事先征得译者同意,保持文章的完整性,并注明译者和出处,译者保留对译文的所有权利。对于违反以上条款造成的后果,译者对此不负任何责任。我的MSNRaymond_King123@hotmail.com,欢迎热爱3D图形和游戏,并有一定图形编程经验的朋友与我进行交流。

 

cocos2dx学习笔记(着色器水纹效果)

转载:http://blog.csdn.net/qq_17749439/article/details/37933937 着色器 转载  http://www.25kx.com/art...
  • wei_hehe
  • wei_hehe
  • 2014年07月23日 09:13
  • 1294

glsl着色器 光照和纹理计算 (有用!)

http://my.oschina.net/sweetdark/blog/214220 以下内容只针对GLSL1.20的版本进行说明的,有些内置的变量在1.20之后,已经被废弃了。 ...
  • z444_579
  • z444_579
  • 2016年07月20日 12:01
  • 1800

GPUImage 顶点着色器和片元着色器 详解

//顶点着色器 //v.shader //顶点着色器是一个可编程的处理单元,执行顶点变换、纹理坐标变换、光照、材质等顶点的相关操作,每顶点执行一次。替代了传统渲染管线中顶点变换、光照以及纹理坐标的处...
  • jeffasd
  • jeffasd
  • 2016年08月31日 14:37
  • 2565

OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用_棋盘纹理贴图

  • 2016年05月23日 14:44
  • 8.98MB
  • 下载

OpenGL 着色器语言3.1-3.3

基本概念 3.1字符集和编译段 OpenGL着色器语言的源字符集是 UTF-8编码的Unicode.经过预处理后,只有以下字符允许存在于GLSL的结果流中: 字母 a-z,A-Z,和下划线(_...
  • bnrmaster
  • bnrmaster
  • 2015年08月02日 17:29
  • 375

渲染世界的OPENGL<12> 一些有趣的纹理着色器

从着色器访问纹理贴图是非常简单的。纹理坐标将会作为属性传递到我们的顶点着色器,在片段着色器当中,这些属性通常是在顶点之间进行平滑插值的。片段着色器使用这些差值纹理坐标来对纹理进行采样。(1)只处理纹理...
  • memories_sunset
  • memories_sunset
  • 2016年09月20日 16:29
  • 1275

OSG环境下,使用glsl的几何着色器,绘制带纹理的三角形

本例子程序实现了在几何着色器中使用颜色和纹理的混合效果,代码包含了一些与效果无关的多余代码,几何着色器里也使用了顶点法线,但实际上没有参与计算。...
  • swety_gxy
  • swety_gxy
  • 2016年08月23日 19:09
  • 1191

OSG环境下GLSL实现几何着色器的纹理采样

最近在写着色器的学习例子,此个例子为原创 ,翻阅了挺多资料的,最后竟发现原来原理如此简单,里面涉及到glsl的基础知识,还有osg的一些应用,主要是作为外部应用程序的设置。...
  • swety_gxy
  • swety_gxy
  • 2016年08月24日 23:23
  • 961

像素着色器实现多重纹理

像素着色器实现多重纹理,首先需要用HLSL语法写出相关代码,保存为一个文件,然后调用D3DXCompileShaderFromFile接口进行编译。还有一种方式是:通过fxc.exe工具编译那个文件。...
  • jujueduoluo
  • jujueduoluo
  • 2016年10月31日 11:48
  • 616

对着色器代码与纹理图优化的一些体会

在以前的项目中写了这么多着色器,以及最近看一些书籍,对着色器的优化有了一些自己的体会,在这里总结一下。...
  • srk19960903
  • srk19960903
  • 2017年06月30日 20:07
  • 246
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:着色器和效果——3.1 多纹理化概览
举报原因:
原因补充:

(最多只允许输入30个字)