繁体中文
设为首页
加入收藏
当前位置:程序开发首页 >> 游戏开发 >> Shader Model 3 Using Vertex Texture 顶点纹理白皮书中文版

Shader Model 3 Using Vertex Texture 顶点纹理白皮书中文版

2006-01-01 11:35:13  作者:csdn_gamedev  来源:互联网  浏览次数:35  文字大小:【】【】【
简介:翻译者 周波 zhoubo22@hotmail.com版权所有  Philipp Gerasimov                  Randima (Randy) Fernando ...

翻译者 周波 zhoubo22@hotmail.com

版权所有 Philipp Gerasimov

Randima (Randy) Fernando

Simon Green

NVIDIA Corporation

仅以此文赠与Rita 19周岁生日快乐

Shader Model 3.0:Using Vertex Textures SM3:使用顶点纹理

随着GPU可编程特性的发展,Vertex Shader与Pixel Shader的差别越来越大。现在,Geforce6系列gpu将Vertex Shader与Pixel Shader之间的通用性特征向前发展了一大步。这篇文章特别介绍了Shader Model3的一项技术,Vertex Shader Fetch。它允许Vertex Shader像Pixel Shader一样从纹理中读取数据。

在现代图形处理中,顶点处理的性能表现不是受制于内存带宽、cpu速度,就是受制于Pixel Shader的处理能力。但这也意味着你可以实现一个复杂的Vertex Shader,提高画质,而且不会有多大损失。Vertex Shader的制作成本比Pixel Shader高,所以在最新的6800芯片里,Vertex Shader的数目要少于Pixel Shader。这样,我们就可以安心地实现一打漂亮的效果,比如流体的模拟等等。

这篇白皮书将同时向您展示如何在OPENGL以及DIRECTX中实现Vertex Texture。最后,我们将用一个游戏的范例向您演示使用Vertex Texture的情况。

Specification详解

DIRECTX与OPENGL中都可以使用Vertex Texture。

DIRECTX9

MS DX9SDK的开发文档中已经包括了VERTEX TEXTURE的详细说明。

Vertex Shader3(即使用Vertex Shader3编译器生成的Shader)支持vertex_fetch,4种纹理样本。Vertex Texture,单从名称上看就同传统的PIXEL TEXTURE类似,但是同PIXEL TEXTURE比起来有一些差别,

硬件无法直接支持Bilinear Trilinear过滤,但是您可以手动在Vertex Shader中实现

反锯齿,内容同上。

自动Mipmap LOD,无效

D3DCAPS成员MaxVertexShader30InstructionSlots标识Vertex Shader3中代码的上限行数。MaxVShaderInstructionsExecuted标识了Vertex Shader的上限代码行数,包括Texture Fetch的数目。

DIRECTX9支持软件Vertex Processing模式下使用Vertex Texture,这样甚至当硬件不支持Vertex Texture时也可以运行。

6800支持使用D3DFMT_R32F and D3DFMT_A32B32G32R32F的纹理格式实现Vertex Texture。

OPENGL

顶点纹理查找通过NV_V_PROGRAM3扩展实现。详情请参阅http://www.nvidia.com/dev_content/nvopenglspecs/GL_NV_vertex_program3.txt

这是标准ARB vertex program language的一项Option(操作)。这就意味着你可以调用现有的ARB API,载入程序,设置参数。在程序开头加入以下代码就可以了:

OPTION NV_VERTEX_PROGRAM3

在程序里加入Vertex Texture

使用Vertex Texture的步骤如下:

检查硬件的Vertex Texture支持情况

创建Vertex Texture资源

在Vertex Shader中加入需要的代码

下面具体来看看怎样在DIRECTX以及OPENGL中实现。

DIRECTX

第一,检查硬件是否支持,否则将不得不用软件方式实现。调用IDirect3D9::CheckDeviceFormat里的D3DUSAGE_QUERY_VERTEXTEXTURE旗标查询硬件支持的Vertex Texture格式。Software Vertex Texture支持所有Vertex Texture格式。

OPENGL

OPENGL里只需要检查硬件是否支持NV_VERTEX_PROGRAM3扩展。GLUT库的glutExtensionSupported函数可以完成这项任务。Vertex Texture数目的上限用下列代码获得

glGetIntegerv(MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &vtex_units)

6系列GPU最大支持4个活动纹理(Active Texture)。你可以尽情的在Vertex Shader中调用它们,不过要注意Vertex Shader的代码行数。

创建Vertex Texture资源

DIRECTX9

库中的任何纹理创建函数都可以创建顶点纹理,IDirect3D9::CreateTexture,

IDirect3D9::CreateCubeTexture, IDirect3D9::CreateVolumeTexture等等。

当使用SVP时,顶点纹理必须创建在D3DPOOL_SCRATCH池中。

OPENGL

基本纹理调用操作已经包括了Vertex Texture的绑定,使用GL_TEXTURE_2D。目前只有GL_LUMINANCE_FLOAT32_ATI 与 GL_RGBA_FLOAT32_ATI这2种格式支持Vertex Texture。这些格式都包含了1个或4个32bit浮点数据通道。注意,使用其他的纹理格式,或者使用不支持的过滤方式都可以导致驱动调用Software Vertex Processing处理,导致性能下降。

示例代码如下:

GLuint vertex_texture;

glGenTextures(1, &vertex_texture);

glBindTexture(GL_TEXTURE_2D, vertex_texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_NEAREST);

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_FLOAT32_ATI, width, height, 0,GL_LUMINANCE, GL_FLOAT, data);

在Vertex Shader里访问Vertex Texture

DIRECTX9

程序调用IDirect3DDevice9::SetTexture设置Vertex Texture,样本索引为D3DVERTEXTEXTURESAMPLER1到D3DVERTEXTEXTURESAMPLER3。在D3DPOOL_DEFAULT里创建的Vertex Texture同时也可以设置成PIXEL TEXTURE。

Vertex Shader里的纹理样本必须使用DEL_SAMPLEType标识。

// 汇编代码

dcl_texcoord0 v0

dcl_2D s0

texldl r0, o0, s0

// HLSL / Cg代码

sampler2D tex;

vDisplacement = tex2Dlod ( tex, t ); // t.w 包括MIPMAP LOD数据

OPENGL

VP的纹理查找功能通过TEX,TXB, TXL or TXP实现,就像在Fragment Shader里一样(或者在其他高等级语言中比如CG)。与Fragment Shader的差异是,纹理查找功能无法自动计算LOD。

LOD的意义是确定纹理在屏幕上缩放的尺寸大小。一般根据纹理坐标象素的改变频率计算,但这里的麻烦是,Vertex Texture由顶点访问,硬件很难计算LOD值。所以你不得不自己在Vertex Processing里计算LOD。

MIPMAP类似普通的Pixel Shader纹理,它可以为Vertex Texture在性能与画质之间折中。早期的图形处理管线中没有Pixel-Level这一概念,无法计算顶点纹理的LOD。如果需要使用LOD我们不得不人工在Vertex Shader里计算mipmap。

示例代码如下:

#define maxMipLevels 10.0f

Out.HPOS = mul( ModelViewProj, vPos );

float mipLevel = ( Out.HPOS.z / Out.HPOS.w ) * maxMipLevels;

float vDisplacement = tex2Dbias( tex, float4( t, mipLevel, mipLevel );

这是根据顶点的深度计算LOD的算法,开销很小,精度能够让人满意。

#define maxMipLevels 10.0f

Out.HPOS = mul( ModelViewProj, vPos );

float mipLevel = ( Out.HPOS.z / Out.HPOS.w ) * maxMipLevels;

float mipLevelFloor = floor(mipLevel);

float mipLevelCeiling = mipLevelFloor + 1;

float mipLevelFrac = frac(mipLevel);

float vDisplacementFloor = tex2D( tex, float4( t, mipLevelFloor,mipLevelFloor );

float vDisplacementCeiling = tex2Dbias(tex,

function ImgZoom(Id)//重新设置图片大小 防止撑破表格 { var w = $(Id).width; var m = 550; if(w < m) { return; } else { var h = $(Id).height; $(Id).height = parseInt(h*m/w); $(Id).width = m; } } window.onload = function() { var Imgs = $("content").getElementsByTagName("img"); var i=0; for(;i

责任编辑:admin
相关文章