纹理混合和模板

纹理混合和模板

最近的笔记和翻译,感觉模板真是一开始让我理解起来费劲。后来又看了一遍好点,再用起来又好点。

构造3D世界

现在我们已经有了基本的天空盒,但是我们还没有大地,不按照次序,以下是构成世界的基本元素: 镜头,天空盒,地形,边界阻挡,天气,视锥,碰撞,纹理贴图,Mesh

其中大地生成,碰撞检测,纹理贴图,镜头,Mesh应该是各自独立的,不像前面说的有所交叉。

为了构成世界,碰撞检测是相当重要的,但是往往人们更容易被画面所迷惑,就是说人们更关注画面,毕竟碰撞是背后的事情,所以首要的贴图,地形, Mesh,镜头,构造世界的技术应该成熟,我们把碰撞规划的交互领域。

为了构造世界,除了Mesh等,还有阴影,光,物体,各种物体,也就涉及到Mesh优化的问题,更具体可以将创建世界的部分划分到场景编辑中,如果制作场景编辑器,那么世界的创建应该更容易,不建议使用Max Maya类毕竟它们是相当复杂的,不容易安插物品。

我们还是按照《Introduction等》相关的来介绍。

创造世界的第一目的就是要真实,好看,漂亮,又在速度可接受的范围内,所以速度和画质是评判的标准。

另外我们可以利用公告牌技术来通过文字来标识各种物品。

好,还是先看纹理

1.Texture Coordinates 纹理坐标

Direct3D使用纹理坐标系统,在水平上使用U轴,和垂直上使用 V轴。一对UV定义一个叫做texel的纹理元素。注意V轴肯定是向下的方向看(图6.2)

纹理坐标系统有时叫做纹理空间。

还有,注意规格化间隔的坐标,[0,1],因为Direct3D固定范围用纹理的变量工作。

因为每个3D三角形,我们想定义符合三角形在文理被贴图的3D三角型。(看图6.3)

这样,我们修改我们的顶点结构并且,添加一对纹理坐标定义在顶点上。

struct Vertex{ float _x,_y,_z; float nx,ny,nz; float _u,_v; static const DWORD FVF; };

const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL |D3DFVF_TEX1

<观察我们添加的D3DFVF_TEX1到我们的顶点格式描述里,这就是说我们的顶点结构包含一对纹理坐标。/p>

现在从每三个顶点对象也定义一个符合纹理三角形。

创建和使用纹理

纹理数据通常使用图片文件存储在磁盘和加载使用IDirect3DTexture9对象。这样,我们使用下面的D3DX函数:

D3DXCreateTextureFromFile(LPDIRECT3DDEVICE9 pDevice, LPCSTR pSrcFile,LPDIRECT3DTEXTURE9* ppTexture);

这个函数可以加载下面一些图片格式BMP,DDS,DIB,JPG,PNG,和TGA

例如,创建纹理从图片调用石头wall.bmp,我们将写作下面的样子:

IDirect3DTexture9* stonewall;

D3DXCreateTextureFromFile(device,"stonewall.bmp",&stonewall);

设置当前的纹理,我们使用下面的方法:

IDirect3DDevice9::SetTexture(DWORD State,IDirect3DBaseTexture9* pTexture);

例如:

Device->SetTexture(0,stonewall)

注意:在Direct3D,你可以设置8个文理合并到更多细节的图片。这叫多重文理,我们不使用知道第五部分;因此我们总是使用 stage为0,现在。

在特殊的纹理stage丧失能力,设置pTexture为0。例如,如果我们不想渲染对象使用纹理,我们这样写:

device->SetTexture(0,0);

renderObjectWithoutTexture();

如果我们的场景有使用不同纹理的三角形,我们将不得不用下面相似的代码:

device->SetTexture(0,tex0);

drawTrisUsingTex0();

Device->SetTexture(0,tex1);

drawTrisUsingTex1();

过滤器

材质过滤

最近取样

线性过滤 Linear Filtering

各向异性过滤

提到以前的纹理贴图到三角形到屏幕空间。通常,纹理三角形在屏幕上是不同大小的。当纹理三角形比屏幕三角形小时,纹理三角形是放大的图象。当纹理三角形比屏幕三角形大的时候,纹理三角形缩小的。这两种情况,将发生扭曲。在Direct3D中使用过滤器技术帮助这些方向平滑。

Direct3D提供了三种不同类型的过滤器;每种提供不同级别的质量。最好的质量也是组慢的,所以你必须在质量和速度之间做出交换。纹理过滤设置通过SetSamplerState设置。

Nearest point sampling - 这中默认过滤方法和看起来最坏的结果,但是也是最快的。下面的是最进点取样缩小和扩大过滤。

Linear filtering - 这类过滤产生了还算好的结果和可以非常快的完成。它使你可以去到线性的最小值。下面的设置线性过滤:

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

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

Anisotropic filtering - 这类过滤产生最好的结果,也最长的计算。下面代码设置

Device->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_ANISOTROPIC);

Device->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_ANISOTROPIC);

当使用各向异性过滤时,我们必须设置D3DSAMP_MAXANISOTROPY等级,来确定anisotropic的质量。最大值是最好的结果。检测D3DCAPS9结构获取设备支持的最大范围。下面代码设置为4

Device->SetSampleState(0,D3DSAMP_MAXANISOTROPY,4);

Mipmaps - 近清晰远模糊

As said in section 6.3,在三角形在屏幕上通常是不同的纹理三角形。In an effort to make the size difference less drastic,我们可以创建一系列的小图到纹理。这种想法是制作一系列小的低分辨率纹理但是自定义过滤每个等级的细节对我们是重要的。

mipmap过滤使用下面的顾虑

Device->SetSamplerState(0,D3DSAMP_MIPFILTER,Filter);

Filter有下面的选项

D3DTEXF_NONE - 关闭mipmap

D3DTEXF_POINT - 使用Filter,Direct3D将选择最近的屏幕三角形。,基于指定的min和最大的过滤器。

D3DTEXF_LINEAR - 使用Filter,Direct3D将设置另个最近的等级,每个登记有最小和最大的过滤器,线性整合两个等级到最后的颜色值。

在Direct3D上使用Mipmaps

使用Mipmaps很容易。如果设备支持mipmaps,通过D3DXCreateTextureFromFile将产生一系列的mipmap.另外,Direct3D将自动选择匹配的屏幕最好的三角形。所以使用mipmap非常漂亮,自动的完成。

地址模式

前面,我们讲述了纹理坐标将在[0,1]范围内指定。技术让那是不恰当的;它们可能超出范围这种超过[0,1]范围的被Direct3D定义为地址模式。有四种地址模式:wrap border color clamp 和mirror

图6.5 6.6 6.7 6.8进行了说明。

这些图中,纹理坐标四种独特的顶点范围定义在(0,0) (0,3) (3,0) (3,3)。三个在UV方向上,这个范围再分为3x3矩阵区域。如果,例如,你想纹理贴在5x5超过范围,你可以指定wrap地址模式和纹理坐标(0,0) (0,5) (5,0)和(5,5).

下面代码指定Wrap地址模式和纹理坐标(0,0)(0,5) (5,0) (5,5).

下面代码从死个地址模式设置来说是微不足道的:

摘要:纹理坐标是使用3D三角形在纹理上定义贴图

我们可以通过加载磁盘上的图片文件来加载纹理用D3DXCreateTextureFromFile

我们可以缩小和放大,和使用mipmap来取样,对纹理进行过滤。

地址模式被定义为超过0,1范围的,举例来说,将纹理贴成瓷砖,反转,clamp,等

2 混合 Blending

在本章我们使用一种技术叫做混合,允许你混合我们当前的光栅化像素和前一个光栅化像素,在相同的像素位置上。换句话说,我们混合了原始绘图。这种技术允许你完成多样的效果(特殊,透明)

目标 - 理解怎样使用混合工作

学习关于不同Direct3D支持模式的混合

找到怎样使用控制原始的透明度使用Alpha组件

混合因素 The Blending Equation

假设我们想画一透明的我们能看见背景的透明茶壶。

我们怎样完成呢?我们需要整合被计算的茶壶的像素颜色,像这种方式,展示一个茶壶。这个想法,郑和当前计算的源像素值到目标像素的颜色值叫做混合。

注意,混合出像玻璃一样的效果是没有限制的。我们可以混合出各种颜色值。

重要的是认识到当前三角形的光栅化使用像素和提前写入后缓冲区。举例说明,我们创建图片写到当前的后缓冲区。我们然后画茶壶所以茶壶被创建。因此,下面的规则将允许使用混合。

画一个对象不使用混合。然后拣选出对象和他们的距离产生混合;这样大部分有效的混合你可以简单使用Z-component.最后,画出使用混合的对象。下面的公式是混合两个像素值。

每个变量都是一个4D的颜色向量(r,g,b,a)和denotes component-wise的指示。

OutputPixel - 输出混合像素

SourcePixel - 当前像素和使用后缓冲计算像素。

SourceBlendFactor - [0,1]间的像素值,混合的百分含量。

DestPixel - 目标像素值在后缓冲上。

DestBlendFactor - 混合后的像素值

源和目标混合因素让我们修改最初的源和目标像素有多种方式,允许不同的效果,7.2覆盖了预先设定的各种值。

混合默认是关闭的;你可以通过如下设置开启它,渲染状态

Device->SetRenderState(D3DRS_ALPHABLENDENABLE,true);

混合不是便宜的操作将仅仅需要几何的支持。但你完成渲染几何,你将关闭Alpha混合。也试图在一批三角形上使用混合和渲染它们在,所以你应该避免关闭混合在每帧。

混合因素

设置不同的混合源和目标混合要素,你可以创建不同的混合效果。使用不同的混合值进行实验。你可以设置源为都使用 D3DRS_SRCBLEND和D3DRS_DESTBLEND渲染状态,例如写做:

Device->SetRenderState(D3DRS_SRCBLEND,Source);

Device->SetRenderState(D3DRS_DESTBLEND,Destination);

源和目标可以有下面的混合要素值。

默认的源和目标值为D3DBLEND_SRCALPHA和D3DBLEND_INVSRCALPHA。

透明

在前面的章节我们忽略了Alpha组件的顶点颜色和材质,因为不需要,然而他们主要使用混合。然而,Alpha值从每个顶点颜色着色到跨过多个三角形的颜色,但是定义了像素颜色,它确定了像素的Alpha内容。Alpha主要用来指定像素的透明度的。假设每个像素有8bit的Alpha,有效的间隔Alpha内容将在[0,255],符合[0%,100%]的不透明。因此,像素值(0)黑色值日完成透明,每个像素的128将是灰色值,50%透明,白色将是255

为了让Alpha描述不同的透明,我们必须设置源混合要素为D3DBLEND_SRCALPHA和目标为D3DBLEND_INVSRCALPHA,这样值将发生混合。

Alpha通道

取代使用Alpha内容计算着色。我们可以从纹理Alpha-channel中获取Alpha通道。这个Alpha通道是一个额外的位类为每个texel存储Alpha内容。当Texture贴图到原始顶点上,Alpha内容的Alpha通道也被贴上,它们改变了Alpha内容的纹理原始信息的像素值。图7.3是个开了8bitAlpha通道的图片。

指定源Alpha

默认的,如果当前设置纹理的Alpha通道,Alpha是从Alpha通道开始。如果没有Alpha通道,Alpha从顶点颜色里。然后你可以指定源(diffuse color或Alpha Channel)使用下面的渲染状态。

Device->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_DIFFUSE);

Device->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);

Device->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);

Device->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);

Stenciling 模板

这章带给我们的是模板缓冲和结束文本的第二部分。stencil缓冲是一个离屏缓冲,我们可以使用它完成特殊效果。stencil缓冲有一些resolution作为后缓冲和深度缓冲,像ij-th像素在stencil缓冲符合使用ij-th像素到后缓冲和深度缓冲。The stencil buffer has the same resolution as the back buffer and depth buffer so that the ij-th pixel in the stencil buffer corresponds with the ij-th pixel in the back buffer and depth buffer.作为命名建议,stencil缓冲工作允许我们成块的渲染后缓冲的一个主要部分。

例如,当完成反射,我们简单需要反射出特殊对象跨过一个平面;然而,我们仅仅想画出反射到镜子。我们可以使用stencil缓冲渲染在镜子反射出的。

stencil缓冲是Direct3D中较小的一部分是控制简单的接口。像 blending,简单的灵活强大的接口。学习使用stencil缓冲,能够更有效的完成存在的应用。一旦你理解了程序中的stencil缓冲,你将有个更好的想法,它可以应用到指定的需要上。基于这个原因,本章设置特殊强调学习两种指定使用stencil(在特殊,完成镜子和平面阴影).

Objectives - 目标

理解stencil缓冲是怎样工作的,怎样创建stencil缓冲,和怎样控制stencil缓冲。

学习怎样完成镜面和使用stencil缓冲到防止反射从drawn到非镜面的接口。

发现怎样渲染阴影和反之双混合使用stencil缓冲。

Using the Stencil Buffer使用模板缓冲

使用模板缓冲,我们必须首先当初始化Direct3D的时候我们开启它。我们描述请求在8.1.1里。开启stencil缓冲,我们必须设置 D3DRS_STENCILENABLE渲染状态,指定真。关闭为false.下面小片代码使用开启和关闭

Device->SetRenderState(D3DRS_STENCILENABLE,true);

Device->SetRenderState(D3DRS_STENCILENABLE,false);

尽管本书不使用,DirectX9.0已经添加一个双向的体积阴影渲染来产生阴影。看SDK文档更多细节。

我们可以清理stencil缓冲到默认值,使用IDirect3DDevice9::Clear方法。重复调用在同样的后缓冲和深度缓冲。

足以我们已经添加了D3DCLEAR_STENCIL到三个参数,指出我们清理目标的模板缓冲和后缓冲。参数6指定了清理模板缓冲的值;例子为0.

注意:使用模板缓冲可以考虑自由操作硬件如果你已经准备了深度缓冲,依照NVIDIA陈述的创建反射和阴影使用模板缓冲 Mark J. Kigard

请求模板可以我们创建深度缓冲的时候同时创建。当指定深度缓冲格式时,我们同时指定模板缓冲的格式。实际上,模板缓冲和深度缓冲共享同一个离屏表面,但是每儿歌像素是设计为分割到每个特殊的缓冲。例如,考虑下面三个深度/模板缓冲格式:

注意这些格式不分配任何位到模板缓冲,例如,D3DFMT_D32格式创建32bit的深度缓冲。

还有,支持变化的各种图形卡,也许不支持8bie模板缓冲。

The Stencil Test

前面声明,我们可以使用模板缓冲渲染主要后缓冲的一块。从决定了模板缓冲的测试,使用下面的表达式:

(ref & mask) ComparisonOperation (value & mask)

模板测试完成每个像素的任务,假设模本是开启的,两个操作:左操作(LHS)确定ANDing一个应用-定义模本引用值(ref)定义模糊值

RHS-右手规则确定ANDing空的模板缓冲到特殊像素测试定义模糊值。

模板测试比较LHS和RHS,测试比较操作。全部表达式为假值。我们写像素到后缓冲区如果测试值为真。如果测试值为假,我们从后缓冲区渲染每个像素。当然,如果像素不写在后缓冲区,特写在深入缓冲区。

Controlling the Stencil Test 控制模板缓冲测试

ZBuffer WBuffer StencilBuffer

为了给我们灵活,Direct3D允许我们控制在Stencil测试中使用变量。换句话说,我们获取了指定的模板参考值,模糊值,甚至比较值。虽然我们不能获取明确的设置模板缓冲值,我们有一些控制覆盖写入在模板缓冲另外清理模板缓冲。

Stencil Reference value模板缓冲值

模板缓冲参考值默认是0,但是我们可以改变它用D3DRS_STENCILREF渲染状态。例如,下面代码设置模板引用值

Device->SetRenderState(D3DRS_STENCILREF,0x1);

注意,我们往往是使用十六进制因为更容易看清位的分配的整数,这样好的位操作,想ANDing.

Stencil Mask 模板模糊

模板模糊值模糊是使用mask(hide)位在双ref和value变量。默认模糊是0xffffffff,任意位不mask.我们可以改变mask用D3DRS_STENCILMASK渲染状态。下面例子mask为16高位:

Device->SetRenderState(D3DRS_STENCILMASK,0x0000ffff);

注意:如果你不理解谈论位和masking,它意味者你需要复习你的二进制,十六进制和bit-wise操作。

Stencil value - 模板值

前面讲过,这个值是当前模板测试的像素值。例如,如果我们完成模板测试在ij-th像素,然后值将被值在ij-th的模板缓冲的入口。我们不明确的设置单独的模板缓冲值,但是回想我们清理了模板缓冲。另外我们可以使用模板渲染状态控制写入在模板缓冲。模板和渲染状态短的发生联系。

Comparison Operation - 比较操作

我们可以通过D3DRS_STENCILFUNC设置比较操作。比较操作任何D3DCMPFUNC枚举类型:

更新模板缓冲 Updating the Stencil Buffer 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值