Material optimization: Difference between revisions
TomEdwards (talk | contribs) (partial rewrite) |
TomEdwards (talk | contribs) mNo edit summary |
||
Line 46: | Line 46: | ||
For a listing of all of the fallback shaders used in Half-Life 2, see the document [[Half-Life 2 Shader Fallbacks]]. | For a listing of all of the fallback shaders used in Half-Life 2, see the document [[Half-Life 2 Shader Fallbacks]]. | ||
== Overdraw == | == Overdraw == | ||
Line 96: | Line 78: | ||
If you've got fillrate and CPU to burn, you can forcibly make the water do local reflections (regardless of video config settings) by specifying <code>$forceexpensive 1</code>, and you can forcibly make the water reflect entities by specifying <code>$reflectentities 1</code>. | If you've got fillrate and CPU to burn, you can forcibly make the water do local reflections (regardless of video config settings) by specifying <code>$forceexpensive 1</code>, and you can forcibly make the water reflect entities by specifying <code>$reflectentities 1</code>. | ||
== Special materials == | |||
=== nodraw === | |||
[[Image:Toolsnodraw.gif|right|tools\toolsnodraw]] | |||
<code>tools\toolsnodraw</code> prevents a surface from being drawn at all, prevents lightmaps from being compiled for it, and prevents it from reflecting light (it still casts shadows). Use it on surfaces that will never be seen by the player but can't be sealed off by another brush, such as the tops of roofs and ledges or the far side of building in inaccessible areas, particularly those in [[background map]]s. | |||
=== black, white === | |||
Two materials that behave like nodraw, but have a color value. Use at the bottom of deep pits, behind bright lights, etc. | |||
=== skybox_2d === | |||
A [[3D skybox]] is drawn in full whenever the <code>tools\toolsskybox</code> material is being drawn. You can avoid this by using <code>tools\toolsskybox2d</code> in its place. Obviously, this only has an effect when the normal skybox material isn't visible! | |||
---- | ---- | ||
'''''[[Optimization (level design)|<< Return to Optimization (level design)]]''''' | '''''[[Optimization (level design)|<< Return to Optimization (level design)]]''''' |
Revision as of 12:36, 16 September 2008
When working with materials, there are a couple performance bottlenecks to keep in mind: fillrate (which usually affects all DirectX levels), and reducing vertex processing (which only is a bottleneck on DirectX7). As a level designer, the only real choice that you've got to combat any of these performance bottlenecks is to either reduce the amount of a particular expensive material on screen, or to turn off some of the expensive features in the material (like bumpmapping, for example). Note that you can make different choices about which features to use at each separate DirectX support level.
One other important aspect of dealing with performance bottlenecks is that you're going to have to measure framerates to see how well you're doing. For Half-Life 2, we used 3 target machines (determined based on looking at our hardware survey stats) for measuring performance at various DirectX levels. These were:
DX (DirectX) Level | Minimum Platform |
---|---|
DX9 | ATI 9800, 1 GB, P4 3.0 GHz |
DX8 | NVidia GeForce4 Ti4600, 512 MB, P4 2.0 GHz |
DX7 | NVidia GeForce2 MX, 256MB, P4 1.2 GHz |
Shader fallbacks
Here's how you specify different material parameters for different DX support levels: Each shader has a specific fallback shader it uses if the shader determines it can't run on the particular DX level on the card currently being run. Within the definition of your material, you add a field with the same name as the fallback shader and a sub-block of fields which are the values of those fields that you want to use if that fallback shader is being used. A list of the most commonly used shaders and their fallback shaders is shown below.
Here's an example:
LightmappedGeneric { $basetexture metal/metalwall063a $surfaceprop metal $envmap env_cubemap LightmappedGeneric_DX9 { $bumpmap metal/metalwall063a_normal $normalmapalphaenvmapmask 1 } LightmappedGeneric_DX8 { $basetexture metal/citadel_metalwall063a $basealphaenvmapmask 1 } LightmappedGeneric_DX6 { $fallbackmaterial metal/metalwall063b } }
In this example, the $envmap
field is used no matter what DirectX level the game is being run at. The $basetexture
field metal/metalwall063a
is used for every fallback shader except LightmappedGeneric_dx8
(used for running under DX8), which uses metal/citadel_metalwall063a
for its $basetexture.
Also under DX8 only, we add a field specifying that the special base texture used by dx8 has an envmap mask in its alpha channel. When using the LightmappedGeneric_DX9
shader (used by DX9), we add a bumpmap and specify that the envmap mask is in the alpha channel of the bumpmap. Note that it's also possible to cause the material system to use a completely different material with a totally different set of shaders by specifying a $fallbackmaterial
in a fallback block, which is done in this example when falling back to the LightmappedGeneric_DX6
shader (used by DX7 and DX6).
For a listing of all of the fallback shaders used in Half-Life 2, see the document Half-Life 2 Shader Fallbacks.
Overdraw
Fillrate refers to the number of pixels that a video card can shove into its memory per second, independently of the time needed to decide what colour they should be. It becomes an issue when the user tries to run a game at a higher resolution than the card is capable of, or more commonly when pixels are processed multiple times.
This effect is known as 'overdraw' and occurs when a material is translucent (particles are dreadful), uses normal mapping, uses specular reflections and/or is refractive. You can spot overdraw by checking showbudget
for an unusually large 'Swap Buffer' bar. (Objects/surfaces that are drawn despite being behind another object are technically overdraw too, but are normally discounted because it would be more expensive to cull them.)
The only real solution to overdraw is reducing the number of pixels that needs to be re-processed, usually with a shader fallback or by creating fewer, larger objects, but there are still a few tricks that can be employed to a limited effect.
Refraction
Any object that crosses the plane of a refractive material will be rendered twice: once for the direct view, and again for the refracted view (
). This becomes avoidable when the water is obscured - for instance, if the object is embedded in a displacement sand drift. By raising the model or cutting the water brush so that it doesn't extend beneath the displacement, the second rendering can be avoided.
You can examine what is being rendered for refraction with mat_showwatertextures 1
.
Normal mapping
LightmappedGeneric
materials are the prime suspects here. To help a little you can add $nodiffusebumplighting 1
to the material in question, which turns off albedo normal mapping without affecting specular, but as ever the only true solution is a fallback.

LightmappedGeneric_NoBump_DX8
to differentiate between video cards that have and haven't been deemed suitable for normal mapping by Valve.Water
With Water overdraw is caused by both refraction and reflection, often over a large area. You can disable them if needed perhaps in conjunction with another shader fallback:
$forcecheap 1
- Disables both reflection and refraction.
$refracttexture
$reflecttexture
- Not specifying a texture bypasses one or both passes.
If you've got fillrate and CPU to burn, you can forcibly make the water do local reflections (regardless of video config settings) by specifying $forceexpensive 1
, and you can forcibly make the water reflect entities by specifying $reflectentities 1
.
Special materials
nodraw
tools\toolsnodraw
prevents a surface from being drawn at all, prevents lightmaps from being compiled for it, and prevents it from reflecting light (it still casts shadows). Use it on surfaces that will never be seen by the player but can't be sealed off by another brush, such as the tops of roofs and ledges or the far side of building in inaccessible areas, particularly those in background maps.
black, white
Two materials that behave like nodraw, but have a color value. Use at the bottom of deep pits, behind bright lights, etc.
skybox_2d
A 3D skybox is drawn in full whenever the tools\toolsskybox
material is being drawn. You can avoid this by using tools\toolsskybox2d
in its place. Obviously, this only has an effect when the normal skybox material isn't visible!