Difference between revisions of "Performance Optimization"

m (Occluders)
(Added 'Using the Debug Client' section)
Line 23: Line 23:
  
 
==Measuring Performance==
 
==Measuring Performance==
The first step to enhancing performance is to measure it. First of all: know you computer. Is it old? Is it new? Is it above Uru's Minimum System Requirements? Depending on your computer Uru Ages will perform differently. Once you know that download and install [http://www.fraps.com/ FRAPS]. This tool will allow you to measure the framerate in Uru. It is free, small, and easy to configure. Your target is to keep the framerate above 30FPS on all computers. Uru was released in late 2003, so computers of this time are our baseline. Computer power tend to double every two years (roughly); if your Age runs at 120 FPS on your computer but you bought it in 2009 then divide that number by 5 or 6... (''This isn't an exact formula, but it will give you an estimation''). Once you start making some good progress on your Age it is a good idea to send it to people with different computers, so they can test the performance.
+
The first step to enhancing performance is to measure it. First of all: know you computer. Is it old? Is it new? Is it above Uru's Minimum System Requirements? Depending on your computer Uru Ages will perform differently. Once you know that download and install [http://www.fraps.com/ FRAPS]. This tool will allow you to measure the framerate in Uru. It is free, small, and easy to configure. Your target is to keep the framerate above 30FPS on all computers. Uru was released in late 2003, so computers of this time are our baseline. Computer power tend to double every two years (roughly); if your Age runs at 120 FPS on your computer but you bought it in 2009 then divide that number by 5... (''This is not an exact formula, but it will give you an estimation''). Once you start making some good progress on your Age it is a good idea to send it to people with different computers, so they can test the performance.
  
 
==Design your Age with 'view blockers'==
 
==Design your Age with 'view blockers'==
Line 29: Line 29:
 
>> See [[#Visibility_Management|visibility management section]]
 
>> See [[#Visibility_Management|visibility management section]]
  
 +
==Using the Debug Client to test your Age==
 +
Now that Uru has gone open source Cyan's internal debug client can be used. This particular version of Uru includes a console that is loaded with features to test Ages and measure performance.
 +
Note: this client can only load ''MOUL'' ages; ages exported for Uru:CC cannot be used with this client.
 +
''There is no article explaining how to compile and use the debug client yet.''<br>
 +
''<This section needs to be expanded>''
  
 
=First things to take care of=
 
=First things to take care of=

Revision as of 17:09, 24 May 2011

Introduction

If you find that your Age is 'lagging' or having various performance issues, it may be the time to learn some optimizations tricks. Performance optimisation is a vast topic, but an important one. Especially for large Ages who are more prone to performance drops than smaller Ages. But for new Writers even small Ages can lead to some unsuspected performance troubles. This article covers the most common and most useful tricks.

Note: This is a ‘work in progress’ article.


Things to always keep in mind

As much as possible it is better to have in mind performance issues before starting work on an Age. If you need to optimize an Age after it is mostly completed you will find yourself retouching, or even losing, weeks of work; and that is not an enjoyable thing to do. Therefore here are a couple things to always have in mind:

Top things to avoid:

Decent performance can usually be accomplished in most Ages by avoiding in a couple key issues. Here are the top performance killers; keep them in mind at all times. In no specific order:

  • Polygon counts : ”Yay! my Age has more polygons than Riven! oh.. wait.."
  • Texture sizes : Plasma can handle texture sizes up to 1024*1024. That doesn't mean that all textures should be that size.
  • Age size / design : An open Age will always be more difficult to optimise. You need to think of ways to block the view at times.
  • Excessive shaders : Fancy effects and multi texturing are nice, but only up to a certain point. Do not over-do them.
  • Too many trees : Many people like forests, but trees are the death of performance: Polygons, transparency... Use them sparingly.
  • Collisions everywhere : Never enable collisions on all your meshes. Hand-made collisions meshes are a necessity.

Do not be excessive: not too many polygons/textures/objects etc.. It is perfectly possible to have an Age that is both 'reasonnable' and nice looking.

Measuring Performance

The first step to enhancing performance is to measure it. First of all: know you computer. Is it old? Is it new? Is it above Uru's Minimum System Requirements? Depending on your computer Uru Ages will perform differently. Once you know that download and install FRAPS. This tool will allow you to measure the framerate in Uru. It is free, small, and easy to configure. Your target is to keep the framerate above 30FPS on all computers. Uru was released in late 2003, so computers of this time are our baseline. Computer power tend to double every two years (roughly); if your Age runs at 120 FPS on your computer but you bought it in 2009 then divide that number by 5... (This is not an exact formula, but it will give you an estimation). Once you start making some good progress on your Age it is a good idea to send it to people with different computers, so they can test the performance.

Design your Age with 'view blockers'

This cannot be stressed enough: Ages must be designed with performance in mind. It is possible to have a large Age perform correctly as long as it is designed correctly. Among other things that means you need to keep in mind Visibility issues. Cut up your Age in various sections so that you can never see the whole Age at a time. For instance, the City is a large Age but it is cut in different sections, with tunnels and small paths joining them. But try to use the FlyMode to see the whole City at a time and you'll notice the performance difference... This can also be used to make smaller Ages more detailed. For instance Eder Kemo is cut in small sections but they are very detailed. Blocking the view with large objects (walls, mountains, tunnels) at strategical spots is critical.
>> See visibility management section

Using the Debug Client to test your Age

Now that Uru has gone open source Cyan's internal debug client can be used. This particular version of Uru includes a console that is loaded with features to test Ages and measure performance. Note: this client can only load MOUL ages; ages exported for Uru:CC cannot be used with this client. There is no article explaining how to compile and use the debug client yet.
<This section needs to be expanded>

First things to take care of

Polygon & texture budgets

When actually modelling the Age, this is the first step to decent performance. Judging the 'correct' polygon count for an object is not always easy. Using your best judgement, along with Visregion (see bellow), try to keep the number of polygons in view bellow 150.000. You can't directly measure polycounts in Uru, so make sure to always keeps an eye on those numbers in Blender (or Max).

Again looking at the Cyan Ages is your best start. Here are a few metrics:

  • Relto Age: Polys: around 110.000 / Textures : xx MB
  • Teledahn: Polys: around 150.000 / Textures : xx MB
  • Ae'gura (the City): Polys: above 550.000 / Textures : xx MB
  • Male avatar (at max resolution) : around 5.000 / Textures : xx MB

Judging texture size is a little easier : the larger an object the larger the texture. A small book on a desk do not need to have 1024x1024 texture. There are some tricks to save up textures though:

  • Re-use textures : Don't create a unique textures for each object -- do you really need 20 different 'wood' textures in your Age?
  • Use multi-texturing or stencils for large objects (terrains) : To avoid repettitive textures on large surfaces use multitexturing.
  • Use vertex painting or multitexturing for color variety : If you have a texture that you want to re-use with different colors.

Collisions

Collisions can be the worst performance hit, but they are pretty easy to take care of. Never enable collision on all your meshes; especially if you have complex meshes. Only enable collisions for objects you can walk on or touch in the game. For complex meshes it is a better idea to build low-polygons custom collider meshes. Have a look a Cyan's Ages (use the [PyPRP_Age_Importer PyPRP importer] version) to see how they handle those. For many objects it is not even necessary to model a custom collider, often a simple automatic 'box', 'hull', or 'cylinder' collision setting (depending on the mesh) will do the trick. For instance on a tree a 'cylinder' collision setting might do a decent approximation. 'Static triangle mesh' setting should be avoided unless absolutely necessary (for instance on a complex terrain mesh).
>> See: How_To_Make_Your_Objects_Collidable

Shadow buffers

By default Blender enable dynamic shadows for all new materials; this is the 'ShadBuf' button (in the 'Material' button, 'Links and Pipeline' panel). It uses up tons of performance so make sure to disable it for most objects materials except for some rare dynamic objects (animated objects/kickables). For static objects shadows can (and should) be done with lightmaps or approximated with vertex painting.

Visibility Management

Vis regions

On large Ages this is the most important performance optimization. Visregions allow you to 'remove' objects from the scene depending on the camera position. If you are in one part of a large Age you may not see the rest of the Age but it is still loaded and it takes up memory. A vis region can be used to unload that. For instance if you are inside a tunnel you do not need to have the rest of the Age loaded; use a vis region here. Used with a good Age design and visibility blockers, this will save a lot of performance and allow you to make detailed Ages. Designing 'visblockers' is often simple, for instance if you have a tunnel joining two sections of an Age don't make it straight or you will see through the other side. (again Kemo and the City are good examples of that.) For instance, if you have a twisty tunnel going from point A to point B; when you enter the tunnel from region A, region B is not loaded in memory yet, then you take a turn in the tunnel and you can load region B and unload region A and the player won't notice the transition.
>> See: Vis regions

Occluders

Note: Occluders are not currently available in PyPRP 1.6
An occluder is a special type of mesh that stops object behind it from being rendered. Occluders take time for the engine to calculate, so they should be large, very simple meshes with few faces. Occluders can be single-sided or double-sided. Occluders are not a replacement for visRegions. Use visRegions wisely, and occluders should be for special cases.

Examples of Occluders in Uru:

  • The volcano in the Cleft occludes the terrain behind it.
  • The desert floor occludes the rooms in the Cleft.
  • Zandi's trailer occludes the brushes and rocks.
  • Some giant occluders hide the two main sections of Eder Kemo from each other

Use an occluder if you already have a large solid object that will block viewing of objects behind it. Note that occluders are "all or nothing": you cannot specify which objects to occlude. Everything behind the occluder will not be rendered.

Page swapping

This is a pretty extreme measure, and no Cyan Age uses it.By default all of the Age pages are loaded in memory on the initial linking. Unlike vis regions who can load(unload objects, Page swapping is used to load/unload whole Age pages via Python. This saves up memory, and shortens loading times; but the tradeback is that when you load/unload a page it freezes the game for several seconds. It is also discouraged as it can cause problems online (because not all players have the same objects in memory). This is an 'old' method and has only ever been used on one Age (Ahra Pahts).
There is no wiki article detailling the process yet; search the forums for relevant informations.

Relevance regions

Relevance regions are not currently available in PyPRP 1.6
<This section needs to be expanded>


Misc. things

Kickables

Kickables are fun, because they are collision-intensive make sure to use custom collider meshes. (alternatively, 'box' 'cylinder' collision settings can work)

Transparency Overdraw reduction

Too many transparent textures on the screen at the same time ('overdraw') can quickly lead to performance drop. If possible when designing an Age, avoid having too many transparent textures on top of each other. (for instances: a glass in front of a tree in front of water etc)

Mesh LODs

For large objects that can be seen from a long distance it is a good idea to create LOD (Level Of Detail) low-polygons versions. For instance this is done by Cyan in the City for most buildings. Those can be displayed/hidden with Vis regions or 'soft distance' softvolumes.
<This section needs to be expanded>

Loading times

PyPRP does not compress vertex data due to floating-point errors that leave visual artefacts. However, you can use libHSPlasma's prc utilities to unpack and repack your DrawableSpans objects. libHSPlasma always compresses vertex data when repacking.
<This section needs to be expanded>