7 (’Cthugha’)
Steve Streeting
c Torus Knot Software Ltd
Permission is granted to make and distribute verbatim copies of this manual provided the
copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the con-
ditions for verbatim copying, provided that the entire resulting derived work is distributed
under the terms of a permission notice identical to this one.
i
Table of Contents
OGRE Manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1 Object Orientation - more than just a buzzword . . . . . . . . . . . . . . . . 2
1.2 Multi-everything . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3 Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.1 Material Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.1.1 Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.1.2 Passes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.1.3 Texture Units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.1.4 Declaring Vertex/Geometry/Fragment Programs . . . . . . . . . . 63
3.1.5 Cg programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
3.1.6 DirectX9 HLSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
3.1.7 OpenGL GLSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
3.1.8 Unified High-level Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
3.1.9 Using Vertex/Geometry/Fragment Programs in a Pass . . . . 79
3.1.10 Vertex Texture Fetch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
3.1.11 Script Inheritence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
3.1.12 Texture Aliases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
3.1.13 Script Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
3.1.14 Script Import Directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
3.2 Compositor Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
3.2.1 Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
3.2.2 Target Passes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
3.2.3 Compositor Passes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
3.2.4 Applying a Compositor. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
3.3 Particle Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
3.3.1 Particle System Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
3.3.2 Particle Emitters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
3.3.3 Particle Emitter Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
3.3.4 Standard Particle Emitters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
ii
7 Shadows. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
7.1 Stencil Shadows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
7.2 Texture-based Shadows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
7.3 Modulative Shadows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
7.4 Additive Light Masking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
iii
8 Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
8.1 Skeletal Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
8.2 Animation State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
8.3 Vertex Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
8.3.1 Morph Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
8.3.2 Pose Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
8.3.3 Combining Skeletal and Vertex Animation . . . . . . . . . . . . . . . 202
8.4 SceneNode Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
8.5 Numeric Value Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
OGRE Manual 1
OGRE Manual
c The OGRE Team
This work is licenced under the Creative Commons Attribution-ShareAlike 2.5 License.
To view a copy of this licence, visit
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305,
USA.
Chapter 1: Introduction 2
1 Introduction
This chapter is intended to give you an overview of the main components of OGRE and
why they have been put together that way.
Well, nowadays graphics engines are like any other large software system. They start
small, but soon they balloon into monstrously complex beasts which just can’t be all un-
derstood:
Abstraction
Common interfaces hide the nuances between different implementations of 3D
API and operating systems
Chapter 1: Introduction 3
Encapsulation
Polymorphism
1.2 Multi-everything
I wanted to do more than create a 3D engine that ran on one 3D API, on one platform,
with one type of scene (indoor levels are most popular). I wanted OGRE to be able to
extend to any kind of scene (but yet still implement scene-specific optimisations under the
surface), any platform and any 3D API.
Therefore all the ’visible’ parts of OGRE are completely independent of platform, 3D
API and scene type. There are no dependencies on Windows types, no assumptions about
the type of scene you are creating, and the principles of the 3D aspects are based on core
maths texts rather than one particular API implementation.
Now of course somewhere OGRE has to get down to the nitty-gritty of the specifics
of the platform, API and scene, but it does this in subclasses specially designed for the
environment in question, but which still expose the same interface as the abstract versions.
For example, there is a ’Win32Window’ class which handles all the details about render-
ing windows on a Win32 platform - however the application designer only has to manipulate
it via the superclass interface ’RenderWindow’, which will be the same across all platforms.
Similarly the ’SceneManager’ class looks after the arrangement of objects in the scene
and their rendering sequence. Applications only have to use this interface, but there is a
’BspSceneManager’ class which optimises the scene management for indoor levels, meaning
you get both performance and an easy to learn interface. All applications have to do is hint
about the kind of scene they will be creating and let OGRE choose the most appropriate
implementation - this is covered in a later tutorial.
OGRE’s object-oriented nature makes all this possible. Currently OGRE runs on Win-
dows, Linux and Mac OSX using plugins to drive the underlying rendering API (currently
Direct3D or OpenGL). Applications use OGRE at the abstract level, thus ensuring that
they automatically operate on all platforms and rendering subsystems that OGRE provides
Chapter 1: Introduction 4
Introduction
This tutorial gives you a quick summary of the core objects that you will use in OGRE and
what they are used for.
This means every class, type etc should be prefixed with ’Ogre::’, e.g. ’Ogre::Camera’,
’Ogre::Vector3’ etc which means if elsewhere in your application you have used a Vector3
type you won’t get name clashes. To avoid lots of extra typing you can add a ’using
namespace Ogre;’ statement to your code which means you don’t have to type the ’Ogre::’
prefix unless there is ambiguity (in the situation where you have another definition with
the same name).
of the more more significant ones to give you an idea of how it slots together.
At the very top of the diagram is the Root object. This is your ’way in’ to the OGRE
system, and it’s where you tend to create the top-level objects that you need to deal with, like
scene managers, rendering systems and render windows, loading plugins, all the fundamental
stuff. If you don’t know where to start, Root is it for almost everything, although often it
will just give you another object which will actually do the detail work, since Root itself is
more of an organiser and facilitator object.
The majority of rest of OGRE’s classes fall into one of 3 roles:
Scene Management
This is about the contents of your scene, how it’s structured, how it’s viewed
from cameras, etc. Objects in this area are responsible for giving you a natural
declarative interface to the world you’re building; i.e. you don’t tell OGRE "set
these render states and then render 3 polygons", you tell it "I want an object
here, here and here, with these materials on them, rendered from this view",
and let it get on with it.
Resource Management
All rendering needs resources, whether it’s geometry, textures, fonts, whatever.
It’s important to manage the loading, re-use and unloading of these things
carefully, so that’s what classes in this area do.
Rendering Finally, there’s getting the visuals on the screen - this is about the lower-level
end of the rendering pipeline, the specific rendering system API objects like
Chapter 2: The Core Objects 7
buffers, render states and the like and pushing it all down the pipeline. Classes
in the Scene Management subsystem use this to get their higher-level scene
information onto the screen.
You’ll notice that scattered around the edge are a number of plugins. OGRE is designed
to be extended, and plugins are the usual way to go about it. Many of the classes in OGRE
can be subclassed and extended, whether it’s changing the scene organisation through a
custom SceneManager, adding a new render system implementation (e.g. Direct3D or
OpenGL), or providing a way to load resources from another source (say from a web location
or a database). Again this is just a small smattering of the kinds of things plugins can do,
but as you can see they can plug in to almost any aspect of the system. This way, OGRE
isn’t just a solution for one narrowly defined problem, it can extend to pretty much anything
you need it to do.
The root object lets you configure the system, for example through the showConfigDia-
log() method which is an extremely handy method which performs all render system options
detection and shows a dialog for the user to customise resolution, colour depth, full screen
options etc. It also sets the options the user selects so that you can initialise the system
directly afterwards.
The root object is also your method for obtaining pointers to other objects in the system,
such as the SceneManager, RenderSystem and various other resource managers. See below
for details.
Finally, if you run OGRE in continuous rendering mode, i.e. you want to always refresh
all the rendering targets as fast as possible (the norm for games and demos, but not for
windowed utilities), the root object has a method called startRendering, which when called
will enter a continuous rendering loop which will only end when all rendering windows are
closed, or any FrameListener objects indicate that they want to stop the cycle (see below
for details of FrameListener objects).
setting all the various rendering options. This class is abstract because all the imple-
mentationys-
tem.
It is to the SceneManager that you go when you want to create a camera for the scene.
It’s also where you go to retrieve or to remove a light from the scene. There is no need for
your application to keep lists of objects, the SceneManager keeps a named set of all of the
scene objects for you to access, should you need them. Look in the main documentation
under the getCamera, getLight, getEntity etc methods.
The SceneManager also sends the scene to the RenderSystem object when it is time to
render the scene. You never have to call the SceneManager:: renderScene method directly
though - it is called automatically whenever a rendering target is asked to update.
So most of your interaction with the SceneManager is during scene setup. You’re likely to
call a great number of methods (perhaps driven by some input file containing the scene data)
Chapter 2: The Core Objects 9
in order to set up your scene. You can also modify the contents of the scene dynamically
during the rendering cycle if you create your own FrameListener object (see later).
Because different scene types require very different algorithmic approaches to deciding
which objects get sent to the RenderSystem in order to attain good rendering performance,
the SceneManager class is designed to be subclassed for different scene types. The default
SceneManager object will render a scene, but it does little or no scene organisation and
you should not expect the results to be high performance in the case of large scenes. The
intention is that specialisations will be created for each type of scene such that under
the surface the subclass will optimise the scene organisation for best performance given
assumptions which can be made for that scene type. An example is the BspSceneManager
which optimises rendering for large indoor levels based on a Binary Space Partition (BSP)
tree.
The application using OGRE does not have to know which subclasses are available.
The application simply calls Root::createSceneManager(..) passing as a parameter one of a
number of scene types (e.g. ST GENERIC, ST INTERIOR etc). OGRE will automatically
use the best SceneManager subclass available for that scene type, or default to the basic
SceneManager if a specialist one is not available. This allows the developers of OGRE to
add new scene specialisations later and thus optimise previously unoptimised scene types
without the user applications having to change any code.
ResourceManagers ensure that resources are only loaded once and shared throughout
the OGRE engine. They also manage the memory requirements of the resources they look
after. They can also search in a number of locations for the resources they need, including
multiple search paths and compressed archives (ZIP files).
Most of the time you won’t interact with resource managers directly. Resource managers
will be called by other parts of the OGRE system as required, for example when you request
for a texture to be added to a Material, the TextureManager will be called for you. If you
like, you can call the appropriate resource manager directly to preload resources (if for
Chapter 2: The Core Objects 10
example you want to prevent disk access later on) but most of the time it’s ok to let OGRE
decide when to do it.
One thing you will want to do is to tell the resource managers where to look for re-
sources. You do this via Root::getSingleton().addResourceLocation, which actually passes
the information on to ResourceGroupManager.
Because there is only ever 1 instance of each resource manager in the engine, if you do
want to get a reference to a resource manager use the following syntax:
TextureManager::getSingleton().someMethod()
MeshManager::getSingleton().someMethod()
Mesh objects are a type of resource, and are managed by the MeshManager resource
manager. They are typically loaded from OGRE’s custom object format, the ’.mesh’ for-
mat. Mesh files are typically created by exporting from a modelling tool See Section 4.1
[Exporters], page 158 and can be manipulated through various Chapter 4 [Mesh Tools],
page 158 Section 2.6 [Entities], page 11.
Mesh objects can also be animated using See Section 8.1 [Skeletal Animation], page 197.
Chapter 2: The Core Objects 11
2.6 Entities.
Entities are not deemed to be a part of the scene until you attach them to a SceneNode
(see the section below). By attaching entities to SceneNodes, you can create complex hier-
archical relationships between the positions and orientations of entities. You then modify
the positions of the nodes to indirectly affect the entity positions.
To understand how this works, you have to know that all Mesh objects are actually
composed of SubMesh objects, each of which represents a part of the mesh using one
Material. If a Mesh uses only one Material, it will only have one SubMesh.
2.7 Materials
The:
Entities automatically have Material’s associated with them if they use a Mesh object,
since the Mesh object typically sets up it’s required materials on loading. You can also
customise the material used by an entity as described in Section 2.6 [Entities], page 11.
Just create a new Material, set it up how you like (you can copy an existing material into
it if you like using a standard assignment statement) and point the SubEntity entries at it
using SubEntity::setMaterialName().
2.8 Overlays
Overl.
Creating 2D Elements.
ate a panel (a plain rectangular area which can contain other OverlayElements) you would
call OverlayManager::getSingleton().createOverlayElement("Panel", "myNewPanel");
square-looking areas you will have to compensate using the typical aspect ratio
e.g. use (0.1875, 0.25) instead.
Transforming Overlays.
Scripting overlays
Overlays can also be defined in scripts. See Section 3.4 [Overlay Scripts], page 144 for
details.
GUI systems
Overlays are only really designed for non-interactive screen elements, although you can
use them as a crude GUI. For a far more complete GUI solution, we recommend CEGui
(), as demonstrated in the sample Demo Gui.
Chapter 3: Scripts 16
3 Scripts
OGRE drives many of its features through scripts in order to make it easier to set up.
The scripts are simply plain text files which can be edited in any standard text editor, and
modifying them immediately takes effect on your OGRE-based applications, without any
need to recompile. This makes prototyping a lot faster. Here are the items that OGRE lets
you script:
• Section 3.1 [Material Scripts], page 16
• Section 3.2 [Compositor Scripts], page 106
• Section 3.3 [Particle Scripts], page 121
• Section 3.4 [Overlay Scripts], page 144
• Section 3.5 [Font Definition Scripts], page 155
Material scripts are loaded when resource groups are initialised: OGRE looks in all re-
source locations associated with the group (see Root::addResourceLocation) for files with
the ’.material’ extension and parses them. If you want to parse files manually, use Materi-
al.
Chapter 3: Scripts 17
Format
}
}
}
}
Every material in the script must be given a name, which is the line ’material <blah>’
before the first opening ’’. This name must be globally unique. It can include path characters
Chapter 3: Scripts 18
 3.1.11
[Script Inheritence], page 96). You can also use variables in your script which can be
replaced in inheriting versions, see See Section 3.1.13 [Script Variables], page 104.
A material can be made up of many techniques (See Section 3.1.1 [Techniques], page 21)- 3.1.2 [Passes], page 24), 3.1.2 [Passes], page 24 for more
details.
Within each pass, there can be zero or many texture units in use (See Section 3.1.3
[Texture Units], page 45). 3.1.4 [Declaring Ver-
tex/Geometry/Fragment Programs], page 63) and are used as described in Section 3.1.9
[Using Vertex/Geometry/Fragment Programs in a Pass], page 79.
Chapter 3: Scripts 19
lod strategy
Sets the name of the LOD strategy to use. Defaults to ’Distance’ which means LOD changes
based on distance from the camera. Also supported is ’PixelCount’ which changes LOD
based on an estimate of the screen-space pixels affected.
lod values], page 19 -], page 22
value for each value in the list (so if you specify 3 values, you must have techniques for LOD
indexes 0, 1, 2 and 3). Note you must always have at least one Technique at lod index 0.
Example:
lod strategy Distance lod values 300.0 600.5 1200
Chapter 3: Scripts 20
The above example would cause the material to use the best Technique at lod index 0
up to a distance of 300 world units, the best from lod index 1 from 300 up to 600, lod index
2 from 600 to 1200, and lod index 3 from 1200 upwards.
receive shadows
This attribute controls whether objects using this material can have shadows cast upon
them.
Whether or not an object casts a shadow is the combination of a number of factors, See
Chapter 7 [Shadows], page 180 for full details; however this allows you to make a transparent
material cast shadows, when it would otherwise not. For example, when using texture
shadows, transparent materials are normally not rendered into the shadow texture because
they should not block light. This flag overrides that.
This attribute can be used to set the textures used in texture unit states that were
inherited from another material.(See Section 3.1.12 [Texture Aliases], page 100)
Chapter 3: Scripts 21
3.1.1 Techniques:
• The number of texture unit entries in each pass
Note that if the number of texture unit entries exceeds the number of texture units in
the current graphics card, the technique may still be supportable so long as a fragment
program is not being used. In this case, Ogre will split the pass which has too many
entries into multiple passes for the less capable card, and the multitexture blend will
be turned into a multipass blend (See [colour op multipass fallback], page 58).
• Whether vertex, geometry or fragment programs are used, and if so which syntax they
use (e.g. vs 1 1, ps 2 x, arbfp1 etc.)
• Other effects like cube mapping and dot3 blending
• Whether the vendor or device name of the current graphics card matches some user-
specified rules
In a material script, techniques must be listed in order of preference, i.e. the earlier tech-
niques Section 3.1.11 [Script Inheritence], page 96)
• [scheme], page 22
• [lod index], page 22 (and also see [lod distances], page 19 in the parent material)
• [shadow caster material], page 23
• [shadow receiver material], page 23
• [gpu vendor rule], page 23
• [gpu device rule], page 23
scheme’.
lod index], page 19 for details.
Chapter 3: Scripts 23
Techniques also contain one or more passes (and there must be at least one), See
Section 3.1.2 [Passes], page 24.:
Chapter 3: Scripts 24.
3.1.2 Passes Section 3.1.11 [Script Inheritence], page 96)
Passes have a set of global attributes (described below), zero or more nested texture unit
entries (See Section 3.1.3 [Texture Units], page 45), and optionally a reference to a vertex and
/ or a fragment program (See Section 3.1.9 [Using Vertex/Geometry/Fragment Programs
in a Pass], page 79).
Here are the attributes you can use in a ’pass’ section of a .material script:
• [ambient], page 25
• [diffuse], page 26
• [specular], page 26
• [emissive], page 27
• [scene blend], page 28
• [separate scene blend], page 29
• [scene blend op], page 30
Chapter 3: Scripts 25
Attribute Descriptions
ambient
Sets the ambient.
diffuse
Sets the diffuse.
specular
Sets the spec ie. This setting has no effect if dynamic lighting
is disabled using the ’lighting off’ attribute, or if any texture layer has a ’colour op replace’
attribute.
emissive
Sets the amount of self-illumination an object has. This attribute has no effect if a asm, CG,
or HLSL shader program is used. With GLSL, the shader can read the OpenGL material
state..
scene blend
Sets the kind of blending this pass has with the existing contents of the scene. Wheras. Valid <blend type> parameters are:
add The colour of the rendering output is added to the scene. Good for explosions,
flares, lights, ghosts etc. Equivalent to ’scene blend one one’.
modulate The colour of the rendering output is multiplied with the scene contents. Gen-
erally colours and darkens the scene, good for smoked glass, semi-transparent
objects etc. Equivalent to ’scene blend dest colour zero’.
colour blend
Colour the scene based on the brightness of the input colours, but don’t darken.
Equivalent to ’scene blend src colour one minus src colour’
alpha blend
The alpha value of the rendering output is used as a mask. Equivalent to
’scene blend src alpha one minus src alpha’
Chapter 3: Scripts 29
This version of the method allows complete control over the blending operation, by
specifying the source and destination blending factors. The resulting colour which is written
to the rendering target is (texture * sourceFactor) + (scene pixel * destFactor). Valid values
for both parameters are:
one Constant value of 1.0
zero Constant value of 0.0
dest colour
The existing pixel colour
src colour The texture pixel (texel) colour
one minus dest colour
1 - (dest colour)
one minus src colour
1 - (src colour)
dest alpha The existing pixel alpha value
src alpha The texel alpha value
one minus dest alpha
1 - (dest alpha)
one minus src alpha
1 - (src alpha)
Format1: separate scene blend <simple colour blend> <simple alpha blend>
Chapter 3: Scripts 30
This example would add colour components but multiply alpha components. The blend
modes available are as in [scene blend], page 28. The more advanced form is also available:
Format2: separate scene blend <colour src factor> <colour dest factor> <al-
pha src factor> <alpha dest factor>
Example: separate scene blend one one minus dest alpha one one
Again the options available in the second format are the same as those in the second
format of [scene blend], page 28.
scene blend op
This directive changes the operation which is applied between the two components of the
scene blending equation, which by default is ’add’ (sourceFactor * source + destFactor *
dest). You may change this to ’add’, ’subtract’, ’reverse subtract’, ’min’ or ’max’.
depth check
Sets whether or not this pass renders with depth-buffer checking on or not.
depth write.
depth func
Sets the function used to compare depth values when depth checking is on.:
always fail
Never writes a pixel to the render target
always pass
Always writes a pixel to the render target
less Write if (new Z < existing Z)
Chapter 3: Scripts 32
greater equal
Write if (new Z >= existing Z)
depth bias
Sets the bias applied to the depth value of this pass. Can be used to make coplanar polygons
appear on top of others e.g. for decals.
alpha rejection.
alpha to coverage.
light scissor
Sets whether when rendering this pass, rendering will be limited to a screen-space scissor
rectangle representing the coverage of the light(s) being used in this pass, derived from their
attenuation ranges.-
TYPE TEXTURE ADDITIVE, since it is the default behaviour to use a scissor for each
additive shadow pass. However, if you’re not using shadows, or you’re using [Integrated
Texture Shadows], page 189 where passes are specified in a custom manner, then this
could be of use to you..ClipVertex in your
Chapter 3: Scripts 35
shader, see the GLSL documentation for more information. In Direct3D user clip planes
are always respected.
illumination stage
When using an additive lighting mode (SHADOWTYPE STENCIL ADDITIVE or SHAD-
OW.
normalise normals
Sets whether or not this pass renders with all vertex normals being automatically re-
normalised..
transparent sorting.
cull hardware
Sets the hardware culling mode for this pass. triagles are rendered (useful
for creating 2-sided passes).
cull software
Sets the software culling mode for this pass..
lighting
Sets whether or not dynamic lighting is turned on for this pass or not. If lighting is turned
off, all objects rendered using the pass will be fully lit. This attribute has no effect if a
vertex program is used.
Chapter 3: Scripts 38
shading
Sets the kind of shading which should be used for representing dynamic lighting for this
pass.
When dynamic lighting is turned on, the effect is to generate colour values at each vertex.
Whether these values are interpolated across the face (and how) depends on this setting.
flat No interpolation takes place. Each face is shaded with a single colour deter-
mined from the first vertex in the face.
gouraud Colour at each vertex is linearly interpolated across the face.
phong Vertex normals are interpolated across the face, and these are used to determine
colour at each pixel. Gives a more natural lighting effect but is more expensive
and works better at high levels of tessellation. Not supported on all hardware.
Default: shading gouraud
polygon mode
Sets how polygons should be rasterised, i.e. whether they should be filled in, or just drawn
as lines or points.
fog override).. Here is an explanation of the
parameters:
colour write
Sets whether or not this pass renders with colour writing on or not.
If colour writing is off no visible pixels are written to the screen during this pass. You
might think this is useless, but if you render with colour writing off, and with very minimal
other settings, you can use this pass to initialise the depth buffer before subsequently ren-
dering other passes which fill in the colour data. This can give you significant performance
boosts on some newer cards, especially when using complex fragment programs, because if
the depth check fails then the fragment program is never run.
start light
Sets the first light which will be considered for use with this], page 41 option to start the iteration from a given point in
the list (e.g. doing the first 2 lights in the first pass, and then iterating every 2 lights from
then on perhaps).
max lights
Sets the maximum number of lights which will be considered for use with this pass.
The maximum number of lights which can be used when rendering fixed-function ma-
terials is set by the rendering system, and is typically set at 8. When you are using the
programmable pipeline (See Section 3.1.9 [Using Vertex/Geometry/Fragment Programs in
a Pass], page 79) this limit is dependent on the program you are running, or, if you use
Chapter 3: Scripts 41
’iteration once per light’ or a variant (See [iteration], page 41),.
iteration
Sets whether or not this pass is iterated, i.e. issued more than once.
Examples:.
Chapter 3: Scripts 42.
vertex_program_ref GLSLDemo/FurVS
{
}
fragment_program_ref GLSLDemo/FurFS
Chapter 3: Scripts 44
{
}
texture_unit
{
texture Fur.tga
tex_coord_set 0
filtering trilinear
}
}
}
}
Note: use gpu program auto parameters [pass number], page 91 and
[pass iteration number], page 92 to tell the vertex, geometry or fragment pro-
gram the pass number and iteration number.
point size
This setting allows you to change the size of points when rendering a point list, or a list of
point sprites. The interpretation of this command depends on the [point size attenuation],
page 45.
point sprites.
Chapter 3: Scripts 45.
Attribute Descriptions
texture alias
Sets the alias name for this texture unit.
Setting the texture alias name is useful if this material is to be inherited by other other
materials and only the textures will be changed in the new material.(See Section 3.1.12
[Texture Aliases], page 100)
Default: If a texture unit has a name then the texture alias defaults to the texture unit
name.
texture.
The ’type’ parameter allows you to specify a the type of texture to create - the default is
’2d’, but you can override this; here’s the full list:
1d A 1-dimensional texture; that is, a texture which is only 1 pixel high. These
kinds of textures can be useful when you need to encode a function in a texture
and use it as a simple lookup, perhaps in a fragment program. It is impor-
tant that you use this setting when you use a fragment program which uses
1-dimensional texture coordinates, since GL requires you to use a texture type
that matches (D3D will let you get away with it, but you ought to plan for
cross-compatibility). Your texture widths should still be a power of 2 for best
compatibility and performance.
2d The default type which is assumed if you omit it, your texture has a width and
a height, both of which should preferably be powers of 2, and if you can, make
them square because this will look best on the most hardware. These can be
addressed with 2D texture coordinates.
3d A 3 dimensional texture i.e. volume texture. Your texture has a width, a height,
both of which should be powers of 2, and has depth. These can be addressed
with 3d texture coordinates i.e. through a pixel shader.
cubic This texture is made up of 6 2D textures which are pasted around the inside of
a cube. Can be addressed with 3D texture coordinates and are useful for cubic
reflection maps and normal maps.
The ’numMipMaps’ option allows you to specify the number of mipmaps to generate for
this texture. The default is ’unlimited’ which means mips down to 1x1 size are generated.
Chapter 3: Scripts 48
You can specify a fixed number (even 0) if you like instead. Note that if you use the same
texture in many material scripts, the number of mipmaps generated will conform to the
number specified in the first texture unit used to load the texture - so be consistent with
your usage.
The ’alpha’ option allows you to specify that a single channel (luminance) texture should
be loaded as alpha, rather than the default which is to load it into the red channel. This
can be helpful if you want to use alpha-only textures in the fixed function pipeline.
Default: none
The <PixelFormat> option allows you to specify the desired pixel format of the texture
to create, which may be different to the pixel format of the texture file being loaded. Bear
in mind that the final pixel format will be constrained by hardware capabilities so you may
not get exactly what you ask for. The available options are:
PF L8 8-bit pixel format, all bits luminance.
PF L16 16-bit pixel format, all bits luminance.
PF A8 8-bit pixel format, all bits alpha.
PF A4L4 8-bit pixel format, 4 bits alpha, 4 bits luminance.
PF BYTE LA
2 byte pixel format, 1 byte luminance, 1 byte alpha
PF R5G6B5
16-bit pixel format, 5 bits red, 6 bits green, 5 bits blue.
PF B5G6R5
16-bit pixel format, 5 bits blue, 6 bits green, 5 bits red.
PF R3G3B2
8-bit pixel format, 3 bits red, 3 bits green, 2 bits blue.
PF A4R4G4B4
16-bit pixel format, 4 bits for alpha, red, green and blue.
PF A1R5G5B5
16-bit pixel format, 1 bit for alpha, 5 bits for red, green and blue.
PF R8G8B8
24-bit pixel format, 8 bits for red, green and blue.
PF B8G8R8
24-bit pixel format, 8 bits for blue, green and red.
PF A8R8G8B8
32-bit pixel format, 8 bits for alpha, red, green and blue.
PF A8B8G8R8
32-bit pixel format, 8 bits for alpha, blue, green and red.
Chapter 3: Scripts 49
PF B8G8R8A8
32-bit pixel format, 8 bits for blue, green, red and alpha.
PF R8G8B8A8
32-bit pixel format, 8 bits for red, green, blue and alpha.
PF X8R8G8B8
32-bit pixel format, 8 bits for red, 8 bits for green, 8 bits for blue like
PF A8R8G8B8, but alpha will get discarded
PF X8B8G8R8
32-bit pixel format, 8 bits for blue, 8 bits for green, 8 bits for red like
PF A8B8G8R8, but alpha will get discarded
PF A2R10G10B10
32-bit pixel format, 2 bits for alpha, 10 bits for red, green and blue.
PF A2B10G10R10
32-bit pixel format, 2 bits for alpha, 10 bits for blue, green and red.
PF FLOAT16 R
16-bit pixel format, 16 bits (float) for red
PF FLOAT16 RGB
48-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits
(float) for blue
PF FLOAT16 RGBA
64-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits
(float) for blue, 16 bits (float) for alpha
PF FLOAT32 R
16-bit pixel format, 16 bits (float) for red
PF FLOAT32 RGB
96-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits
(float) for blue
PF FLOAT32 RGBA
128-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits
(float) for blue, 32 bits (float) for alpha
PF SHORT RGBA
64-bit pixel format, 16 bits for red, green, blue and alpha
The ’gamma’ option informs the renderer that you want the graphics hardware to per-
form gamma correction on the texture values as they are sampled for rendering. This is
only applicable for textures which have 8-bit colour channels (e.g.PF R8G8B8). Often,
8-bit per channel textures will be stored in gamma space in order to increase the precision
of the darker colours () but this can
throw out blending and filtering calculations since they assume linear space colour values.
For the best quality shading, you may want to enable gamma correction so that the hard-
ware converts the texture values to linear space for you automatically when sampling the
texture, then the calculations in the pipeline can be done in a reliable linear colour space.
Chapter 3: Scripts 50
When rendering to a final 8-bit per channel display, you’ll also want to convert back to
gamma space which can be done in your shader (by raising to the power 1/2.2) or you can
enable gamma correction on the texture being rendered to or the render window. Note
that the ’gamma’ option on textures is applied on loading the texture so must be specified
consistently if you use this texture in multiple places.
anim texture
Sets the images to be used in an animated texture layer. In this case an animated texture
layer means one which has multiple frames, each of which is a separate image file. There
are 2 formats, one for implicitly determined image names, one for explicitly named images..
This sets up the same duration animation but from 5 separately named image files. The
first format is more concise, but the second is provided if you cannot make your images
conform to the naming standard required for it.
Default: none
cubic texture
Sets the images used in a cubic texture, i.e. one made up of 6 individual images making
up the faces of a cube. These kinds of textures are used for reflection maps (if hardware
supports cubic reflection maps) or skyboxes. There are 2 formats, a brief format expecting
image names of a particular format and a more flexible but longer format for arbitrarily
Chapter 3: Scripts 51
named textures..
Format2 (long): cubic texture <front> <back> <left> <right> <up> <down> separateUV).
Default: none
binding type
Tells this texture unit to bind to either the fragment processing unit or the vertex processing
unit (for Section 3.1.10 [Vertex Texture Fetch], page 95).
content type
Tells this texture unit where it should get its content from. The default is to get tex-
ture content from a named texture, as defined with the [texture], page 47, [cubic texture],
Chapter 3: Scripts 52
page 50, [anim texture], page 50 attributes. However you can also pull texture information
from other automated sources. The options are:
named The default option, this derives texture content from a texture name, loaded
by ordinary means from a file or having been manually created with a given
name.
shadow This option allows you to pull in a shadow texture, and is only valid when
you use texture shadows and one of the ’custom sequence’ shadowing types
(See Chapter 7 [Shadows], page 180)..
compositor
This option allows you to reference a texture from a compositor, and is only
valid when the pass is rendered within a compositor sequence. This can be ei-
ther second is the name of the texture to reference in the compositor. (Re-
quired)
The third is the index of the texture to take, in case of an MRT. (Optional)
filtering.
Simple Format
Format: filtering <none|bilinear|trilinear|anisotropic>
Default: filtering bilinear
With this format, you only need to provide a single parameter which is one of the following:
none No filtering or mipmapping is used. This is equivalent to the complex format
’filtering point point none’.
bilinear 2x2 box filtering is performed when magnifying or reducing a texture, and a
mipmap is picked from the list but no filtering is done between the levels of
the mipmaps. This is equivalent to the complex format ’filtering linear linear
point’.
trilinear 2x2 box filtering is performed when magnifying and reducing a texture, and
the closest 2 mipmaps are filtered together. This is equivalent to the complex
format ’filtering linear linear linear’.
anisotropic lin-
ear’. Note that in order for this to make any difference, you must also set the
[max anisotropy], page 55 attribute too.
Complex Format
Format: filtering <minification> <magnification> <mip>
Default: filtering linear linear point
This format gives you complete control over the minification, magnification, and mip filters.
Each parameter can be one of the following:
Chapter 3: Scripts 55
none Nothing - only a valid option for the ’mip’ filter , since this turns mipmapping
off completely. The lowest setting for min and mag is ’point’.
point Pick the closet pixel in min or mag modes. In mip mode, this picks the closet
matching mipmap.
linear Filter a 2x2 box of pixels around the closest one. In the ’mip’ filter this enables
filtering between mipmap levels.
anisotropic
Only valid for min and mag modes, makes the filter compensate for camera-
space slope of the triangles. Note that in order for this to make any difference,
you must also set the [max anisotropy], page 55 attribute too.
max anisotropy
Sets the maximum degree of anisotropy that the renderer will try to compensate for when
filtering textures.).], page 54 option on this texture to anisotropic.
Format: max anisotropy <value>
Default: max anisotropy 1
mipmap bias], page 54 has to be
set to point or linear.
Format: mipmap bias <value>
Default: mipmap bias 0
colour op
Determines how the colour of this texture layer is combined with the one below it (or the
lighting effect on the geometry if this is the first layer).
Chapter 3: Scripts 56 [colour op ex], page 56, but you’ll either have to be sure that
enough multitexturing units will be available, or you should explicitly set a fallback using
[colour op multipass fallback], page 58.
colour op ex
This is an extended version of the [colour op], page 55 attribute which allows extremely
detailed control over the blending applied between this and earlier layers. Multitexturing
hardware can apply more complex blending operations that multipass blending, but you
are limited to the number of texture units which are available in hardware.,
Chapter 3: Scripts 57
Operation options
source1 Use source1 without modification
source2 Use source2 without modification
modulate Multiply source1 and source2 together.
modulate x2
Multiply source1 and source2 together, then by 2 (brightening).
modulate x4
Multiply source1 and source2 together, then by 4 (brightening).
add Add source1 and source2 together.
add signed
Add source1 and source2 then subtract 0.5.
add smooth
Add source1 and source2, subtract the product
subtract Subtract source2 from source1
blend diffuse alpha
Use interpolated alpha value from vertices to scale source1, then
add source2 scaled by (1-alpha).
blend texture alpha
As blend diffuse alpha but use alpha from texture
blend current alpha
As blend diffuse alpha but use current alpha from previous stages
(same as blend diffuse alpha for first layer)
blend manual
As blend diffuse alpha but use a constant manual alpha value spec-
ified in <manual>
dotproduct
The dot product of source1 and source2
blend diffuse colour
Use interpolated colour value from vertices to scale source1, then
add source2 scaled by (1-colour).
Source1 and source2 options
src current
The colour as built up from previous stages.
src texture
The colour derived from the texture assigned to this layer.
Chapter 3: Scripts 58
src diffuse The interpolated diffuse colour from the vertices (same as
’src current’ for first layer).
src specular
The interpolated specular colour from the vertices.
src manual
The manual colour specified at the end of the command. to-
gether. oper-
ations.
alpha op ex
Behaves in exactly the same away as [colour op ex], page 56 except that it determines
how alpha values are combined between texture layers rather than colour values.The only
difference is that the 2 manual colours at the end of colour op ex are just single floating-
point values in alpha op ex.
env map
Turns on/off texture coordinate effect that makes this layer an environment map.
Environment maps make an object look reflective by using automatic texture coordinate
generation depending on the relationship between the objects vertices or normals and the
eye.
spherical.
planar Similar to the spherical environment map, but the effect is based on the po-
sition of the vertices in the viewport rather than vertex normals. This effect
is therefore useful for planar geometry (where a spherical env map would not
look good because the normals are all the same) or objects without normals.
Chapter 3: Scripts 60
cubic reflection],
page 50 to this texture unit and use the ’combinedUVW’ option.
cubic normal
Generates 3D texture coordinates containing the camera space normal vector
from the normal information held in the vertex data. Again, full use of this
feature requires a [cubic texture], page 50 with the ’combinedUVW’ option.
scroll
Sets a fixed scroll offset for the texture.
This method offsets the texture in this layer by a fixed amount. Useful for small ad-
justments without altering texture coordinates in models. However if you wish to have an
animated scroll effect, see the [scroll anim], page 60 attribute.
scroll anim
Sets up an animated scroll for the texture layer. Useful for creating fixed-speed scrolling
effects on a texture layer (for varying scroll speeds, see [wave xform], page 61).
rotate
Rotates a texture to a fixed angle. This attribute changes the rotational orientation of a
texture to a fixed angle, useful for fixed adjustments. If you wish to animate the rotation,
see [rotate anim], page 61.
rotate anim
Sets up an animated rotation effect of this layer. Useful for creating fixed-speed rotation
animations (for varying speeds, see [wave xform], page 61).
scale
Adjusts the scaling factor applied to this texture layer. Useful for adjusting the size of
textures without making changes to geometry. This is a fixed scaling factor, if you wish to
animate this see [wave xform], page 61.
Valid scale values are greater than 0, with a scale factor of 2 making the texture twice
as big in that dimension etc.
wave xform
Sets up a transformation animation based on a wave function. Useful for more advanced
texture layer transform effects. You can add multiple instances of this attribute to a single
texture layer if you wish.
Format: wave xform <xform type> <wave type> <base> <frequency> <phase> <ampli-
tude>
xform type
scroll x Animate the x scroll value
Chapter 3: Scripts 62
The range of the output of the wave will be base, base+amplitude. So the example above
scales the texture in the x direction between 1 (normal size) and 5 along a sine wave at one
cycle every 5 second (0.2 waves per second).
transform>.
Chapter 3: Scripts 639 HLSL, Open GL Shader Language, or nVidia’s Cg language (See [High-level
Programs], page 67)..
program is in before reading it, because during compilation of the material, we want to skip
programs which use an unsupportable syntax quickly, without loading the program first.
ps 2 x DirectX pixel shader (ie fragment program) assembler syntax. This is basically
ps 2 0 with a higher number of instructions.
Supported cards: ATI Radeon X series, nVidia GeForce FX 6 series
arbfp1).
fp20. You can find more information about nvparse at.
fp30 Another nVidia-specific OpenGL fragment shader syntax. It is a superset of ps
2.0, which is supported on nVidia GeForce FX 5 series and higher. ATI Radeon
HD 2000+ also supports it.
fp40 Another nVidia-specific OpenGL fragment shader syntax. It is a superset of ps
3.0, which is supported on nVidia GeForce FX 6 series and higher.
gpu gp, gp4 gp
An nVidia-specific OpenGL geometry shader syntax.
Supported cards: nVidia GeForce FX8 series
You can get a definitive list of the syntaxes supported by the current card by calling
GpuProgramManager::getSingleton().getSupportedSyntax().
default_params
{
param_named_auto lightPosition light_position_object_space 0
param_named_auto eyePosition camera_position_object_space
param_named_auto worldViewProj worldviewproj_matrix
param_named shininess float 10
}
}
The syntax of the parameter definition is exactly the same as when you define parameters
when using programs, See [Program Parameter Specification], page 80. Defining default
parameters allows you to avoid rebinding common parameters repeatedly (clearly in the
above example, all but ’shininess’ are unlikely to change between uses of the program)
which makes your material declarations shorter.
...
}
As you can see, you need to use the keyword ’shared params’ and follow it with the
name that you will use to identify these shared parameters. Inside the curly braces, you
can define one parameter per line, in a way which is very similar to the [param named],
page 92 syntax. The definition of these lines is:
Format: shared param name <param name> <param type> [<[array size]>] [<ini-
tial white-
space). If you wish, you can also initialise the parameters by providing a list of values.
Once you have defined the shared parameters, you can reference them inside
default params and params blocks using [shared params ref], page 93. You can also
obtain a reference to them in your code via GpuProgramManager::getSharedParameters,
and update the values for all instances using them.
High-level Programs
Support for high level vertex and fragment programs is provided through plugins; this is to
make sure that an application using OGRE can use as little or as much of the high-level
program functionality as they like. OGRE currently supports 3 high-level program types,
Cg (Section 3.1.5 [Cg], page 69) (an API- and card-independent, high-level language which
lets you write programs for both OpenGL and DirectX for lots of cards), DirectX 9 High-
Level Shader Language (Section 3.1.6 [HLSL], page 70), and OpenGL Shader Language
(Section 3.1.7 [GLSL], page 71). HLSL can only be used with the DirectX rendersystem,
and GLSL can only be used with the GL rendersystem. Cg can be used with both, although
experience has shown that more advanced programs, particularly fragment programs which
perform a lot of texture fetches, can produce better code in the rendersystem-specific shader
language. Section 3.1.8 [Unified High-
level Programs], page 76 to automatically pick a program suitable for your rendersystem
whilst using a single technique.
Chapter 3: Scripts 68.
If you use texture shadows, then vertex deformation is acceptable; however, when ren-
dering the object into a shadow texture (the shadow caster pass), the shadow has to be
rendered in a solid colour (linked to the ambient colour for modulative shadows, black for
additive shadows). You must therefore provide an alternative vertex program, so Ogre pro-
vides you with a way of specifying one to use when rendering the caster, See [Shadows and
Vertex Programs], page 93.
3.1.5 Cg programs
In order to define Cg programs, you have to have to load Plugin CgProgramManager.so/.dll
at startup, either through plugins.cfg or through your own plugin loading code. They are
very easy to define:
fragment_program myCgFragmentProgram cg
{
source myCgFragmentProgram.cg
entry_point main
profiles ps_2_0 arbfp1
Chapter 3: Scripts 70
}.
Lastly, there is a final option called ’compile arguments’, where you can specify argu-
ments exactly as you would to the cgc command-line compiler, should you wish to.
Chapter 3: Scripts 71
GLSL supports the use of modular shaders. This means you can write GLSL external
functions that can be used in multiple shaders.
vertex_program myExternalGLSLFunction1 glsl
{
source myExternalGLSLfunction1.txt
}
void main(void)
Chapter 3: Scripts 73
{.
Matrix parameters
Chapter 3: Scripts 74
// mat3
param_named TextRotMatrix float9 1 0 0 0 1 0 0 0 1
}
fragment_program_ref myFragmentShader
{
// mat2 uniform
param_named skewMatrix float4 0.5 0 -0.5 1.0
}
}
}
}).
vertex Binds VES POSITION, declare as ’attribute vec4 vertex;’.
normal Binds VES NORMAL, declare as ’attribute vec3 normal;’.
colour Binds VES DIFFUSE, declare as ’attribute vec4 colour;’.
secondary colour
Binds VES SPECULAR, declare as ’attribute vec4 secondary colour;’.
uv0 - uv7 Binds VES TEXTURE COORDINATES, declare as ’attribute vec4 uv0;’. Note
that uv6 and uv7 share attributes with tangent and binormal respectively so
cannot both be present.
tangent Binds VES TANGENT, declare as ’attribute vec3 tangent;’.
Chapter 3: Scripts 75
Preprocessor definitions
GLSL supports using preprocessor definitions in your code - some are defined by the imple-
mentation, but you can also define your own, say in order to use the same source code for
a few different variants of the same technique. In order to use this feature, include prepro-
cessor
{
source prog.hlsl
entry_point main_fp
target ps_2_0
}
vertex_program myVertexProgramGLSL glsl
{
source prog.vert
}
fragment_program myFragmentProgramGLSL glsl
{
source prog.frag
default_params
{
param_named tex int 0
}
}
material SupportHLSLandGLSLwithoutUnified
{
// HL
}
fragment_program_ref myFragmentProgramHLSL
{
}
}
}
// GL
Chapter 3: Scripts 78
}
fragment_program_ref myFragmentProgramHLSL
{
}
}
}
}
And that’s a really small example. Everything you added to the HLSL technique, you’d
have to duplicate in the GLSL technique too. So instead, here’s how you’d do it with unified
program definitions:
vertex_program myVertexProgramHLSL hlsl
{
source prog.hlsl
entry_point main_vp
target vs_2_0
}
fragment_program myFragmentProgramHLSL hlsl
{
source prog.hlsl
entry_point main_fp
target ps_2_0
}
vertex_program myVertexProgramGLSL glsl
{
source prog.vert
}
fragment_program myFragmentProgramGLSL glsl
{
source prog.frag
default_params
{
param_named tex int 0
}
}
//
Chapter 3: Scripts 79
{
//, OGRE automat-
ically.
As well as naming the program in question, you can also provide parameters to it. Here’s
a simple example:
vertex_program_ref myVertexProgram
{
param_indexed_auto 0 worldviewproj_matrix
param_indexed 4 float4 10.0 0 0 0
}
Chapter 3: Scripts 80able.
Parameter specification
Parameters can be specified using one of 4 commands as shown below. The same syntax is
used whether you are defining a parameter just for this particular use of the program, or
when specifying the [Default Program Parameters], page 66. Parameters set in the specific
use of the program override the defaults.
• [param indexed], page 80
• [param indexed auto], page 81
• [param named], page 92
• [param named auto], page 93
• [shared params ref], page 93
Chapter 3: Scripts 81
param indexed
This command sets the value of an indexed parameter.
The ’index’ is simply a number representing the position in the parameter list which
the value should be written, and you should derive this from your program definition. The
index is relative to the way constants are stored on the card, which is in 4-element blocks.
For example if you defined a float4 parameter at index 0, the next index would be 1. If you
defined a matrix4x4 at index 0, the next usable index would be 4, since a 4x4 matrix takes
up 4 indexes.
The value of ’type’ can be float4, matrix4x4, float<n>, int4, int<n>. Note that ’int’
parameters are only available on some more advanced program syntaxes, check the D3D or
GL vertex / fragment program documentation for full details. Typically the most useful
ones will be float4 and matrix4x4. Note that if you use a type which is not a multiple of
4, then the remaining values up to the multiple of 4 will be filled with zeroes for you (since
GPUs always use banks of 4 floats per constant even if only one is used).
’value’ is simply a space or tab-delimited list of values which can be converted into the
type you have specified.
’index’ has the same meaning as [param indexed], page 80; note this time you do not
have to specify the size of the parameter because the engine knows this already. In the
example, the world/view/projection matrix is being used so this is implicitly a matrix4x4.
Chapter 3: Scripts 82
world matrix
The current world matrix.
inverse world matrix
The inverse of the current world matrix.
transpose world matrix
The transpose of the world matrix
inverse transpose world matrix
The inverse transpose of the world matrix
world matrix array 3x4
An array of world matrices, each represented as only a 3x4 matrix (3 rows
of 4columns) usually for doing hardware skinning. You should make enough
entries available in your vertex program for the number of bones in use, ie an
array of numBones*3 float4’s.
view matrix
The current view matrix.
inverse view matrix
The inverse of the current view matrix.
transpose view matrix
The transpose of the view matrix
inverse transpose view matrix
The inverse transpose of the view matrix
projection matrix
The current projection matrix.
inverse projection matrix
The inverse of the projection matrix
transpose projection matrix
The transpose of the projection matrix
inverse transpose projection matrix
The inverse transpose of the projection matrix
worldview matrix
The current world and view matrices concatenated.
inverse worldview matrix
The inverse of the current concatenated world and view matrices.
transpose worldview matrix
The transpose of the world and view matrices
inverse transpose worldview matrix
The inverse transpose of the current concatenated world and view matrices.
Chapter 3: Scripts 83
viewproj matrix
The current view and projection matrices concatenated.
inverse viewproj matrix
The inverse of the view & projection matrices
transpose viewproj matrix
The transpose of the view & projection matrices
inverse transpose viewproj matrix
The inverse transpose of the view & projection matrices
worldviewproj matrix
The current world, view and projection matrices concatenated.
inverse worldviewproj matrix
The inverse of the world, view and projection matrices
transpose worldviewproj matrix
The transpose of the world, view and projection matrices
inverse transpose worldviewproj matrix
The inverse transpose of the world, view and projection matrices
texture matrix
The transform matrix of a given texture unit, as it would usually be seen in the
fixed-function pipeline. This requires an index in the ’extra params’ field, and
relates to the ’nth’ texture unit of the pass in question. NB if the given index
exceeds the number of texture units available for this pass, then the parameter
will be set to Matrix4::IDENTITY.
render target flipping
The value use to adjust transformed y position if bypassed projection matrix
transform. It’s -1 if the render target requires texture flipping, +1 otherwise.
vertex winding
Indicates what vertex winding mode the render state is in at this point; +1 for
standard, -1 for inverted (e.g. when processing reflections).
light diffuse colour
The diffuse colour of a given light; this requires an index in the ’extra params’
field, and relates to the ’nth’ closest light which could affect this object (i.e. 0
refers to the closest light - note that directional lights are always first in the list
and always present). NB if there are no lights this close, then the parameter
will be set to black.
light specular colour
The specular colour of a given light; this requires an index in the ’extra params’
field, and relates to the ’nth’ closest light which could affect this object (i.e.
0 refers to the closest light). NB if there are no lights this close, then the
parameter will be set to black.
light attenuation
A float4 containing the 4 light attenuation variables for a given light. This
requires an index in the ’extra params’ field, and relates to the ’nth’ closest
Chapter 3: Scripts 84
light which could affect this object (i.e. 0 refers to the closest light). NB
if there are no lights this close, then the parameter will be set to all zeroes.
The order of the parameters is range, constant attenuation, linear attenuation,
quadric attenuation.
spotlight params
A float4 containing the 3 spotlight parameters and a control value. The order of
the parameters is cos(inner angle /2 ), cos(outer angle / 2), falloff, and the final
w value is 1.0f. For non-spotlights the value is float4(1,0,0,1). This requires
an index in the ’extra params’ field, and relates to the ’nth’ closest light which
could affect this object (i.e. 0 refers to the closest light). If there are less lights
than this, the details are like a non-spotlight.
light position
The position
The direction - this property
only works on directional lights, and we recommend that you use light position
instead since that returns a generic 4D vector.
light position object space
The position object space
The direction, except for spotlights - for directional lights we recommend
that you use light position object space instead since that returns a generic
4D vector.
Chapter 3: Scripts 85
light power
The ’power’ scaling for a given light, useful in HDR rendering. This requires
an index in the ’extra params’ field, and relates to the ’nth’ closest light which
could affect this object (i.e. 0 refers to the closest light).
light number
When rendering, there is generally a list of lights available for use by all of the
passes for a given object, and those lights may or may not be referenced in
one or more passes. Sometimes it can be useful to know where in that overall
list a given light light (as seen from a pass) is. For example if you use iterate
once per light, the pass always sees the light as index 0, but in each iteration
the actual light referenced is different. This binding lets you pass through the
actual index of the light in that overall list. You just need to give it a parameter
of the pass-relative light number and it will map it to the overall list index.
Chapter 3: Scripts 86
frame time
The current frame time, factored by the optional parameter (or 1.0f if not
supplied).
fps The current frames per second
viewport width
The current viewport width in pixels
viewport height
The current viewport height in pixels
inverse viewport width
1.0/the current viewport width in pixels
inverse viewport height
1.0/the current viewport height in pixels
viewport size
4-element vector of viewport width, viewport height, inverse viewport width,
inverse viewport height
texel offsets
Provides details of the rendersystem-specific texture coordinate offsets required
to map texels onto pixels. float4(horizontalOffset, verticalOffset, horizontalOff-
set / viewport width, verticalOffset / viewport height).
view direction
View direction vector in object space
view side vector
View local X axis
view up vector
View local Y axis
fov Vertical field of view, in radians
near clip distance
Near clip distance, in world units
far clip distance
Far clip distance, in world units (may be 0 for infinite view projection)
texture viewproj matrix
Applicable to vertex programs which have been specified as the ’shadow re-
ceiver’ vertex program alternative, or where a texture unit is marked as con-
tent type shadow; this provides details of the view/projection matrix for the
current shadow projector. The optional ’extra params’ entry specifies which
light the projector refers to (for the case of content type shadow where more
than one shadow texture may be present in a single pass), where 0 is the default
and refers to the first light referenced in this pass.
texture viewproj matrix array
As texture viewproj matrix, except an array of matrices is passed, up to the
number that you specify as the ’extra params’ value.
Chapter 3: Scripts 91
param named
Chapter 3: Scripts 93
script is parsed, so at this stage we have no idea what types the parameters are. Programs
are only loaded and compiled when they are used, to save memory.
The allowed value codes and the meaning of extra params are detailed in
[param indexed auto], page 81..
Chapter 3: Scripts 94
If you use texture shadows, then vertex deformation is acceptable; however, when ren-
dering the object into the shadow texture (the shadow caster pass), the shadow has to be
rendered in a solid colour (linked to the ambient colour). You must therefore provide an
alternative vertex program, so Ogre provides you with a way of specifying one to use when
rendering the caster. Basically you link an alternative vertex program, using exactly the
same syntax as the original vertex program link:
shadow_caster_vertex_program_ref myShadowCasterVertexProgram
{
param_indexed_auto 0 worldviewproj_matrix
param_indexed_auto 4 ambient_light_colour
}
When rendering a shadow caster, Ogre will automatically use the alternate program.
You can bind the same or different parameters to the program - the most important thing
is that you bind ambiend light colour, since this determines the colour of the shadow in
modulative texture shadows. If you don’t supply an alternate program, Ogre will fall back
on a fixed-function material which will not reflect any vertex deformation you do in your
vertex program.
In addition, when rendering the shadow receivers with shadow textures, Ogre needs to
project the shadow texture. It does this automatically in fixed function mode, but if the
receivers use vertex programs, they need to have a shadow receiver program which does the
usual vertex deformation, but also generates projective texture coordinates. The additional
program linked into the pass like this:
shadow_receiver_vertex_program_ref myShadowReceiverVertexProgram
{
param_indexed_auto 0 worldviewproj_matrix
param_indexed_auto 4 texture_viewproj_matrix
}
For the purposes of writing this alternate program, there is an automatic parameter
binding of ’texture view pass render is actually the lighting
render, so if you perform any fragment program lighting you also need to pull in a custom
fragment program. You use the shadow receiver fragment program ref for this:
shadow_receiver_fragment_program_ref myShadowReceiverFragmentProgram
{
param_named_auto lightDiffuse light_diffuse_colour 0
Chapter 3: Scripts 95
}
You should pass the projected shadow coordinates from the custom vertex program. As
for textures, texture unit 0 will always be the shadow texture. Any other textures which
you bind in your pass will be carried across too, but will be moved up by 1 unit to make
room for the shadow texture. Therefore your shadow receiver fragment program is likely
to be the same as the bare lighting pass of your normal material, except that you insert an
extra texture sampler at index 0, which you will use to adjust the result by (modulating
diffuse and specular components).
To reflect this, you should use the [binding type], page 51
Chapter 3: Scripts 96.
Hardware limitations).
For example, to make a new material that is based on one previously defined, add a
colon : after the new material name followed by the name of the material that is to be
copied.
The only caveat is that a parent material must have been defined/parsed prior to the
child material script being parsed. The easiest way to achieve this is to either place parents
at the beginning of the material script file, or to use the ’import’ directive (See Section 3.1.14
[Script Import Directive], page 105). Note that inheritence is actually a copy - after scripts
are loaded into Ogre, objects no longer maintain their copy inheritance structure. If a
parent material is modified through code at runtime, the changes have no effect on child
materials that were copied from it in the script.
Chapter 3: Scripts 97 Section 3.1.13 [Script Variables],
page 104.:
material test2 : test1
{
technique
{
pass
{
}
pass
{
}
pass
{
}
pass
{
}
pass
{
ambient 0.5 0.7 0.3 1.0
}
}
}
This method is tedious for materials that only have slight variations to their parent. An
easier way is to name the pass directly without listing the previous passes:
Chapter 3: Scripts 98
Note: if passes or techniques aren’t given a name, they will take on a default name based
on their index. For example the first pass has index 0 so its name will be 0.
}
}
}
material Test
{
technique
{
pass : ParentPass
{
}
}
}.
The final matching option is based on wildcards. Using the ’*’ character, you can make
a powerful matching scheme and override multiple objects at once, even if you don’t know
Chapter 3: Scripts 100
material TSNormalSpecMapping
{
technique GLSL
{
pass
Chapter 3: Scripts 101
{
ambient 0.1 0.1 0.1
diffuse 0.7 0.7 0.7
specular 0.7 0.7 0.7 128
vertex_program_ref GLSLDemo/OffsetMappingVS
{
param_named_auto lightPosition light_position_object_space 0
param_named_auto eyePosition camera_position_object_space
param_named textureScale float 1.0
}
fragment_program_ref GLSLDemo/TSNormalSpecMappingFS
{
param_named normalMap int 0
param_named diffuseMap int 1
param_named fxMap int 2
}
// Normal map
texture_unit NormalMap
{
texture defaultNM.png
tex_coord_set 0
filtering trilinear
}
}
Chapter 3: Scripts 102
technique HLSL_DX9
{
pass
{
vertex_program_ref FxMap_HLSL_VS
{
param_named_auto worldViewProj_matrix worldviewproj_matrix
param_named_auto lightPosition light_position_object_space 0
param_named_auto eyePosition camera_position_object_space
}
fragment_program_ref FxMap_HLSL_PS
{
param_named ambientColor float4 0.2 0.2 0.2 0.2
}
// Normal map
texture_unit
{
texture_alias NormalMap
texture defaultNM.png
tex_coord_set 0
filtering trilinear
}
}
Chapter 3: Scripts 103
}.
Format:
set texture alias <alias name> <texture name>
The same process can be done in code as long you set up the texture alias names
so then there is no need to traverse technique/pass/TUS to change a texture. You just
call myMaterialPtr->applyTextureAliases(myAliasTextureNameList) which will update all
textures in all texture units that match the alias names in the map container reference you
passed as a parameter.
You don’t have to supply all the textures in the copied material.
Another example:
material fxTest3 : TSNormalSpecMapping
{
set_texture_alias DiffuseMap fxTest2Diff.png
}.
material Test
{
technique
{
pass : ParentPass
{
set $diffuse_colour "1 0 0 1"
}
}
}
The ParentPass object declares a variable called "diffuse colour" which is then overrid-
den.
Chapter 3: Scripts 105
material Test
{
set $diffuse_colour "1 0 0 1"
technique
{
pass : ParentPass
{
}
}
}
The $diffuse colour assignment carries down through the technique and into the pass.
Note, however that importing does not actually cause objects in the imported script to
be fully parsed & created, it just makes the definitions available for inheritence. This has a
specific ramification for vertex / fragment program definitions, which must be loaded before
any parameters can be specified. You should continue to put common program definitions
in .program files to ensure they are fully parsed before being referenced in multiple .ma-
terial files. The ’import’ command just makes sure you can resolve dependencies between
equivalent script definitions (e.g. material to material).
Chapter 3: Scripts 106
Compositor Fundamentals defi-
nitions are required:
Compositor
Definition of a fullscreen effect that can be applied to a user viewport. This is
what you’re defining when writing compositor scripts as detailed in this section.
Compositor Instance
An instance of a compositor as applied to a single viewport. You create these
based on compositor definitions, See Section 3.2.4 [Applying a Compositor],
page 120.
Compositor Chain 3.2.4 [Applying
a Compositor], page 120
Target [compositor texture], page 109. A target
Chapter 3: Scripts 107
which is not the output target has a defined size and pixel format which you
can control.
Output Target.
Target Pass
A Target may be rendered to many times in the course of a composition effect.
In particular if you ’ping pong’ a convolution between a couple of textures, you
will have more than one Target Pass per Target. Target passes are declared in
the script using a Section 3.2.2 [Compositor Target Passes], page 112, the latter
being the final output target pass, of which there can be only one.
Pass Within a Target Pass, there are one or more individual Section 3.2.3 [Compos-
itor Passes], page 114,.
Format
Chapter 3: Scripts 108 ie compositor "My
Name".
The major components of a compositor are the Section 3.2.1 [Compositor Techniques],
page 108, the Section 3.2.2 [Compositor Target Passes], page 112 and the Section 3.2.3
[Compositor Passes], page 114, which are covered in detail in the following sections.
3.2.1 Techniques
A compositor technique is much like a Section 3.1.1 [Techniques], page 21 in that it describes
one approach to achieving the effect you’re looking for. A compositor definition can have
more than one technique if you wish to provide some fallback should the hardware not
support the technique you’d prefer to use. Techniques are evaluated for hardware support
based on 2 things:
Material support
All Section 3.2.3 [Compositor Passes], page 114 that render a fullscreen quad
use a material; for the technique to be supported, all of the materials refer-
enced must have at least one supported material technique. If they don’t, the
compositor technique is marked as unsupported and won’t be used.
Chapter 3: Scripts 109
As with material techniques, compositor techniques are evaluated in the order you define
them in the script, so techniques declared first are preferred over those declared later.
Format: technique
texture
This declares a render texture for use in subsequent Section 3.2.2 [Compositor Target
Passes], page 112.
Format: texture <Name> <Width> <Height> <Pixel Format> [<MRT Pixel Format2>]
[<MRT Pixel FormatN>] [pooled] [gamma] [no fsaa] [<scope>]
Name A name to give the render texture, which must be unique within this compos-
itor..
Chapter 3: Scripts 110
Width, Height
The dimensions of the render texture. You can either specify a fixed width
and height, or you can request that the texture is based on the physical di-
mensions of the viewport to which the compositor is attached. The options
for the latter are ’target width’, ’target height’, ’target width scaled <factor>’
and ’target height scaled <factor>’ - where ’factor’ is the amount by which you
wish to multiply the size of the main target to derive the dimensions.
Pixel Format
The pixel format of the render texture. This affects how much memory it
will take, what colour channels will be available, and what precision you
will have within those channels. The available options are PF A8R8G8B8,
PF R8G8B8A8, PF R8G8B8, PF FLOAT16 RGBA, PF FLOAT16 RGB,
PF FLOAT16 R, PF FLOAT32 RGBA, PF FLOAT32 RGB, and
PF FLOAT32 R.
pooled If present, this directive makes this texture ’pooled’ among compositor in-
stances, which can save some memory.
gamma If present, this directive means that sRGB gamma correction will be enabled
on writes to this texture. You should remember to include the opposite sRGB
conversion when you read this texture back in another material, such as a quad.
This option will automatically enabled if you use a render scene pass on this
texture and the viewport on which the compositor is based has sRGB write
support enabled.
no fsaa If present, this directive disables the use of anti-aliasing on this texture. FSAA
is only used if this texture is subject to a render scene pass and FSAA was
enabled on the original viewport on which this compositor is based; this option
allows you to override it and disable the FSAA if you wish.
scope If present, this directive sets the scope for the texture for being accessed by other
compositors using the [compositor texture ref], page 111 directive. There are
three options : ’local scope’ (which is also the default) means that only the
compositor defining the texture can access it. ’chain scope’ means that the
compositors after this compositor in the chain can reference its textures, and
’global scope’ means that the entire application can access the texture. This
directive also affects the creation of the textures (global textures are created
once and thus can’t be used with the pooled directive, and can’t rely on viewport
size).
Example: texture rt0 512 512 PF R8G8B8A8
Example: texture rt1 target width target height PF FLOAT32 RGB
You can in fact repeat this element if you wish. If you do so, that means that this
render texture becomes a Multiple Render Target (MRT), when the GPU writes to multiple
textures at once. It is imperative that if you use MRT that the shaders that render to it
render to ALL the targets. Not doing so can cause undefined results. It is also important
to note that although you can use different pixel formats for each target in a MRT, each
Chapter 3: Scripts 111
one should have the same total bit depth since most cards do not support independent bit
depths. If you try to use this feature on cards that do not support the number of MRTs
you’ve asked for, the technique will be skipped (so you ought to write a fallback technique).
Example : texture mrt output target width target height PF FLOAT16 RGBA
PF FLOAT16 RGBA chain scope
texture ref
This declares a reference of a texture from another compositor to be used in this compositor.
Format: texture ref <Local Name> <Reference Compositor> <Reference Texture Name>
Here is a description of the parameters:
Local Name
A name to give the referenced texture, which must be unique within this com-
positor..
Reference Compositor
The name of the compositor that we are referencing a texture from
Reference Texture Name
The name of the texture in the compositor that we are referencing
Make sure that the texture being referenced is scoped accordingly (either chain or global
scope) and placed accordingly during chain creation (if referencing a chain-scoped texture,
the compositor must be present in the chain and placed before the compositor referencing
it).
Example : texture ref GBuffer GBufferCompositor mrt output
scheme
This gives a compositor technique a scheme name, allowing you to manually switch be-
tween different techniques for this compositor when instantiated on a viewport by calling
CompositorInstance::setScheme.
compositor logic
This connects between a compositor and code that it requires in order to function correctly.
When an instance of this compositor will be created, the compositor logic will be notified
and will have the chance to prepare the compositor’s operation (for example, adding a
listener).
Chapter 3: Scripts 112
There are two types of target pass, the sort that updates a render texture:
... and the sort that defines the final output render:
The contents of both are identical, the only real difference is that you can only have a
single target output entry, whilst you can have many target entries. Here are the attributes
you can use in a ’target’ or ’target output’ section of a .compositor script:
• [compositor target input], page 112
• [only initial], page 113
• [visibility mask], page 113
• [compositor lod bias], page 113
• [material scheme], page 114
• [compositor shadows], page 113
• Section 3.2.3 [Compositor Passes], page 114
Attribute Descriptions
input
Sets input mode of the target, which tells the target pass what is pulled in before any of its
own passes are rendered..
previous.
only initial
If set to on, this target pass will only execute once initially after the effect has been enabled.
This could be useful to perform once-off renders, after which the static contents are used
by the rest of the compositor.
visibility mask
Sets the visibility mask for any render scene passes performed in this target pass. This
is a bitmask (although it must be specified as decimal, not hex) and maps to SceneMan-
ager::setVisibilityMask. Format: visibility mask <mask>
lod bias
Set the scene LOD bias for any render scene passes performed in this target pass. The
default is 1.0, everything below that means lower quality, higher means higher quality.
shadows
Sets whether shadows should be rendered during any render scene pass performed in this
target pass. The default is ’on’.
Default: shadows on
Chapter 3: Scripts 114
material scheme
If set, indicates the material scheme to use for any render scene pass. Useful for performing
special-case rendering effects.
Default: None
Format: ’pass’ (render quad | clear | stencil | render scene | render custom) [custom
name]
material
For passes of type ’render quad’, sets the material used to render the quad. You
will want to use shaders in this material to perform fullscreen effects, and use the
[compositor pass input], page 115 attribute to map other texture targets into the texture
bindings needed by this material.
input
For passes of type ’render quad’, this is how you map one or more local render textures
(See [compositor texture], page 109) into the material you’re using to render the fullscreen
quad. To bind more than one texture, repeat this attribute with different sampler indexes.
sampler The texture sampler to set, must be a number in the range [0,
OGRE MAX TEXTURE LAYERS-1].
Name The name of the local render texture to bind, as declared in
[compositor texture], page 109 and rendered to in one or more
Section 3.2.2 [Compositor Target Passes], page 112.
MRTIndex
If the local texture that you’re referencing is a Multiple Render Target (MRT),
this identifies the surface from the MRT that you wish to reference (0 is the
first surface, 1 the second etc).
Example: input 0 rt0
identifier
Associates a numeric identifier with the pass. This is useful for registering a listener with
the compositor (CompositorInstance::addListener), and being able to identify which pass it
is that’s being processed when you get events regarding it. Numbers between 0 and 2^32
Chapter 3: Scripts 116
are allowed.
Default: identifier 0
material scheme
If set, indicates the material scheme to use for this pass only. Useful for performing special-
case rendering effects.
This will overwrite the scheme if set at the target scope as well.
Default: None
Clear Section
For passes of type ’clear’, this section defines the buffer clearing parameters.
Format: clear
Chapter 3: Scripts 117
Here are the attributes you can use in a ’clear’ section of a .compositor script:
• [compositor clear buffers], page 117
• [compositor clear colour value], page 117
• [compositor clear depth value], page 117
• [compositor clear stencil value], page 117
buffers
Sets the buffers cleared by this pass.
colour value
Set the colour used to fill the colour buffer by this pass, if the colour buffer is being
cleared ([compositor clear buffers], page 117).
depth value
Set the depth value used to fill the depth buffer by this pass, if the depth buffer is being
cleared ([compositor clear buffers], page 117).
stencil value
Set the stencil value used to fill the stencil buffer by this pass, if the stencil buffer is
being cleared ([compositor clear buffers], page 117).
Stencil Section
For passes of type ’stencil’, this section defines the stencil operation parameters.
Format: stencil
Here are the attributes you can use in a ’stencil’ section of a .compositor script:
• [compositor stencil check], page 118
• [compositor stencil comp func], page 118
• [compositor stencil ref value], page 118
• [compositor stencil mask], page 119
• [compositor stencil fail op], page 119
• [compositor stencil depth fail op], page 119
• [compositor stencil pass op], page 120
• [compositor stencil two sided], page 120
check
Enables or disables the stencil check, thus enabling the use of the rest of the features
in this section. The rest of the options in this section do nothing if the stencil check is
off. Format: check (on | off)
comp func
Sets the function used to perform the following comparison:
(ref value & mask) comp func (Stencil Buffer Value & mask)
What happens as a result of this comparison will be one of 3 actions on the stencil
buffer, depending on whether the test fails, succeeds but with the depth buffer check
still failing, or succeeds with the depth buffer check passing too. You set the actions
in the [compositor stencil fail op], page 119, [compositor stencil depth fail op],
page 119 and [compositor stencil pass op], page 120 respectively. If the stencil check
fails, no colour or depth are written to the frame buffer.
Format: comp func (always fail | always pass | less | less equal | not equal |
greater equal | greater)
ref value
Sets the reference value used to compare with the stencil buffer as described in
[compositor stencil comp func], page 118.
mask
Sets the mask used to compare with the stencil buffer as described in
[compositor stencil comp func], page 118.
fail op
Sets what to do with the stencil buffer value if the result of the stencil comparison
([compositor stencil comp func], page 118) and depth comparison is that both fail.
depth fail op
Sets what to do with the stencil buffer value if the result of the stencil comparison
([compositor stencil comp func], page 118) passes but the depth comparison fails.
Chapter 3: Scripts 120
Format: depth fail op (keep | zero | replace | increment | decrement | increment wrap
| decrement wrap | invert)
pass op
Sets what to do with the stencil buffer value if the result of the stencil comparison
([compositor stencil comp func], page 118) and the depth comparison pass.
two sided
Enables or disables two-sided stencil operations, which means the inverse of the oper-
ations applies to back-facing polygons.
CompositorManager::getSingleton().addCompositor(viewport, compositorName);
Where viewport is a pointer to your viewport, and compositorName is the name of the
compositor to create an instance of. By doing this, a new instance of a compositor will
be added to a new compositor chain on that viewport. You can call the method multiple
times to add further compositors to the chain on this viewport. By default, each compositor
which is added is disabled, but you can change this state by calling:
For more information on defining and using compositors, see Demo Compositor in the
Samples area, together with the Examples.compositor script in the media area.
Particle system scripts are loaded at initialisation time by the system: by default it looks in
all common resource locations (see Root::addResourceLocation) for files with the ’.particle’
extension and parses them. If you want to parse files with a different extension, use the Par-
ticleS).
Format
Chapter 3: Scripts 122
{ depen-
dent on the type of emitter / affector.
For a detailed description of the core particle system attributes, see the list below:
quota).
material
Sets the name of the material which all particles in this system will use. All particles in a
system use the same material, although each particle can tint this material through the use
of it’s colour property.
Chapter 3: Scripts 124
particle width
Sets the width of particles in world coordinates. Note that this property is absolute when
billboard type (see below) is set to ’point’ or ’perpendicular self’, but is scaled by the
length of the direction vector when billboard type is ’oriented common’, ’oriented self’ or
’perpendicular common’.
particle height
Sets the height of particles in world coordinates. Note that this property is absolute when
billboard type (see below) is set to ’point’ or ’perpendicular self’, but is scaled by the
length of the direction vector when billboard type is ’oriented common’, ’oriented self’ or
’perpendicular common’.
cull each.
renderer
Particle systems do not render themselves, they do it through ParticleRenderer classes.
Those classes are registered with a manager in order to provide particle systems with a
Chapter 3: Scripts 125.
sorted
By default, particles are not sorted. By setting this attribute to ’true’, the particles will be
sorted with respect to the camera, furthest first. This can make certain rendering effects
look better at a small sorting expense.
local space.
billboard type.
Chapter 3: Scripts 126
billboard origin
Specifying the point which acts as the origin point for all billboard particles, controls the
fine tuning of where a billboard particle appears in relation to it’s position.
format: billboard origin <top left|top center|top right|center left|center|center right|bottom left|bottom
Chapter 3: Scripts 127
vertex Billboard particles will rotate the vertices around their facing direction to ac-
cording with particle rotation. Rotate vertices guarantee texture corners exactly
match billboard corners, thus has advantage mentioned above, but should take
more time to generate the vertices.
texcoord Billboard particles will rotate the texture coordinates to according with particle
rotation. Rotate texture coordinates is faster than rotate vertices, but has some
disadvantage mentioned above.
Chapter 3: Scripts 128
common direction
Only required if [billboard type], page 125 is set to oriented common or perpendicu-
lar common, this vector is the common direction vector used to orient all particles in the
system.
See also: Section 3.3.2 [Particle Emitters], page 130, Section 3.3.5 [Particle Affectors],
page 137
common up vector
Only required if [billboard type], page 125 is set to perpendicular self or perpendicu-
lar common, this vector is the common up vector used to orient all particles in the system.
See also: Section 3.3.2 [Particle Emitters], page 130, Section 3.3.5 [Particle Affectors],
page 137
point rendering
This is actually an attribute of the ’billboard’ particle renderer (the default), and sets
whether or not the BillboardSet will use point rendering rather than manually generated
quads.
Using point rendering is faster than generating quads manually, but is more restrictive.
The following restrictions apply:
• Only the ’point’ orientation type is supported
• Size and appearance of each particle is controlled by the material pass ([point size],
page 44, [point size attenuation], page 45, [point sprites], page 44)
Chapter 3: Scripts 129
You will almost certainly want to enable in your material pass both point attenuation
and point sprites if you use this option.
accurate facing.
iteration interval.
This option lets you set a ’timeout’ on the particle system, so that if it isn’t visible for
this amount of time, it will stop updating until it is next visible. A value of 0 disables the
timeout and always updates.
It is also possible to ’emit emitters’ - that is, have new emitters spawned based on the
position of particles. See [Emitting Emitters], page 137
See also: Section 3.3 [Particle Scripts], page 121, Section 3.3.5 [Particle Affectors], page 137
angle
Sets the maximum angle (in degrees) which emitted particles may deviate from the direction
of the emitter (see direction). Setting this to 10 allows particles to deviate up to 10 degrees
in any direction away from the emitter’s direction. A value of 180 means emit in any
direction, whilst 0 means emit always exactly in the direction of the emitter.
colour
Sets a static colour for all particle emitted. Also see the colour range start and
colour range end attributes for setting a range of colours. The format of the colour
parameter is "r g b a", where each component is a value from 0 to 1, and the alpha value
is optional (assumes 1 if not specified).
format: as colour
example (generates random colours between red and blue):
colour range start 1 0 0
colour range end 0 0 1
default: both 1 1 1 1
direction
Sets the direction of the emitter. This is relative to the SceneNode which the particle system
is attached to, meaning that as with other movable objects changing the orientation of the
node will also move the emitter.
emission rate
Sets how many particles per second should be emitted. The specific emitter does not have
to emit these in a continuous burst - this is a relative parameter and the emitter may choose
to emit all of the second’s worth of particles every half-second for example, the behaviour
depends on the emitter. The emission rate will also be limited by the particle system’s
’quota’ setting.
position
Sets the position of the emitter relative to the SceneNode the particle system is attached
to.
velocity
Sets a constant velocity for all particles at emission time. See also the velocity min and
velocity max attributes which allow you to set a range of velocities instead of a fixed one.
format: as velocity
example:
velocity min 50
velocity max 100
default: both 1
time to live
Sets the number of seconds each particle will ’live’ for before being destroyed. NB it is
possible for particle affectors to alter this in flight, but this is the value given to particles
on emission. See also the time to live min and time to live max attributes which let you
set a lifetime range instead of a fixed one.
duration
Sets the number of seconds the emitter is active. The emitter can be started again, see
[repeat delay], page 134. A value of 0 means infinite duration. See also the duration min
and duration max attributes which let you set a duration range instead of a fixed one.
format: as duration
example:
duration min 2
duration max 5
default: both 0
repeat delay
Sets the number of seconds to wait before the emission is repeated when stopped by a limited
[duration], page 133. See also the repeat delay min and repeat delay max attributes which
allow you to set a range of repeat delays instead of a fixed one.
repeat delay 2
repeat delay 5
default: both 0
See also: Section 3.3.4 [Standard Particle Emitters], page 135, Section 3.3 [Particle
Scripts], page 121, Section 3.3.5 [Particle Affectors], page 137
Point Emitter
This emitter emits particles from a single point, which is it’s position. This emitter has no
additional attributes over an above the standard emitter attributes.
To create a point emitter, include a section like this within your particle system script:
emitter Point
{
// Settings go here
}
Box Emitter
This emitter emits particles from a random location within a 3-dimensional box. It’s extra
attributes are:
width Sets the width of the box (this is the size of the box along it’s local X axis,
which is dependent on the ’direction’ attribute which forms the box’s local Z).
Chapter 3: Scripts 136
height Sets the height of the box (this is the size of the box along it’s local Y axis,
which is dependent on the ’direction’ attribute which forms the box’s local Z).
format: height <units>
example: height 250
default: 100
depth Sets the depth of the box (this is the size of the box along it’s local Z axis,
which is the same as the ’direction’ attribute).
format: depth <units>
example: depth 250
default: 100
To create a box emitter, include a section like this within your particle system script:
emitter Box
{
// Settings go here
}
Cylinder Emitter
This emitter emits particles in a random direction from within a cylinder area, where the
cylinder is oriented along the Z-axis. This emitter has exactly the same parameters as the
[Box Emitter], page 135 so there are no additional parameters to consider here - the width
and height determine the shape of the cylinder along it’s axis (if they are different it is an
ellipsoid cylinder), the depth determines the length of the cylinder.
Ellipsoid Emitter
This emitter emits particles from within an ellipsoid shaped area, i.e. a sphere or squashed-
sphere area. The parameters are again identical to the [Box Emitter], page 135, except that
the dimensions describe the widest points along each of the axes.
inner depth
The depth of the inner area which does not emit any particles.
Ring Emitter
This emitter emits particles from a ring-shaped area, i.e. a little like [Hollow Ellipsoid
Emitter], page 136 except only in 2 dimensions.
inner width
The width of the inner area which does not emit any particles.
inner height
The height of the inner area which does not emit any particles.
See also: Section 3.3 [Particle Scripts], page 121, Section 3.3.2 [Particle Emitters],
page 130
Emitting Emitters
It is possible to spawn new emitters on the expiry of particles, for example to product
’firework’ style effects. This is controlled via the following directives:
emit emitter quota
This parameter is a system-level parameter telling the system how many emitted
emitters may be in use at any one time. This is just to allow for the space
allocation process.
name This parameter is an emitter-level parameter, giving a name to an emitter. This
can then be referred to in another emitter as the new emitter type to spawn
when an emitted particle dies.
emit emitter
This is an emitter-level parameter, and if specified, it means that when particles
emitted by this emitter die, they spawn a new emitter of the named type.
Particle affectors actually have no universal attributes; they are all specific to the type
of affector.
Chapter 3: Scripts 138
See also: Section 3.3.6 [Standard Particle Affectors], page 138, Section 3.3 [Particle
Scripts], page 121, Section 3.3.2 [Particle Emitters], page 130
force vector
Sets the vector for the force to be applied to every particle. The magnitude of
this vector determines how strong the force is.
format: force vector <x> <y> <z>
example: force vector 50 0 -50
default: 0 -100 0 (a fair gravity effect)
force application
Sets the way in which the force vector is applied to particle momentum.
format: force application <add|average>
example: force application average
default: add
The options are:
average The resulting momentum is the average of the force vector and the
particle’s current motion. Is self-stabilising but the speed at which
the particle changes direction is non-linear.
add The resulting momentum is the particle’s current motion plus the
force vector. This is traditional force acceleration but can poten-
tially result in unlimited velocity.
To create a linear force affector, include a section like this within your particle system script:
Chapter 3: Scripts 139
affector LinearForce
{
// Settings go here
}
Please note that the name of the affector type (’LinearForce’) is case-sensitive.
ColourFader Affector
This affector modifies the colour of particles in flight. It’s extra attributes are:
red Sets the adjustment to be made to the red component of the particle colour per
second.
format: red <delta value>
example: red -0.1
default: 0
green Sets the adjustment to be made to the green component of the particle colour
per second.
format: green <delta value>
example: green -0.1
default: 0
blue Sets the adjustment to be made to the blue component of the particle colour
per second.
format: blue <delta value>
example: blue -0.1
default: 0
alpha Sets the adjustment to be made to the alpha component of the particle colour
per second.
format: alpha <delta value>
example: alpha -0.1
default: 0
To create a colour fader affector, include a section like this within your particle system
script:
affector ColourFader
{
// Settings go here
}
ColourFader2 Affector
This affector is similar to the [ColourFader Affector], page 139, except it introduces two
states of colour changes as opposed to just one. The second colour change state is activated
once a specified amount of time remains in the particles life.
Chapter 3: Scripts 140
red1 Sets the adjustment to be made to the red component of the particle colour per
second for the first state.
format: red <delta value>
example: red -0.1
default: 0
green1 Sets the adjustment to be made to the green component of the particle colour
per second for the first state.
format: green <delta value>
example: green -0.1
default: 0
blue1 Sets the adjustment to be made to the blue component of the particle colour
per second for the first state.
format: blue <delta value>
example: blue -0.1
default: 0
alpha1 Sets the adjustment to be made to the alpha component of the particle colour
per second for the first state.
format: alpha <delta value>
example: alpha -0.1
default: 0
red2 Sets the adjustment to be made to the red component of the particle colour per
second for the second state.
format: red <delta value>
example: red -0.1
default: 0
green2 Sets the adjustment to be made to the green component of the particle colour
per second for the second state.
format: green <delta value>
example: green -0.1
default: 0
blue2 Sets the adjustment to be made to the blue component of the particle colour
per second for the second state.
format: blue <delta value>
example: blue -0.1
default: 0
alpha2 Sets the adjustment to be made to the alpha component of the particle colour
per second for the second state.
Chapter 3: Scripts 141
state change
When a particle has this much time left to live, it will switch to state 2.
format: state change <seconds>
example: state change 2
default: 1
To create a ColourFader2 affector, include a section like this within your particle system
script:
affector ColourFader2
{
// Settings go here
}
Scaler Affector
This affector scales particles in flight. It’s extra attributes are:
rate The amount by which to scale the particles in both the x and y direction per
second.
To create a scale affector, include a section like this within your particle system script:
affector Scaler
{
// Settings go here
}
Rotator Affector
This affector rotates particles in flight. This is done by rotating the texture. It’s extra
attributes are:
rotation speed range start
The start of a range of rotation speeds to be assigned to emitted particles.
format: rotation speed range start <degrees per second>
example: rotation speed range start 90
default: 0
To create a rotate affector, include a section like this within your particle system script:
affector Rotator
{
// Settings go here
}
ColourInterpolator Affector
Similar to the ColourFader and ColourFader2 Affector?s, this affector modifies the colour
of particles in flight, except it has a variable number of defined stages. It swaps the particle
colour for several stages in the life of a particle and interpolates between them. It’s extra
attributes are:
time0 The point in time of stage 0.
format: time0 <0-1 based on lifetime>
example: time0 0
default: 1
[...]
The number of stages is variable. The maximal number of stages is 6; where time5 and
colour5 are the last possible parameters. To create a colour interpolation affector, include
a section like this within your particle system script:
affector ColourInterpolator
{
// Settings go here
}
ColourImage Affector
This is another affector that modifies the colour of particles in flight, but instead of pro-
grammatically defining colours, the colours are taken from a specified image file. The range
of colour values begins from the left side of the image and move to the right over the life-
time of the particle, therefore only the horizontal dimension of the image is used. Its extra
attributes are:
image The start of a range of rotation speed to be assigned to emitted particles.
format: image <image name>
example: image rainbow.png
default: none
To create a ColourImage affector, include a section like this within your particle system
script:
affector ColourImage
{
// Settings go here
}
DeflectorPlane Affector
This affector defines a plane which deflects particles which collide with it. The attributes
are:
plane point
A point on the deflector plane. Together with the normal vector it defines the
plane.
Chapter 3: Scripts 144
plane normal
The normal vector of the deflector plane. Together with the point it defines the
plane.
default: plane normal 0 1 0
DirectionRandomiser Affector
This affector applies randomness to the movement of the particles. Its extra attributes are:
randomness
The amount of randomness to introduce in each axial direction.
example: randomness 5
default: randomness 1
keep velocity
Determines whether the velocity of particles is unchanged.
example: keep velocity true
default: keep velocity false.
Chapter 3: Scripts 145
Format.
Chapter 3: Scripts 146
The element and container blocks are pretty identical apart from their ability to store nested
blocks.
type name
Must resolve to the name of a OverlayElement type which has been registered
with the OverlayManager. Plugins register with the OverlayManager to ad-
vertise their ability to create elements, and at this time advertise the name of
the type. OGRE comes preconfigured with types ’Panel’, ’BorderPanel’ and
’TextArea’.
instance name
Must be a name unique among all other elements / containers by which to
identify the element. Note that you can obtain a pointer to any named element
by calling OverlayManager::getSingleton().getOverlayElement(name).
template name
Optional template on which to base this item. See templates.
The properties which can be included within the braces depend on the custom type.
However the following are always valid:
• [metrics mode], page 149
• [horz align], page 149
• [vert align], page 150
• [left], page 150
• [top], page 151
• [width], page 151
• [height], page 151
• [overlay material], page 152
• [caption], page 152
Chapter 3: Scripts 147
Templates sub-
classed and instantiated. Using the template keyword for the children of a template is
optional but recommended for clarity, as the children of a template are always going to be
templates themselves.
The above example uses templates to define a button. Note that the button template
inherits from the borderPanel template. This reduces the number of attributes needed to
instantiate a button.
Also note that the instantiate of a Button needs a template name for the caption at-
tribute. So templates can also be used by elements that need dynamic creation of children
elements (the button creates a TextAreaElement in this case for its caption).
See Section 3.4.1 [OverlayElement Attributes], page 149, Section 3.4.2 [Standard Over-
layElements], page 153
metrics mode
Sets the units which will be used to size and position this element.
This can be used to change the way that all measurement attributes in the rest of this
element are interpreted. In relative mode, they are interpreted as being a parametric value
from 0 to 1, as a proportion of the width / height of the screen. In pixels mode, they are
simply pixel offsets.
horz align
Sets the horizontal alignment of this element, in terms of where the horizontal origin is.
This can be used to change where the origin is deemed to be for the purposes of any
horizontal positioning attributes of this element. By default the origin is deemed to be the
Chapter 3: Scripts 150
left edge of the screen, but if you change this you can center or right-align your elements.
Note that setting the alignment to center or right does not automatically force your elements
to appear in the center or the right edge, you just have to treat that point as the origin
and adjust your coordinates appropriately. This is more flexible because you can choose to
position your element anywhere relative to that origin. For example, if your element was
10 pixels wide, you would use a ’left’ property of -10 to align it exactly to the right edge,
or -20 to leave a gap but still make it stick to the right edge.
Note that you can use this property in both relative and pixel modes, but it is most
useful in pixel mode.
vert align
Sets the vertical alignment of this element, in terms of where the vertical origin is.
This can be used to change where the origin is deemed to be for the purposes of any
vertical positioning attributes of this element. By default the origin is deemed to be the
top edge of the screen, but if you change this you can center or bottom-align your elements.
Note that setting the alignment to center or bottom does not automatically force your
elements to appear in the center or the bottom edge, you just have to treat that point as
the origin and adjust your coordinates appropriately. This is more flexible because you
can choose to position your element anywhere relative to that origin. For example, if your
element was 50 pixels high, you would use a ’top’ property of -50 to align it exactly to the
bottom edge, or -70 to leave a gap but still make it stick to the bottom edge.
Note that you can use this property in both relative and pixel modes, but it is most
useful in pixel mode.
left
Sets the horizontal position of the element relative to it’s parent.
Chapter 3: Scripts 151
Positions are relative to the parent (the top-left of the screen if the parent is an overlay,
the top-left of the parent otherwise) and are expressed in terms of a proportion of screen
size. Therefore 0.5 is half-way across the screen.
Default: left 0
top
Sets the vertical position of the element relative to it’s parent.
Positions are relative to the parent (the top-left of the screen if the parent is an overlay,
the top-left of the parent otherwise) and are expressed in terms of a proportion of screen
size. Therefore 0.5 is half-way down the screen.
Default: top 0
width
Sets the width: width 1
Chapter 3: Scripts 152
height
Sets the height: height 1
material
Sets the name of the material to use for this element.
This sets the base material which this element will use. Each type of element may inter-
pret this differently; for example the OGRE element ’Panel’ treats this as the background
of the panel, whilst ’BorderPanel’ interprets this as the material for the center area only.
Materials should be defined in .material scripts.
Note that using a material in an overlay element automatically disables lighting and depth
checking on this material. Therefore you should not use the same material as is used for
real 3D objects for an overlay.
Default: none
caption
Sets a text caption for the element.
Not all elements support captions, so each element is free to disregard this if it wants.
However, a general text caption is so common to many elements that it is included in the
generic interface to make it simpler to use. This is a common feature in GUI systems.
Default: blank
rotation
Sets the rotation of the element.
Format: rotation <angle in degrees> <axis x> <axis y> <axis z> Example: rotation 30
001
Default: none
This section describes how you define their custom attributes in an .overlay script, but
you can also change these custom properties in code if you wish. You do this by calling
setParameter(paramname, value). You may wish to use the StringConverter class to convert
your types to and from strings.
Panel (container):
transparent <true | false>
If set to ’true’ the panel is transparent and is not rendered itself, it is just used
as a grouping level for it’s children.
tiling <layer> <x tile> <y tile>
Sets the number of times the texture(s) of the material are tiled across the panel
in the x and y direction. <layer> is the texture layer, from 0 to the number of
Chapter 3: Scripts 154
texture layers in the material minus one. By setting tiling per layer you can
create some nice multitextured backdrops for your panels, this works especially
well when you animate one of the layers.
uv coords <topleft u> <topleft v> <bottomright u> <bottomright v>
Sets the texture coordinates to use for this panel.
BorderPanel (container):
border size <left> <right> <top> <bottom>
The size of the border at each edge, as a proportion of the size of the screen.
This lets you have different size borders at each edge if you like, or you can use
the same value 4 times to create a constant size border.
border material <name>.
border topleft uv <u1> <v1> <u2> <v2>
.
border left uv <u1> <v1> <u2> <v2>
[also border right uv, border top uv, border bottom uv]; The texture coordi-
nates.
TextArea (element)
This is a generic element that you can use to render text. It uses fonts which can be defined
in code using the FontManager and Font classes, or which have been predefined in .fontdef
files. See the font definitions section for more information.
Chapter 3: Scripts 155
Attributes:
font name <name>
The name of the font to use. This font must be defined in a .fontdef file to
ensure it is available at scripting time.
char height <height>
The height of the letters as a proportion of the screen height. Character widths
may vary because OGRE supports proportional fonts, but will be based on this
constant height.
colour <red> <green> <blue>.
colour bottom <red> <green> <blue> / colour top <red> <green> <blue>
As an alternative to a solid colour, you can colour the text differently at the
top and bottom to create a gradient colour effect which can be very effective.
alignment <left | center | right>
Sets the horizontal alignment of the text. This is different from the horz align
parameter.
space width <width>
Sets the width of a space in relation to the screen.
All font definitions are held in .fontdef files, which are parsed by the system at startup
time. Each .fontdef file can contain multiple font definitions. The basic format of an entry
in the .fontdef file is:
Chapter 3: Scripts 156
<font_name>
{
type <image | truetype>
source <image file | truetype font file>
...
... custom attributes depending on type
}
You can also create new fonts at runtime by using the FontManager if you wish.
Chapter 4: Mesh Tools 158
4 Mesh Tools
There are a number of mesh tools available with OGRE to help you manipulate your meshes.
4.1 Exporters
Exporters are plugins to 3D modelling tools which write meshes and skeletal animation to
file formats which OGRE can use for realtime rendering. The files the exporters write end
in .mesh and .skeleton respectively.
Each exporter has to be written specifically for the modeller in question, although they all
use a common set of facilities provided by the classes MeshSerializer and SkeletonSerializer.
They also normally require you to own the modelling tool.
All the exporters here can be built from the source code, or you can download precom-
piled versions from the OGRE web site.
If you’re creating unanimated meshes, then you do not need to be concerned with the
above.
Full documentation for each exporter is provided along with the exporter itself,
and there is a list of the currently supported modelling tools in the OGRE Wiki at.
Chapter 4: Mesh Tools 159
4.2 XmlConverter
The OgreXmlConverter tool can converter binary .mesh and .skeleton files to XML and back
again - this is a very useful tool for debugging the contents of meshes, or for exchanging
mesh data easily - many of the modeller mesh exporters export to XML because it is simpler
to do, and OgreXmlConverter can then produce a binary from it., you will be prompted to (re)generate level-of-
detail(LOD) information for the mesh - you can choose to skip this part if you wish, but
doing it will allow you to make your mesh reduce in detail automatically when it is loaded
into the engine. The engine uses a complex algorithm to determine the best parts of the
mesh to reduce in detail depending on many factors such as the curvature of the surface,
the edges of the mesh and seams at the edges of textures and smoothing groups - taking
advantage of it is advised to make your meshes more scalable in real scenes.
4.3 MeshUpgrader
This tool is provided to allow you to upgrade your meshes when the binary format changes
- sometimes we alter it to add new features and as such you need to keep your own assets
up to date. This tools has a very simple syntax:
OgreMeshUpgrade <oldmesh> <newmesh>
The OGRE release notes will notify you when this is necessary with a new release.
Chapter 5: Hardware Buffers 160
5 Hardware Buffers
Vertex buffers, index buffers and pixel buffers inherit most of their features from the Hard-
wareBuffer class. The general premise with a hardware buffer is that it is an area of memory
with which you can do whatever you like; there is no format (vertex or otherwise) associated
with the buffer itself - that is entirely up to interpretation by the methods that use it - in
that way, a HardwareBuffer is just like an area of memory you might allocate using ’malloc’
- the difference being that this memory is likely to be located in GPU or AGP memory.
For example:
VertexDeclaration* decl = HardwareBufferManager::getSingleton().createVertexDeclaration();
HardwareVertexBufferSharedPtr vbuf =
HardwareBufferManager::getSingleton().createVertexBuffer(
3*sizeof(Real), // size of one whole vertex
numVertices, // number of vertices
HardwareBuffer::HBU_STATIC_WRITE_ONLY, // usage
false); // no shadow buffer
Don’t worry about the details of the above, we’ll cover that in the later sections. The im-
portant thing to remember is to always create objects through the HardwareBufferManager,
don’t use ’new’ (it won’t work anyway in most cases).
The most optimal type of hardware buffer is one which is not updated often, and is never
read from. The usage parameter of createVertexBuffer or createIndexBuffer can be one of
the following:
Chapter 5: Hardware Buffers 161 5.3 [Shadow Buffers], page 161). 5.3 [Shadow Buffers], page 161). ex-
tremely.
when you write data into this buffer, it will first update the system memory copy, then it
will update the hardware buffer, as separate copying process - therefore this technique has
an additional overhead when writing data. Don’t use it unless you really need it.
Lock parameters
Chapter 5: Hardware Buffers 163 5.6 [Hardware Vertex Buffers], page 163 and See Section 5.7 [Hardware
Index Buffers], page 168
It’s worth noting that you don’t necessarily have to use VertexData to store your applica-
tions geometry; all that is required is that you can build a VertexData structure when it
comes to rendering. This is pretty easy since all of VertexData’s members are pointers, so
you could maintain your vertex buffers and declarations in alternative structures if you like,
so long as you can convert them for rendering.
To add an element to a VertexDeclaration, you call it’s addElement method. The parameters
to this method are:
source This tells the declaration which buffer the element is to be pulled from. Note
that this is just an index, which may range from 0 to one less than the number
of buffers which are being bound as sources of vertex data. See Section 5.6.3
Chapter 5: Hardware Buffers 165
[Vertex Buffer Bindings], page 166 for information on how a real buffer is bound
to a source index. Storing the source of the vertex element this way (rather
than using a buffer pointer) allows you to rebind the source of a vertex very
easily, without changing the declaration of the vertex format itself.
offset.
type
outuputs. This part of the element definition covers the basic type and size,
e.g. VET FLOAT3 is 3 floating point numbers - the meaning of the data is
dealt with in the next paramter.
semantic.
index.
Important Considerations
Whilst in theory you have completely full reign over the format of you vertices, in reality
there are some restrictions. Older DirectX hardware imposes a fixed ordering on the ele-
ments which are pulled from each buffer; specifically any hardware prior to DirectX 9 may
impose the following restrictions:
• VertexElements should be added in the following order, and the order of the elements
within any shared buffer should be as follows:
1. Positions
2. Blending weights
3. Normals
4. Diffuse colours
5. Specular colours
6. Texture coordinates (starting at 0, listed in order, with no gaps)
Chapter 5: Hardware Buffers 166
• You must not have unused gaps in your buffers which are not referenced by any Ver-
texElement
• You must not cause the buffer & offset settings of 2 VertexElements to overlap!
usage This tells the system how you intend to use the buffer. See Section 5.2 [Buffer
Usage], page 160
useShadowBuffer
Tells the system whether you want this buffer backed by a system-memory copy.
See Section 5.3 [Shadow Buffers], page 161
There are also methods for retrieving buffers from the binding data - see the API reference
for full details.
Lets start with a vert simple example. Lets say you have a buffer which only contains vertex
positions, so it only contains sets of 3 floating point numbers per vertex. In this case, all
you need to do to write data into it is:
Real* pReal = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
... then you just write positions in chunks of 3 reals. If you have other floating point
data in there, it’s a little more complex but the principle is largely the same, you just need
to write alternate elements. But what if you have elements of different types, or you need
to derive how to write the vertex data from the elements themselves? Well, there are some
useful methods on the VertexElement class to help you out.
Firstly, you lock the buffer but assign the result to a unsigned char* rather than
a specific type. Then, for each element whcih is sourcing from this buffer (which
you can find out by calling VertexDeclaration::findElementsBySource) you call
VertexElement::baseVertexPointerToElement. This offsets a pointer which points at the
base of a vertex in a buffer to the beginning of the element in question, and allows you to
use a pointer of the right type to boot. Here’s a full example:
// Get base pointer
unsigned char* pVert = static_cast<unsigned char*>(vbuf->lock(HardwareBuffer::HBL_READ_ONLY)
Real* pReal;
for (size_t v = 0; v < vertexCount; ++v)
{
// Get elements
VertexDeclaration::VertexElementList elems = decl->findElementsBySource(bufferIdx);
Chapter 5: Hardware Buffers 168
VertexDeclaration::VertexElementList::iterator i, iend;
for (i = elems.begin(); i != elems.end(); ++i)
{
VertexElement& elem = *i;
if (elem.getSemantic() == VES_POSITION)
{
elem.baseVertexPointerToElement(pVert, &pReal);
// write position using pReal
...
}
pVert += vbuf->getVertexSize();
}
vbuf->unlock();
See the API docs for full details of all the helper methods on VertexDeclaration and
VertexElement to assist you in manipulating vertex buffer data pointers.
5.8.1 Textures
A texture is an image that can be applied onto the surface of a three dimensional model.
In Ogre, textures are represented by the Texture resource class.
Chapter 5: Hardware Buffers 170
Creating a texture
Textures are created through the TextureManager. In most cases they are created from
image files directly by the Ogre resource system. If you are reading this, you most probably
want to create a texture manually so that you can provide it with image data yourself. This
is done through TextureManager::createManual:
ptex = TextureManager::getSingleton().createManual(
"MyManualTexture", // Name of texture
"General", // Name of resource group in which the texture should be created
TEX_TYPE_2D, // Texture type
256, // Width
256, // Height
1, // Depth (Must be 1 for two dimensional textures)
0, // Number of mipmaps
PF_A8R8G8B8, // Pixel format
TU_DYNAMIC_WRITE_ONLY // usage
);
This example creates a texture named MyManualTexture in resource group General. It
is a square two dimensional texture, with width 256 and height 256. It has no mipmaps,
internal format PF A8R8G8B8 and usage TU DYNAMIC WRITE ONLY.
The different texture types will be discussed in Section 5.8.3 [Texture Types], page 172.
Pixel formats are summarised in Section 5.8.4 [Pixel Formats], page 173.
Texture usages
In addition to the hardware buffer usages as described in See Section 5.2 [Buffer Usage],
page 160 there are some usage flags specific to textures:
TU AUTOMIPMAP
Mipmaps for this texture will be automatically generated by the graphics hard-
ware. The exact algorithm used is not defined, but you can assume it to be a
2x2 box filter.
TU RENDERTARGET
This texture will be a render target, ie. used as a target for render to texture.
Setting this flag will ignore all other texture usages except TU AUTOMIPMAP.
TU DEFAULT
This is actualy a combination of usage flags, and is equivalent to
TU AUTOMIPMAP | TU STATIC WRITE ONLY. The resource system
uses these flags for textures that are loaded from images.
Getting a PixelBuffer
A Texture can consist of multiple PixelBuffers, one for each combo if mipmap level and face
number. To get a PixelBuffer from a Texture object the method Texture::getBuffer(face,
mipmap) is used:
face should be zero for non-cubemap textures. For cubemap textures it identifies the
face to use, which is one of the cube faces described in See Section 5.8.3 [Texture Types],
page 172.
Chapter 5: Hardware Buffers 171
mipmap is zero for the zeroth mipmap level, one for the first mipmap level, and so on.
On textures that have automatic mipmap generation (TU AUTOMIPMAP) only level 0
should be accessed, the rest will be taken care of by the rendering API.
A simple example of using getBuffer is
// Get the PixelBuffer for face 0, mipmap 0.
HardwarePixelBufferSharedPtr ptr = tex->getBuffer(0,0);
blitFromMemory
The easy method to get an image into a PixelBuffer is by using HardwarePixel-
Buffer::blitFromMemory. This takes a PixelBox object and does all necessary pixel format
conversion and scaling for you. For example, to create a manual texture and load an image
into it, all you have to do is
// Manually loads an image and puts the contents in a manually created texture
Image img;
img.load("elephant.png", "General");
// Create RGB texture with 5 mipmaps
TexturePtr tex = TextureManager::getSingleton().createManual(
"elephant",
"General",
TEX_TYPE_2D,
img.getWidth(), img.getHeight(),
5, PF_X8R8G8B8);
// Copy face 0 mipmap 0 of the image to face 0 mipmap 0 of the texture.
tex->getBuffer(0,0)->blitFromMemory(img.getPixelBox(0,0));
{
for(size_t x=0; x<width; ++x)
{
// 0xRRGGBB -> fill the buffer with yellow pixels
data[pitch*y + x] = 0x00FFFF00;
}
}
/// Unlock the buffer again (frees it for use by the GPU)
buffer->unlock();
Colour channels).
Chapter 5: Hardware Buffers 174.
data The pointer to the first component of the image data in memory.
format The pixel format (See Section 5.8.4 [Pixel Formats], page 173) of the image
data.
rowPitch The number of elements between the leftmost pixel of one row and the left pixel
of the next. This value must always be equal to getWidth() (consecutive) for
compressed formats.
slicePitch The number of elements between the top left pixel of one (depth) slice and
the top left pixel of the next. Must be a multiple of rowPitch. This value
must always be equal to getWidth()*getHeight() (consecutive) for compressed
formats.
left, top, right, bottom, front, backWidth()
Get the width of this box
getHeight()
Get the height of this box. This is 1 for one dimensional images.
getDepth()
Get the depth of this box. This is 1 for one and two dimensional images.
setConsecutive()
Set the rowPitch and slicePitch so that the buffer is laid out consecutive in
memory.
getRowSkip()
Get the number of elements between one past the rightmost pixel of one row
and the leftmost pixel of the next row. This is zero if rows are consecutive.
getSliceSkip()
Get the number of elements between one past the right bottom pixel of one slice
and the left top pixel of the next slice. This is zero if slices are consecutive.
isConsecutive()
Return whether this buffer is laid out consecutive in memory (ie the pitches are
equal to the dimensions)
getConsecutiveSize()
Return the size (in bytes) this image would take if it was laid out consecutive
in memory
getSubVolume(const Box &def)
Return a subvolume of this PixelBox, as a PixelBox.
For more information about these methods consult the API documentation.
Chapter 6: External Texture Sources 176
Introduction
This tutorial will provide a brief introduction of ExternalTextureSource and ExternalTex-
tureSourceManager classes, their relationship, and how the PlugIns work. For those inter-
ested in developing a Texture Source Plugin or maybe just wanting to know more about
this system, take a look the ffmpegVideoSystem plugin, which you can find more about on
the OGRE forums..
ExternalTextureSource Class
The ExternalTextureSource class is the base class that Texture Source PlugIns must be de-
rived from. It provides a generic framework (via StringInterface class) with a very limited
amount of functionality. The most common of parameters can be set through the Tex-
turePlugInSource class interface or via the StringInterface commands contained within this
class. While this may seem like duplication of code, it is not. By using the string command
interface, it becomes extremely easy for derived plugins to add any new types of parameters
that it may need.
• Parameter Name: "frames per second" Argument Type: Ogre::String Set a Frames
per second update speed. (Integer Values only)
ExternalTextureSourceManager ClassTex-
tureSourceManager:
• Obviously, the first step is to have the desired plugin included in plugin.cfg for it to be
loaded.
• Set the desired PlugIn as Active via AdvancedTextureManager::getSingleton().SetCurrentPlugIn(
String Type ); – type is whatever the plugin registers as handling (e.g. "video",
"flash", "whatever", etc).
• Note: Consult Desired PlugIn to see what params it needs/expects. Set
params/value pairs via AdvancedTextureManager::getSingleton().getCurrentPlugIn()-
>setParameter( String Param, String Value );
• After required params are set, a simple call to AdvancedTextureManager::getSingleton().getCurrentPlugIn(
>createDefinedTexture( sMaterialName ); will create a texture to the material name
given.
The manager also provides a method for deleting a texture source material: Advanced-
TextureManager::DestroyAdvancedTexture( String sTextureName ); The destroy method
works by broadcasting the material name to all loaded TextureSourcePlugIns, and the Plu-
gIn.
7 Shadows
Shadows are clearly an important part of rendering a believable scene - they provide a more
tangible feel to the objects in the scene, and aid the viewer in understanding the spatial
relationship between objects. Unfortunately, shadows are also one of the most challenging
aspects of 3D rendering, and they are still very much an active area of research. Whilst there
are many techniques to render shadows, none is perfect and they all come with advantages
and disadvantages. For this reason, Ogre provides multiple shadow implementations, with
plenty of configuration settings, so you can choose which technique is most appropriate for
your scene.
Shadow implementations fall into basically 2 broad categories: Section 7.1 [Stencil Shad-
ows], page 181 and Section 7.2 [Texture-based Shadows], page 185. This describes the
method by which the shape of the shadow is generated. In addition, there is more than one
way to render the shadow into the scene: Section 7.3 [Modulative Shadows], page 190, which
darkens the scene in areas of shadow, and Section 7.4 [Additive Light Masking], page 191
which by contrast builds up light contribution in areas which are not in shadow. You also
have the option of [Integrated Texture Shadows], page 189 which gives you complete control
over texture shadow application, allowing for complex single-pass shadowing shaders. Ogre
supports all these combinations.
Enabling shadows
Shadows are disabled by default, here’s how you turn them on and configure them in the
general sense:
1. Enable a shadow technique on the SceneManager as the first thing you doing your
scene setup. It is important that this is done first because the shadow technique can
alter the way meshes are loaded. Here’s an example:
mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
2. Create one or more lights. Note that not all light types are necessarily supported by
all shadow techniques, you should check the sections about each technique to check.
Note that if certain lights should not cast shadows, you can turn that off by calling
setCastShadows(false) on the light, the default is true.
3. Disable shadow casting on objects which should not cast shadows. Call setCastShad-
ows(false) on objects you don’t want to cast shadows, the default for all objects is to
cast shadows.
4. Configure shadow far distance. You can limit the distance at which shadows are con-
sidered for performance reasons, by calling SceneManager::setShadowFarDistance.
5. Turn off the receipt of shadows on materials that should not receive them. You can
turn off the receipt of shadows (note, not the casting of shadows - that is done per-
object) by calling Material::setReceiveShadows or using the receive shadows material
attribute. This is useful for materials which should be considered self-illuminated for
example. Note that transparent materials are typically excluded from receiving and
Chapter 7: Shadows 181
casting shadows, although see the [transparency casts shadows], page 20 option for
exceptions.
In order to generate the stencil, ’shadow volumes’ are rendered by extruding the silhou-
ette of the shadow caster away from the light. Where these shadow volumes intersect other
objects (or the caster, since self-shadowing is supported using this technique), the stencil
is updated, allowing subsequent operations to differentiate between light and shadow. How
Chapter 7: Shadows 182
exactly this is used to render the shadows depends on whether Section 7.3 [Modulative
Shadows], page 190 or Section 7.4 [Additive Light Masking], page 191 is being used. Ob-
jects can both cast and receive stencil shadows, so self-shadowing is inbuilt.
The advantage of stencil shadows is that they can do self-shadowing simply on low-
end hardware, provided you keep your poly count under control. In contrast doing self-
shadowing with texture shadows requires a fairly modern machine (See Section 7.2 [Texture-
based Shadows], page 185). For this reason, you’re likely to pick stencil shadows if you need
an accurate shadowing solution for an application aimed at older or lower-spec machines.
The disadvantages of stencil shadows are numerous though, especially on more modern
hardware. Because stencil shadows are a geometric technique, they are inherently more
costly the higher the number of polygons you use, meaning you are penalized the more
detailed you make your meshes. The fillrate cost, which comes from having to render
shadow volumes, also escalates the same way. Since more modern applications are likely to
use higher polygon counts, stencil shadows can start to become a bottleneck. In addition,
the visual aspects of stencil shadows are pretty primitive - your shadows will always be
hard-edged, and you have no possibility of doing clever things with shaders since the stencil
is not available for manipulation there. Therefore, if your application is aimed at higher-
end machines you should definitely consider switching to texture shadows (See Section 7.2
[Texture-based Shadows], page 185).
There are a number of issues to consider which are specific to stencil shadows:
• [CPU Overhead], page 182
• [Extrusion distance], page 183
• [Camera far plane positioning], page 183
• [Mesh edge lists], page 183
• [The Silhouette Edge], page 183
• [Be realistic], page 184
• [Stencil Optimisations Performed By Ogre], page 184
CPU Overhead
Calculating the shadow volume for a mesh can be expensive, and it has to be done on the
CPU, it is not a hardware accelerated feature. Therefore, you can find that if you overuse
this feature, you can create a CPU bottleneck for your application. Ogre quite aggressively
eliminates objects which cannot be casting shadows on the frustum, but there are limits
to how much it can do, and large, elongated shadows (e.g. representing a very low sun
position) are very difficult to cull efficiently. Try to avoid having too many shadow casters
around at once, and avoid long shadows if you can. Also, make use of the ’shadow far
distance’ parameter on the SceneManager, this can eliminate distant shadow casters from
the shadow volume construction and save you some time, at the expense of only having
shadows for closer objects. Lastly, make use of Ogre’s Level-Of-Detail (LOD) features; you
can generate automatically calculated LODs for your meshes in code (see the Mesh API
Chapter 7: Shadows 183
docs) or when using the mesh tools such as OgreXmlConverter and OgreMeshUpgrader.
Alternatively, you can assign your own manual LODs by providing alternative mesh files at
lower detail levels. Both methods will cause the shadow volume complexity to decrease as
the object gets further away, which saves you valuable volume calculation time.
Extrusion distance
When vertex programs are not available, Ogre can only extrude shadow volumes a finite
distance from the object. If an object gets too close to a light, any finite extrusion dis-
tance will be inadequate to guarantee all objects will be shadowed properly by this object.
Therefore, you are advised not to let shadow casters pass too close to light sources if you
can avoid it, unless you can guarantee that your target audience will have vertex program
capable hardware (in this case, Ogre extrudes the volume to infinity using a vertex program
so the problem does not occur).
When infinite extrusion is not possible, Ogre uses finite extrusion, either derived from the
attenuation range of a light (in the case of a point light or spotlight), or a fixed extrusion
distance set in the application in the case of directional lights. To change the directional
light extrusion distance, use SceneManager::setShadowDirectionalLightExtrusionDistance.
or more lights in a scene using modulative stencil shadows is not advisable; the silhouette
edges will be very marked. Additive lights do not suffer from this as badly because each
light is masked individually, meaning that it is only ambient light which can show up the
silhouette edges.
Be realistic
Don’t expect to be able to throw any scene using any hardware at the stencil shadow
algorithm and expect to get perfect, optimum speed results. Shadows are a complex and
expensive technique, so you should impose some reasonable limitations on your placing of
lights and objects; they’re not really that restricting, but you should be aware that this is
not a complete free-for-all.
• Try to avoid letting objects pass very close (or even through) lights - it might look nice
but it’s one of the cases where artifacts can occur on machines not capable of running
vertex programs.
• Be aware that shadow volumes do not respect the ’solidity’ of the objects they pass
through, and if those objects do not themselves cast shadows (which would hide the
effect) then the result will be that you can see shadows on the other side of what should
be an occluding object.
• Make use of SceneManager::setShadowFarDistance to limit the number of shadow vol-
umes constructed
• Make use of LOD to reduce shadow volume complexity at distance
• Avoid very long (dusk and dawn) shadows - they exacerbate other issues such as volume
clipping, fillrate, and cause many more objects at a greater distance to require volume
construction.
The main disadvantage to texture shadows is that, because they are simply a texture,
they have a fixed resolution which means if stretched, the pixellation of the texture can
become obvious. There are ways to combat this though:
Chapter 7: Shadows 186
Directional Lights
Directional lights in theory shadow the entire scene from an infinitely distant light. Now,
since we only have a finite texture which will look very poor quality if stretched over the
entire scene, clearly a simplification is required. Ogre places a shadow texture over the area
immediately in front of the camera, and moves it as the camera moves (although it rounds
this movement to multiples of texels so that the slight ’swimming shadow’ effect caused
by moving the texture is minimised). The range to which this shadow extends, and the
offset used to move it in front of the camera, are configurable (See [Configuring Texture
Shadows], page 187). At the far edge of the shadow, Ogre fades out the shadow based on
other configurable parameters so that the termination of the shadow is softened.
Spotlights
Spotlights are much easier to represent as renderable shadow textures than directional
lights, since they are naturally a frustum. Ogre represents spotlight directly by rendering
the shadow from the light position, in the direction of the light cone; the field-of-view of
Chapter 7: Shadows 187
the texture camera is adjusted based on the spotlight falloff angles. In addition, to hide the
fact that the shadow texture is square and has definite edges which could show up outside
the spotlight, Ogre uses a second texture unit when projecting the shadow onto the scene
which fades out the shadow gradually in a projected circle around the spotlight.
Point Lights
As mentioned above, to support point lights properly would require multiple renders (either
6 for a cubic render or perhaps 2 for a less precise parabolic mapping), so rather than do
that we approximate point lights as spotlights, where the configuration is changed on the
fly to make the light shine from its position over the whole of the viewing frustum. This is
not an ideal setup since it means it can only really work if the point light’s position is out
of view, and in addition the changing parameterisation can cause some ’swimming’ of the
texture. Generally we recommend avoiding making point lights cast texture shadows.
If you’re not using depth shadow mapping, OGRE divides shadow casters and receivers into
2 disjoint groups. Simply by turning off shadow casting on an object, you automatically
make it a shadow receiver (although this can be disabled by setting the ’receive shadows’
option to ’false’ in a material script. Similarly, if an object is set as a shadow caster, it
cannot receive shadows.
You can adjust this manually by simply turning off shadow casting for lights you do not
wish to cast shadows. In addition, you can set a maximum limit on the number of shadow
textures Ogre is allowed to use by calling SceneManager::setShadowTextureCount. Each
frame, Ogre determines the lights which could be affecting the frustum, and then allocates
the number of shadow textures it is allowed to use to the lights on a first-come-first-served
basis. Any additional lights will not cast shadows that frame.
Note that you can set the number of shadow textures and their size at the same time by
using the SceneManager::setShadowTextureSettings method; this is useful because both the
individual calls require the potential creation / destruction of texture resources.
Important: if you use the GL render system your shadow texture size can only be larger
(in either dimension) than the size of your primary window surface if the hardware
supports the Frame Buffer Object (FBO) or Pixel Buffer Object (PBO) extensions. Most
modern cards support this now, but be careful of older cards - you can check the ability of
the hardware to manage this through ogreRoot->getRenderSystem()->getCapabilities()-
>hasCapability(RSC HWRENDER TO TEXTURE). If this returns false, if you create a
shadow texture larger in any dimension than the primary surface, the rest of the shadow
texture will be blank.
value, or increasing the texture size, you can improve the quality of shadows from directional
lights at the expense of closer shadow termination or increased memory usage, respectively.
Here is where ’integrated’ texture shadows step in. Both of the texture shadow types
above have alternative versions called SHADOWTYPE TEXTURE MODULATIVE INTEGRATED
and SHADOWTYPE TEXTURE ADDITIVE INTEGRATED, where instead of rendering
the shadows for you, it just creates the texture shadow and then expects you to use that
shadow texture as you see fit when rendering receiver objects in the scene. The downside
is that you have to take into account shadow receipt in every one of your materials if you
use this option - the upside is that you have total control over how the shadow textures
are used. The big advantage here is that you can can perform more complex shading,
taking into account shadowing, than is possible using the generalised bolt-on approaches,
AND you can probably write them in a smaller number of passes, since you know precisely
what you need and can combine passes where possible. When you use one of these
shadowing approaches, the only difference between additive and modulative is the colour
of the casters in the shadow texture (the shadow colour for modulative, black for additive)
- the actual calculation of how the texture affects the receivers is of course up to you.
No separate modulative pass will be performed, and no splitting of your materials into
ambient / per-light / decal etc will occur - absolutely everything is determined by your
original material (which may have modulative passes or per-light iteration if you want of
course, but it’s not required).
You reference a shadow texture in a material which implements this approach by using
the ’[content type], page 51 shadow’ directive in your {texture unit. It implicitly references
a shadow texture based on the number of times you’ve used this directive in the same pass,
and the light start option or light-based pass iteration, which might start the light index
higher than 0.
Shadow Colour
The colour which is used to darken the areas in shadow is set by SceneMan-
ager::setShadowColour; it defaults to a dark grey (so that the underlying colour still shows
through a bit).
Note that if you’re using texture shadows you have the additional option of using
[Integrated Texture Shadows], page 189 rather than being forced to have a separate pass of
the scene to render shadows. In this case the ’modulative’ aspect of the shadow technique
just affects the colour of the shadow texture.
As many technical papers (and game marketing) will tell you, rendering realistic lighting
like this requires multiple passes. Being a friendly sort of engine, Ogre frees you from most
of the hard work though, and will let you use the exact same material definitions whether
you use this lighting technique or not (for the most part, see [Pass Classification and Vertex
Programs], page 193). In order to do this technique, Ogre automatically categorises the
Section 3.1.2 [Passes], page 24 you define in your materials into 3 types:
1. ambient Passes categorised as ’ambient’ include any base pass which is not lit by any
particular light, i.e. it occurs even if there is no ambient light in the scene. The
ambient pass always happens first, and sets up the initial depth value of the fragments,
Chapter 3: Scripts 192
and the ambient colour if applicable. It also includes any emissive / self illumination
contribution. Only textures which affect ambient light (e.g. ambient occlusion maps)
should be rendered in this pass.
2. diffuse/specular Passes categorised as ’diffuse/specular’ (or ’per-light’) are rendered
once per light, and each pass contributes the diffuse and specular colour from that
single light as reflected by the diffuse / specular terms in the pass. Areas in shadow
from that light are masked and are thus not updated. The resulting masked colour
is added to the existing colour in the scene. Again, no textures are used in this pass
(except for textures used for lighting calculations such as normal maps).
3. decal Passes categorised as ’decal’ add the final texture colour to the scene, which is
modulated by the accumulated light built up from all the ambient and diffuse/specular
passes.
In practice, Section 3.1.2 [Passes], page 24 rarely fall nicely into just one of these cate-
gories. For each Technique, Ogre compiles a list of ’Illumination Passes’, which are derived
from the user defined passes, but can be split, to ensure that the divisions between illumi-
nation pass categories can be maintained. For example, if we take a very simple material
definition:
material TestIllumination
{
technique
{
pass
{
ambient 0.5 0.2 0.2
diffuse 1 0 0
specular 1 0.8 0.8 15
texture_unit
{
texture grass.png
}
}
}
}
Ogre will split this into 3 illumination passes, which will be the equivalent of this:
material TestIlluminationSplitIllumination
{
technique
{
// Ambient pass
pass
{
ambient 0.5 0.2 0.2
diffuse 0 0 0
specular 0 0 0
}
Chapter 3: Scripts 193
// Decal pass
pass
{
scene_blend modulate
lighting off
texture_unit
{
texture grass.png
}
}
}
}.
In practice this is very easy. Even though your vertex program could be doing a lot
of complex, highly customised processing, it can still be classified into one of the 3 types
listed above. All you need to do to tell Ogre what you’re doing is to use the pass attributes
ambient, diffuse, specular and self illumination, just as if you were not using a vertex
program. Sure, these attributes do nothing (as far as rendering is concerned) when you’re
using vertex programs, but it’s the easiest way to indicate to Ogre which light components
you’re using in your vertex program. Ogre will then classify and potentially split your
programmable pass based on this information - it will leave the vertex program as-is (so
that any split passes will respect any vertex modification that is being done).
Note that when classifying a diffuse/specular programmable pass, Ogre checks to see
whether you have indicated the pass can be run once per light (iteration once per light).
If so, the pass is left intact, including it’s vertex and fragment programs. However, if this
attribute is not included in the pass, Ogre tries to split off the per-light part, and in doing
so it will disable the fragment program, since in the absence of the ’iteration once per light’
attribute it can only assume that the fragment program is performing decal work and hence
must not be used per light.
So clearly, when you use additive light masking as a shadow technique, you need to make
sure that programmable passes you use are properly set up so that they can be classified
correctly. However, also note that the changes you have to make to ensure the classification
is correct does not affect the way the material renders when you choose not to use additive
lighting, so the principle that you should be able to use the same material definitions for
all lighting scenarios still holds. Here is an example of a programmable material which will
be classified correctly by the illumination pass classifier:
// Per-pixel normal mapping Any number of lights, diffuse and specular
material Examples/BumpMapping/MultiLightSpecular
{
technique
{
// Base ambient pass
pass
{
// ambient only, not needed for rendering, but as information
// to lighting pass categorisation routine
ambient 1 1 1
diffuse 0 0 0
specular 0 0 0 0
// Really basic vertex program
vertex_program_ref Ogre/BasicVertexPrograms/AmbientOneTexture
{
Chapter 3: Scripts 195
}
// Now do the lighting pass
// NB we don’t do decal texture here because this is repeated per light
pass
{
// set ambient off, not needed for rendering, but as information
// to lighting pass categorisation routine
ambient 0 0 0
// do this for each light
iteration once_per_light
scene_blend add
// Fragment program
fragment_program_ref Examples/BumpMapFPSpecular
{
param_named_auto lightDiffuse light_diffuse_colour 0
param_named_auto lightSpecular light_specular_colour 0
}
texture_unit
{
cubic_texture nm.png combinedUVW
tex_coord_set 1
tex_address_mode clamp
}
}
// Decal pass
pass
{
lighting off
// Really basic vertex program
vertex_program_ref Ogre/BasicVertexPrograms/AmbientOneTexture
{
param_named_auto worldViewProj worldviewproj_matrix
param_named ambient float4 1 1 1 1
}
scene_blend dest_colour zero
texture_unit
{
texture RustedMetal.jpg
}
}
}
}
Note that if you’re using texture shadows you have the additional option of using
[Integrated Texture Shadows], page 189 rather than being forced to use this explicit se-
quence - allowing you to compress the number of passes into a much smaller number at the
expense of defining an upper number of shadow casting lights. In this case the ’additive’
aspect of the shadow technique just affects the colour of the shadow texture and it’s up to
you to combine the shadow textures in your receivers however you like.
Static Lighting
Despite their power, additive lighting techniques have an additional limitation; they do not
combine well with pre-calculated static lighting in the scene. This is because they are based
on the principle that shadow is an absence of light, but since static lighting in the scene
already includes areas of light and shadow, additive lighting cannot remove light to create
new shadows. Therefore, if you use the additive lighting technique you must either use
it exclusively as your lighting solution (and you can combine it with per-pixel lighting to
create a very impressive dynamic lighting solution), or you must use [Integrated Texture
Shadows], page 189 to combine the static lighting according to your chosen approach.
Chapter 8: Animation 197
8 Animation
OGRE supports a pretty flexible animation system that allows you to script animation for
several different purposes:
Section 8.1 [Skeletal Animation], page 197
Mesh animation using a skeletal structure to determine how the mesh deforms.
There are many grades of skeletal animation, and not all engines (or modellers for that
matter) support all of them. OGRE supports the following features:
• Each mesh can be linked to a single skeleton
• Unlimited bones per skeleton
• Hierarchical forward-kinematics on bones
• Multiple named animations per skeleton (e.g. ’Walk’, ’Run’, ’Jump’, ’Shoot’ etc)
• Unlimited keyframes per animation
• Linear or spline-based interpolation between keyframes
• A vertex can be assigned to multiple bones and assigned weightings for smoother skin-
ning
• Multiple animations can be applied to a mesh at the same time, again with a blend
weighting
Skeletons and the animations which go with them are held in .skeleton files, which are
Chapter 8: Animation 198
produced by the OGRE exporters. These files are loaded automatically when you create an
Entity based on a Mesh which is linked to the skeleton in question. You then use Section 8.2
[Animation State], page 198 to set the use of animation on the entity in question.
Skeletal animation can be performed in software, or implemented in shaders (hardware
skinning). Clearly the latter is preferable, since it takes some of the work away from the
CPU and gives it to the graphics card, and also means that the vertex data does not need
to be re-uploaded every frame. This is especially important for large, detailed models. You
should try to use hardware skinning wherever possible; this basically means assigning a ma-
terial which has a vertex program powered technique. See hundefinedi [Skeletal Animation
in Vertex Programs], page hundefinedi for more details. Skeletal animation can be com-
bined with vertex animation, See Section 8.3.3 [Combining Skeletal and Vertex Animation],
page 202.
Pose animation is more complex. Like morph animation each track references a single
unique set of vertex data, but unlike morph animation, each keyframe references 1 or more
’poses’, each with an influence level. A pose is a series of offsets to the base vertex data,
and may be sparse - i.e. it may not reference every vertex. Because they’re offsets, they
can be blended - both within a track and between animations. This set of features is very
well suited to facial animation.
For example, let’s say you modelled a face (one set of vertex data), and defined a set of
poses which represented the various phonetic positions of the face. You could then define
an animation called ’SayHello’, containing a single track which referenced the face vertex
data, and which included a series of keyframes, each of which referenced one or more of the
facial positions at different influence levels - the combination of which over time made the
face form the shapes required to say the word ’hello’. Since the poses are only stored once,
but can be referenced may times in many animations, this is a very powerful way to build
up a speech system.
Chapter 8: Animation 200
The downside of pose animation is that it can be more difficult to set up, requiring
poses to be separately defined and then referenced in the keyframes. Also, since it uses
more buffers (one for the base data, and one for each active pose), if you’re animating in
hardware using vertex shaders you need to keep an eye on how many poses you’re blending
at once. You define a maximum supported number in your vertex program definition,
via the includes pose animation material script entry, See hundefinedi [Pose Animation in
Vertex Programs], page hundefinedi.
So, by partitioning the vertex animation approaches into 2, we keep the simple morph
technique easy to use, whilst still allowing all the powerful techniques to be used. Note
that morph animation cannot be blended with other types of vertex animation on the same
vertex data (pose animation or other morph animation); pose animation can be blended
with other pose animation though, and both types can be combined with skeletal animation.
This combination limitation applies per set of vertex data though, not globally across the
mesh (see below). Also note that all morph animation can be expressed (in a more complex
fashion) as pose animation, but not vice versa.
For example, a common set-up for a complex character which needs both skeletal and
facial animation might be to split the head into a separate SubMesh with its own geometry,
then apply skeletal animation to both submeshes, and pose animation to just the head.
To see how to apply vertex animation, See Section 8.2 [Animation State], page 198.
To do this, you have a set of helper functions in Ogre::Mesh. See API Reference entries for
Ogre::VertexData::reorganiseBuffers() and Ogre::VertexDeclaration::getAutoOrganisedDeclaration().
The latter will turn a vertex declaration into one which is recommended for the usage
you’ve indicated, and the former will reorganise the contents of a set of buffers to conform
to that layout.
Chapter 8: Animation 201 8.3.3
[Combining Skeletal and Vertex Animation], page 202. Morph animation can also be im-
plemented in hardware using vertex shaders, See hundefinedi [Morph Animation in Vertex
Programs], page hundefinedi..
Chapter 8: Animation 202
You should be careful how many poses you apply at once. When performing pose
animation in hardware (See hundefinedi [Pose Animation in Vertex Programs], page hunde-
finedi), 8.3.3 [Combin-
ing Skeletal and Vertex Animation], page 202, and you can also hardware accelerate the
application of the blend with a vertex shader, See hundefinedi [Pose Animation in Vertex
Programs], page hundefinedi.
Combining the two is, from a user perspective, as simple as just enabling both animations
at the same time. When it comes to using this feature efficiently though, there are a few
points to bear in mind:
bullet [Combined Hardware Skinning], page 202
bullet [Submesh Splits], page 203
When combining animation types, your vertex programs must support both types of
animation that the combined mesh needs, otherwise hardware skinning will be disabled.
You should implement the animation in the same way that OGRE does, ie.
Chapter 8: Animation 203
Submesh Splits.
At it’s heart, scene node animation is mostly the same code which animates the under-
lying skeleton in skeletal animation. After creating the main Animation using SceneMan-
ager::createAnimation you can create a NodeAnimationTrack per SceneNode that you want
to animate, and create keyframes which control its position, orientation and scale which can
be interpolated linearly or via splines. You use Section 8.2 [Animation State], page 198 in the
same way as you do for skeletal/vertex animation, except you obtain the state from Scene-
Manager instead of from an individual Entity.Animations are applied automatically every
frame, or the state can be applied manually in advance using the applySceneAnimations()
method on SceneManager. See the API reference for full details of the interface for config-
uring scene animations.
AnimableObject
AnimableObject is an abstract interface that any class can extend in order to provide access
to a number of [AnimableValue], page 204s.
Chapter 8: Animation 204
property.
One example of this is the Light class. It extends AnimableObject and provides Ani-
m.
AnimableValue.