以此纪念我的伯父,数学教育家钟载硕

  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  4 随笔 :: 0 文章 :: 1 评论 :: 0 Trackbacks

2008年2月13日 #

下面的建议都是为大型3D系统准备的,不是为了一个小demo准备的,所以这些建议不一定适合小demo。
首先是来自于gamedev论坛的建议:
There are a fair few things that can be done to optimise a particle engine. Off the top of my head I would recommend some of these...

Calculate a bounding volume (bounding box or sphere) for your particle system so that you can then cull this against your view frustum. If outside your view then simply don't render the particle system - although you still may (or maybe not) wish to update those particles in that system.

Use a fixed array size for the particles in a given system. (As IndirectX hints at in the post above). Alternatively a method whereby you use two linked lists to keep track of the particles can be used - one tracking live particles, the other tracking 'dead' particles. Whichever method you use you do not want to be creating and deleting particles on the fly too often (i.e. using, say, new and delete operators) as this can seriously dent performance. Easy solution? Use a fixed array and flag particles as dead or alive.

Do you use quads (two triangles) for rendering your particles? If you do then try using triangles and mapping your particle texture onto a single triangle. You will need to modify the uv's to display the texture correcly, but you immediately decrease the number of triangles you need to render by two.

Ensure you do not call SetTexture for *each* and every particle. Group particles by texture. It is usually common for a particle system to produce particles that utilise only one texture (for example, a snowflake within a snowflake particle system). This way you set the texture once for the system then proceed to render the individual particles contained within that system.

Maybe consider enabling alpha testing - this can then reject fragments of your particles before the final rasterisation stage.

If you are calculating the inverse view matrix for billboarding then ensure you only do this once per frame (or, if your implementation suggests so, less than once per frame). This matrix need not be calculated per particle per frame - although a lot of implementations I have seen in the past calculate this per particle!

Ok - there are several more things you can do to optimise, but at least the above gives an idea as to what to look for, or be aware of. Hopefully this will help you out a bit!

Sharky

这个Sharky看来是个老手,一口气写了那么多优良的建议。

还有一句建议:当粒子大小大于一半屏幕面积的时候,就不要渲染这个粒子。
这句话也出自gamedev,原文我找不到了。WOW就有很多这种情况,例如你把人物特意靠近某个粒子系统,例如一个冒烟的小锅。当你把镜头拉近那些烟的时候,游戏的FPS会突然大跌,非常卡。原因就是单个粒子遮盖了屏幕很多象素,渲染粒子时候要做的alpha_blend突然大大增多,而且不是1个粒子,是很多个粒子重重复复在大块区域进行alpha_blend,导致FPS暴跌。

WOW早期粒子效果比较好,合理的画面效果,高效的速度,但是到了现在(TBC 2.x)后,可能换了粒子效果美工,对粒子效果掌握的很不好,过于花巧,对游戏FPS影响过大。例如,粒子速度过快,数量过多。猎人的箭雨多了20倍的箭,法师的暴风雪多了3倍的雪箭,然后速度都加快了2倍,特别猎人那个箭雨,什么都看不到,一顿卡就结束了。
posted @ 2008-02-13 18:54 昆达 阅读(335) | 评论 (1)编辑 收藏

2008年1月8日 #

/Files/plea/wave.rarWOW水面渲染
posted @ 2008-01-08 13:23 昆达 阅读(448) | 评论 (0)编辑 收藏

2007年8月12日 #

     摘要: // Copyright (C) 2000 by Autodesk, Inc.//// Permission to use, copy, modify, and distribute this software in// object code form for any purpose and without fee is hereby granted,// provided that the a...  阅读全文
posted @ 2007-08-12 18:11 昆达 阅读(776) | 评论 (0)编辑 收藏

2007年8月7日 #

D3D API的处理顺序如下:
程序调用API
windows把API解释为通用型处理指令
windows把指令填充到指令缓冲
windows检查指令缓冲是否满了,或者该指令具有强制执行命令
 如果符合清理缓冲条件,windows进入"核心态",把指令交给显卡驱动,显卡驱动把windows通用指令翻译成为显卡指令,然后返回"用户态".

具有强制执行命令有(部分api,这里不全部举例):
创建vertexbuffer, indexbuffer,texture.
释放(release)vertexbuffer, indexbuffer,texture.


由"用户态"进入"核心态",把指令缓冲交给驱动,再由"核心态"返回到"用户态"就需要花费不少时间.所以,要尽量把缓冲填满再进行处理.
当渲染场景的时候调用某些函数,会导致潜在的性能障碍.例如,渲染过程中发现某个texture不需要了,此时调用texture->release(),导致windows强制清理指令缓冲,很有可能浪费大量时间.因为缓冲使用率可能还没有10%.
类似这些会引导系统强行清理缓冲的指令,应该在渲染前,或者渲染后再进行处理.提高渲染过程的缓冲使用率.

CPU,GPU不是同步工作的.类似如下代码:
device->SetStreamSource(pBuffer......);
device->DrawPrimitive(....);
pBuffer->Release();
能够保证无错运行,靠的就是上面的规则.Release()命令导致缓冲清空,所有命令都被顺序强制执行.
posted @ 2007-08-07 18:31 昆达 阅读(733) | 评论 (0)编辑 收藏

仅列出标题