王朝网络
分享
 
 
 

小技巧:使用DirectX9进行遮盖剔除

王朝other·作者佚名  2008-05-19
宽屏版  字体: |||超大  

对象剔除是图形编程中一个重要的方面。渲染那些看不见的物体是十分耗时的。然而,就目前来说当务之急是优化剔除算法本身。因为通常剔除算法会消耗大量的处理时间。

传统的算法对于一般情况的处理已经提升得很快了也改进得足够多了,但还是留下了些许遗憾。一些算法剔除了太多的物体,而另一些剔除的数量却不够多。

遮盖剔除的原理告诉我们一个事实,那就是一个物体即便在视锥内,仍有可能被遮住而看不见。

这里,如图1.1所示,有五个多边形被显示在屏幕上。然而,在最后的渲染结果中(如图1.2所示),实际只有三个物体可以看得见。简单的视锥剔除算法会导致所有的物体都被渲染,原因是它们都在视锥内。就象在图1.1中一样,即使另外两个物体完全被遮住,它们仍会被渲染,这将耗费许多时间。

遮盖剔除通常会判断哪个物体会真正看得见,只有这些物体才会被渲染,从而节省了大量的时间。遮盖物(occluder)就是那些以遮住其它物体的东西(比如:图1.1中的那个巨大的红色盒子)。部分被遮盖的物体就是那些只能部分看见的物体(蓝色的五边形和紫色的楔形),这是需要被渲染的。完全被遮的物体就是完全看不见的物体(绿色的球体和桔红色的盒子),它们在渲染过程中将被排除掉。

关于遮盖剔除的更多信息,请参看由Tomas Möller 和 Eric Haines写的Occlusion

Culling Algorithms地(Occlusion Culling Algorithms)

介绍IDirect3DQuery9

IDirect3DQuery9 接口是Directx9的一个新特性。它允许开发人员能访问大量的统计数据,这其中包括优化信息、由资源管理器所处理的对象以及三角形处理信息。

IDirect3DQuery9 还能执行遮盖请求,它将计算在屏幕上可见的象素数目。只有在请求开始和请求结束之间渲染的象素才会被计算在内。如果计算的结果为0,那么说明物体的所有顶点都被遮住了,这个物体就当前摄像机所处的位置来说是看不见的。另外,如果计算的结果是大于0的,那么物体是可见的。

Query Type Datatype Use

D3DQUERYTYPE_VCACHE D3DDEVINFO_VCACHE Information about optimization,

pertaining to data layout for vertex caching

D3DQUERYTYPE_RESOURCEMANAGER D3DDEVINFO_RESOURCEMANAGER Number of objects

sent, created, evicted, and managed in video memory

D3DQUERYTYPE_VERTEXSTATS D3DDEVINFO_D3DVERTEXSTATS Number of triangles that

have been processed and clipped

D3DQUERYTYPE_EVENT bool For any and all asynchronous events issued from API

calls

D3DQUERYTYPE_OCCLUSION DWORD The number of pixels that pass Z-testing, or

are visible on-screen.

Table 2.1: Uses of IDirect3DQuery9

ATI的Occlusion Query(http://www.ati.com/developer/samples/dx9/OcclusionQuery.html)演示给出了使用IDirect3DQuery9的基础。

使用 DirectX9进行遮盖剔除

IDirect3DQuery9的出现提供了一个简单而有效的遮盖剔除的方法。基本过程如下:

1.

渲染各物体的包围网格(bounding mesh)。

2.

对每一个物体执行如下操作:

A。开始询问。

B。再一次渲染各物体的包围盒。

C。终止询问。

D。获取遮盖询问的数据。如果物体可见那么数据会大于0,此物体需要进行实际的渲染。否则物体将被排除。

第一步:

对于遮盖测试物体的实际网格包含了太多的顶点,而包围网格的顶点数要少得多,它将被用作替代物。那为什么用包围网格而不是包围盒或包围球呢?

图3.1各种类型的包围体

图3.1展示了多种类型的包围体,包括盒体、球体和网格。注意在这个特定的例子中包围网格和包围球的顶点数目是一样的。可是,即使顶点数目比较接近,在体积的接近程度上,包围网格的体积上和原始网格的的体积是最接近的。这在遮盖处理中很重要,要不大量的顶点会错误地渲染或剔除掉。

然而包围网格不能像包围盒或包围球那样通过某个算法来产生。它需要实时地建模和加载,就象普通的网格一样。每一个对象的包围网格先渲染一次以确保Z-buffer中有整个场景的深度信息。如果遮盖询问在整个场景的深度信息加入Z-buffer之前就开始了,那么即使被要求询问的物体在最终的场景里完全被遮挡住,可能也会被错误地认为是可见的。

第二步:

现在所有物体的包围网格深度数据已经在Z-buffer中了,我们还要再做一次同样的事,这一次遮盖询问将被用来判断每个物体的可视状态。如果询问后发现没有可见的象素,这个物体最后将不会被渲染。如果发现有一个或多个可见的象素点,那这个物体就会被加入到渲染处理过程里。

需要重点注意的是遮盖剔除的渲染不应在全尺寸的主缓冲里进行。用一个小些的缓冲(320 X 240可以很好地工作)可以提升效率。

代码

类型声明

Sobject(代码表4.1)是主对象实体。CMesh是一个封装了加载、渲染和释放ID3DXMesh接口的类。

struct SObject

{

CMesh* meshReference;

// Reference to a mesh object

CMesh* boundingMesh;

// Reference to low-poly bounding mesh

D3DXVECTOR3 pos;

// Position of this object

D3DXMATRIX matTranslate; // Translation matrix for this object

bool render;

// If true, render the object

float distanceToCamera;

// The distance to the camera (player position)

// Constructor

SObject( CMesh* meshRef, CMesh* boundMesh, D3DXVECTOR3 position )

{

meshReference = meshRef;

boundingMesh = boundMesh;

pos = position;

render = false;

distanceToCamera = 0.0f;

}

};

Code Listing 4.1: SObject definition

对象声明

遮盖剔除的处理过程中,我们还需要声明LPDIRECT3DQUERY9, LPD3DXRENDERTOSURFACE, LPDIRECT3DSURFACE9, 和 LPDIRECT3DTEXTURE9

LPDIRECT3D9 d3dObject;

// Direct3D Object

LPDIRECT3DDEVICE9 d3dDevice;

// Direct3D Device

LPDIRECT3DQUERY9 d3dQuery;

// The occlusion query

LPD3DXRENDERTOSURFACE occlusionRender; // Occlusion's render to surface

LPDIRECT3DSURFACE9 occlusionSurface;

// Occlusion's surface that it uses

LPDIRECT3DTEXTURE9 occlusionTexture;

// Texture to get surface from

std::vector<SObject objects;

// Vector of objects

Code Listing 4.2: Declarations of objects pertaining to the occlusion

culling procedure

设置遮盖对象

首先询问要被创建,此外还有纹理和要渲染的缓冲。在创建纹理过程里我们要用到D3DUSAGE_RENDERTARGET ,因为我们要在其上进行渲染。而缓冲通过LPDIRECT3DTEXTURE9 中的GetSurfaceLevel()来获得。我们还要用LPD3DXRENDERTOSURFACE 接口把Z-buffer的格式值设置成D3DFMT_D16。

//-----------------------------------------------------------------------------

// Name: SetupOcclusion()

// Desc: Create the objects needed for the occlusion culling

//-----------------------------------------------------------------------------

HRESULT SetupOcclusion()

{

// Create the query

d3dDevice-CreateQuery( D3DQUERYTYPE_OCCLUSION, &d3dQuery );

// Get the display mode to obtain the format

D3DDISPLAYMODE mode;

d3dDevice-GetDisplayMode( 0, &mode );

// Create the texture first, so we can get access to it's surface

if( FAILED( D3DXCreateTexture( d3dDevice, 320, 240, 1,

D3DUSAGE_RENDERTARGET,

mode.Format, D3DPOOL_DEFAULT,

&occlusionTexture ) ) )

{

return E_FAIL;

}

// Obtain the surface (what we really need)

D3DSURFACE_DESC desc;

occlusionTexture-GetSurfaceLevel(0, &occlusionSurface);

occlusionSurface-GetDesc(&desc);

// Create the render to surface

if( FAILED( D3DXCreateRenderToSurface( d3dDevice, desc.Width,

desc.Height, desc.Format,

TRUE, D3DFMT_D16,

&occlusionRender ) ) )

{

return E_FAIL;

}

return S_OK;

}

Code Listing 4.3: The SetupOcclusion() function

剔除物体

Occlusion

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有