Table of Contents
Moo is a 3D engine using DirectX 9 that provides resource-, object- and device- based services up to, but not including the scene database.
Resource-based services include the generation and management of vertex buffers, index buffers, vertex shaders, pixel shaders, and effects. Textures are compressed and stored automatically. All resources that are not managed by Direct3D are managed by Moo, allowing for large amounts of data moving in and out of use.
Object-based services include a full animation system, skinned bipeds, compound skeletal geometrics, and specialised terrain rendering. Moo exposes the concept of a visual, an important mid-level geometric construct that sits beneath the scene database and greatly simplifies the scene database code.
Device-based services include level-of-detail control over rendering states, encapsulated in materials and shaders. The 3D window is encapsulated as a RenderContext, and provides frames-of-reference in which to render geometrics and store lighting states.
Finally, Moo provides the essential alpha-blended sorted triangle pipeline, a service that unfortunately is still not provided by Direct3D or directly in (most) hardware.
It is important to note that where possible, Moo uses underlying Direct3DX structures such as D3DXMatrix, D3DXVector, and D3DXQuaternion. The DirectX team continually improves the implementation of these mathematical classes, and their functionality often takes advantage of processor specific instructions, such as MMX, SIMD and 3DNow!. It is prudent to leverage the efforts of these engineers.
Some of the advanced features of Moo are listed below:
-
D3DXEffects vertex and pixel shader support
-
Cubic environment maps
-
Render targets
-
Lighting
-
Normal mapping/bump mapping
-
Terrain
-
Animation
-
Vertex morphing
The following sections describe these features.
Effect files are used extensively in Moo. Most of the rendering pipeline is based around the class EffectMaterial, which implements a way of managing the global values used by the effects, and also the per-instance data for the effects, such as textures, self-illumination values, and specular reflection constants.
The effect files also make it easier to manage pixel and vertex shaders, as they are created together in one file. Using the D3DXEffect format removes much of the complexities of adding new shader effects to the engine and allows rapid prototyping of new visual effects.
Cubic environment maps can be used for some reflections and for normalisation cube maps (used for normal mapping).
Render targets are used to create billboard textures. They can also be used in conjunction with the GUI components to display 3D objects in the 2D GUI (for example, for item selection previews).
The lighting component of Moo supports three different kinds of lights:
-
Directional lights.
-
Point lights.
-
Spot lights.
Any object can be lit by two directional lights, four point lights and two spot lights. These lights are picked according to an attenuation metric, so that generally the closest lights will be chosen. It is also important to note that the fewer lights used, the faster the execution of the lighting vertex shader will be.
The class bigworld/src/lib/romp/light_map.cpp is generalised to support both the flora and sky light maps. Light maps are configurable in XML files.
The flora light map details are specified in
flora.xml (for details on this file's grammar,
see the document File Grammar Guide's section
<flora>
.xml)
and its location is specified in the file
resources.xml (for details on this file, see
File resources.xml).
The material tag for flora light map should be system/materials/light_map.mfm (for details on this file's grammar, see the document File Grammar Guide's section .mfm).
The default width/height for the flora light map is 64x64. This is small, but still enough resolution for the projection onto the flora, because its visible area is 100x100 metres.

Definition of flora light map
The sky light map details are specified in the space's sky.xml file, and its location is specified in the space's space.settings file (for details on this file's grammar, see the document File Grammar Guide's section space.settings.).
The material tag for sky light map should be system/materials/sky_light_map.mfm (for details on this file's grammar, see the document File Grammar Guide's section .mfm).
The default width/height for the sky light map is 512x512. This is quite large because the light map is projected across the whole visible world (usually around 1x1 km).

Definition of sky light map
Note
The sky light map can be disabled via the SKY_LIGHT_MAP graphic setting (for details, see Customising options).
Normal mapping is used to add surface detail to objects by using per-texel normals baked into a texture. Moo currently supports normal maps for specular and diffuse lighting on dynamically lit objects, and specular lighting on statically lit objects. The current version of the Exporter supports tangent space normal mapping only.
Moo takes advantage of the multi-texture, vertex, and pixel shading capabilities of the supported graphics cards. Since it uses a blended 4-layered texturing system for the terrain, Moo utilises the hardware's four texture stages optimally so that most of the terrain can be rendered in just one pass. The terrain also supports self-shadowing from a directional light source.
Moo supports node-based and vertex-based (morph) animation. Moo can also blend animations together to provide smooth transitions between them.
Moo's vertex morphing is suitable for small changes in surfaces, such as facial animation. Morph targets are exported from the content creation package, and controlled through the normal animation system.
Please note that as morph targets are applied in software, extensive use will affect rendering performance.
The currently supported graphics cards are as follows:
-
NVIDIA
GeForce4 series, GeForce FX series, GeForce 6x00 series, GeForce 7x00 series cards and above.
-
ATI
Radeon 9000 series, and Radeon x000 series of cards.
Any graphics chip that supports at least Hardware Transform and Lighting and two texture stages should work, some with a limited subset of features enabled. These include (but are not limited to):
-
NVIDIA
GeForce3 series and GeForce GO 4 series cards.
-
ATI
Radeon 7000 series, Radeon 8000 series, Mobility 8000 and Mobility 9000 series.
The table below lists the special effects available in Moo, and their hardware requirements:
Special effect | Vertex shader version | Pixel shader version | Texture stages required |
---|---|---|---|
Bloom | 1.1 | 1.1 | 4 |
Cloud shadows | 1.1 | - | 3 |
Flora | 1.1 | - | 1 |
Heat Shimmer | 1.1 | - | 1 |
Normal mapping | 1.1 | 1.1 | 4 |
PyModel Shimmer | 1.1 | - | 1 |
PyModel stipple | 1.1 | 1.1 | 4 |
Entity shadows | 2.0 | 2.0 | 1 |
Simulated sub-surface scattering | 3.0 | 3.0 | 4 |
Sky Gradient dome | 1.1 | - | 3 |
Terrain shadows | 1.1 | 1.1 | 4 |
Terrain Specular | 1.1 | 1.1 | 4 |
Hardware requirements for special effects
The Visual class implements the basic renderable objects drawn by the 3D engine. A visual contains a node hierarchy, vertices, indices, and materials used for rendering objects, and it also contains a BSP tree used for collision detection.
The node hierarchy gives the renderable object a frame of reference when rendering objects. Visual uses the EffectMaterial, Primitives, and Vertices classes to render its geometry.
The material system in the BigWorld 3D engine uses D3DXEffects files extensively.
The material system is implemented through the class EffectMaterial, which contains one or more D3DX effects, their overridden values, and information about the collision properties and surface type of the material.
The idea behind the material system is to give as much control as possible to the artists, to allow them to experiment with new rendering techniques without involving programmers.
The format of the EffectMaterial on disk is very simple, having only a handful of sections, and with most of the work done through the .fx file.
Automatic variables are used for any variable that is controlled by the engine, such as transforms, lights, camera positions, etc... Automatic variables are exposed to Effect files using variable semantics.
In an Effect file, the automatic variables are defined like below:
<type
> <variableName
> : <semantic
>;
where:
-
<
type
>The variable type (float, bool, texture, etc.).
-
<
variableName
>Name used for the variable in the effect file.
-
<
semantic
>Name exposed to the engine.
The automatic variables are connected to the effect through the class EffectConstantValue. New automatic variables can be added by overriding the EffectConstantValue interface, implementing the operation (), and adding an instance of the new class using EffectConstantValue::set or using a handle returned from EffectConstantValue::get.
The automatic variables set up by Moo::EffectVisualContext are listed below:
-
Ambient (float4)
Current ambient colour.
-
CameraPos (float3)
Current camera position in world space.
-
CameraPosObjectSpace (float3)
Current camera position in object space.
-
DepthTex (texture)
The depth of the scene, stored encoded in a 32-bit RGBA texture. This is only available when the Advanced Post Processing graphics setting is switched on.
-
DirectionalLightCount (int)
Number of directional lights.
-
DirectionalLights (DirectionalLights[2])
Current diffuse directional lights in world space.
-
DirectionalLightsObjectSpace (DirectionalLights[2])
Current diffuse directional lights in object space.
-
EnvironmentCubeMap (texture)
Cube map containing a low-resolution dynamic cube map of the environment (sun, moon, sky gradient dome, sky boxes ).
-
EnvironmentTransform(float4x4)
Matrix used to transform environmental and skybox objects to the screen. Comes pre-multiplied with the projection matrix.
-
EnvironmentShadowTransform(float4x4)
Matrix used to transform environmental and skybox objects to the sky light map.
-
FarPlane (float)
Current far plane in metres.
-
FloraAnimationGrid (float4[64])
8x8 array of Perlin noise values used to animate the flora vertex buffer.
-
FloraTexture (texture)
The composite Flora texture map used by the FloraRenderer.
-
FogColour (float4)
Fog colour.
-
FogEnd (float)
End of linear fog.
-
FogGradientTexture (texture)
The fog texture used by the terrain renderer.
-
FogStart (float)
Start of linear fog.
-
FogTextureTransform (matrix)
Projects the fog texture onto the terrain.
-
GUIColour (float4)
Colour for use by the GUI.
-
LastViewProjection (float4x4)
The last frame's view*projection matrix.
-
InvView (float4x4)
Current inverse view matrix.
-
InvViewProjection (float4x4)
Current inverse view*projection matrix.
-
MipFilter (int)
Configurable MIPFILTER.
-
MinMagFilter (int)
Configurable MIN/ MAGFILTER.
-
MaxAnisotropy (int)
Configurable MAXANISOTROPY.
-
NearPlane (float)
Current near plane in metres.
-
NormalisationMap (texture)
Normalisation cubemap.
-
ObjectID (float)
Set to 1 when rendering a PyModel, aka a dynamic/entity model. Set to 0 for all other models. In future, this may expand to designate further groups of objects.
-
PenumbraSize (float)
Used by the terrain renderer for self-shadowing.
-
PointLightCount (int)
Number of point lights.
-
PointLights (PointLights[4])
Current diffuse point lights in world space.
-
PointLightsObjectSpace (PointLights[4])
Current diffuse point lights in object space.
-
Screen (float4)
Holds the screen dimension thus : ( width, height, half width, half height )
-
SkyBoxController (float4)
Holds the current value of the Vector4 that was registered with the sky box currently being rendered. How this variable is interpreted is up to the individual sky box, although the fourth component is generally treated as an alpha value.
-
SpecularDirectionalLightCount (int)
Number of specular directional lights.
-
SpecularDirectionalLights (DirectionalLights[2])
Current specular directional lights in world space.
-
SpecularDirectionalLightsObjectSpace (DirectionalLights[2])
Current specular directional lights in object space.
-
SpecularPointLightCount (int)
Number of specular point lights.
-
SpecularPointLights (PointLights[2])
Current specular point lights in world space.
-
SpecularPointLightsObjectSpace (PointLights[2])
Current specular point lights in object space.
-
SpotLightCount (int)
Number of spot lights.
-
SpotLights (SpotLights[2])
Current diffuse spot lights in world space.
-
SpotLightsObjectSpace (SpotLights[2])
Current diffuse spot lights in object space.
-
StaticLighting (bool)
Whether static lighting is applied or not.
-
StippleMap (texture)
Map to be used for the stipple effect.
-
SunAngle (float)
Used by the terrain renderer for self-shadowing.
-
TerrainTextureTransform (float4[2])
Projects textures onto the terrain.
-
Time (float)
Time in seconds since the game started.
-
View (float4x4)
Current view matrix.
-
ViewProjection (float4x4)
Current view*projection matrix.
-
WindAnimation (float4)
Two Vector2's. in (x,y) is a value that can be used for wind-affected texture scrolling. It keeps the incremental value of a single uv coordinate blown around by the wind. in (x,z) is the current wind average speed.
-
World (float4x4)
Current world matrix.
-
WorldPalette (float4[17*3])
Matrix palette, made up of the current renderset matrices stored as transposed 4x3 matrices.
-
WorldView (float4x4)
Current world*view matrix.
-
WorldViewProjection (float4x4)
Current world*view*projection matrix.
Artist-editable variables are variables that are designed to be overridden on a per-material basis. These variables can be edited in World Editor and Model Editor, allowing you to change the look of a model in real time, while visualising it.
The artist-editable variables can be exposed to the engine by setting the attribute artistEditable or worldBuilderEditable to true.
Setting artistEditable to true exposes the variable to Model Editor's Materials Settings panel (for details, see the document Content Tools Reference Guide's section Model Editor → Panel summary → Materials Settings panel), while setting worldBuilderEditable to true exposes it to both Model Editor and, if the objects/materialOverrideMode tag is set to 1 in bigworld/tools/worldeditor/options.xml (for details on this file's grammar, see the document File Grammar Guide's section options.xml → World Editor) file, to World Editor's Properties panel (for details, see the document Content Tools Reference Guide's section World Editor → Panel summary → Properties panel).
The notation for these variables in a FX file is described below:
<type> <variableName> < bool [artistEditable|worldBuilderEditable] = true; ...> = <defaultValue>;
where:
-
<type> — Type of the object.
-
<variableName> — Variable name in the effect file.
-
<defaultValue> — Default value of the variable.
Currently, the supported types of artist-editable variables are:
-
bool
-
float
-
float4
-
float4x4
-
int
-
texture
The conditions to have the variable exposed in either tool are described below:
-
If artistEditable is set to true in the FX file
Exposed in Model Editor?: Yes
Exposed in World Editor?: No
-
If worldBuilderEditable is set to true in the FX file
-
If materialOverrideMode is set to 1 in bigworld/tools/ worldeditor/options.xml
Exposed in Model Editor?: No
Exposed in World Editor?: No
-
If materialOverrideMode is set to 0 in bigworld/tools/ worldeditor/options.xml
Exposed in Model Editor?: No
Exposed in World Editor?: Yes
-
The Moo::EffectMaterial class supports having multiple-layered D3DXEffects per material.
This is useful for materials that need to use a standard set of vertex shaders, but only have slight changes to the pixel shader component of the effect. These materials would generally only be created by the asset converter, as Model Editor does not support adding more than one effect per material.
Material states can be recorded by class Moo::EffectMaterial by calling the method recordPass() between a begin() and end() pair on the material.
This method returns a Moo::StateRecorder that is used to store the current render states for delayed rendering.
This object only stays valid until the end of the current render loop, and will not be usable after this point.
BigWorld .fx files and 3ds Max .fx files unfortunately are not 100% compatible. It is however possible to create a .fx file that can be used in both applications.
To expose editable parameters, BigWorld shaders use the annotation below:
bool artistEditable = true;
whereas 3ds Max requires the annotation string below:
UIName="name"
The sample effect file bigworld/res/shaders/std_effects/normalmap.fx exposes its parameters properly to BigWorld and 3ds Max. The exporter also exports the values entered in the 3ds Max shader material panel.
The file normalmap.fx also uses a separate technique, called max_preview, plus additional vertex and pixel shaders.
This is due to two reasons:
-
There is no uniform way to apply the lighting in both the BigWorld engine and 3ds Max.
-
3ds Max uses a right-handed coordinate system, while BigWorld uses a left-handed one.
In itself this is not a big problem, but it means that additional shader work is required if you want to preview your shaders in 3ds Max.
If you have not applied Service Pack 1for 3ds Max 7, an issue exists in that its Material Panel is very poor at dealing with #include directives in the effect files. What happens is that if you save a material with the effect normalmap applied, then not always it will be properly loaded up again in 3ds Max, which can cause additional confusion for the artists. This problem has been fixed in Service Pack 1, so it is important to apply it if you want to use .fx files in 3ds Max.
It is important to be mindful of these issues before you decide to make your .fx files compatible with 3ds Max.
The visual channels implement the delayed rendering pipeline in Moo.
There are presently five standard channels implemented:
-
Sorted channel
-
Internal sorted channel
-
Shimmer channel
-
Sorted shimmer channel
-
Distortion channel
An application can create as many channels as it wants by overriding the Moo::VisualChannel interface and implementing VisualChannel::addItem.
The following sub-sections describe these channels.
The sorted channel is used for objects that need to be rendered in a back-to-front order.
When a primitive group from a visual is added to this channel, its triangles are not sorted internally.
This channel is mostly useful for additive objects, i.e., objects with a destination blend of one.
The internal sorted channel is used for objects that need to be rendered in a back-to-front order, and also have its triangles rendered in a back-to-front order.
Objects that are added to this channel will also be sorted against objects in the sorted channel.
This channel is useful for alpha-blended objects, and any transparent object that does not have a destination blend of one.
The shimmer channel is used for objects that need a heat shimmer.
Any object that is added to this channel should only write to the alpha channel of the frame buffer.
The sorted shimmer channel is used for objects that need a heat shimmer, and also need to draw colour information.
Any object added to this channel should write to both the alpha channel (for shimmer amount) and colour channel of the frame buffer.
Textures are loaded and compressed automatically based on their filenames, which control the size, format conversions, and compression levels.
For details on this file's grammar, see the document File Grammar Guide's section .texformat.
The system is implemented through the class Moo::TextureDetailLevel. The Texture Manager stores a list of texture detail levels and uses them to resize and compress textures based on their filenames. The legacy .texformat system is still supported.
The properties for the TextureDetailLevel are divided into two sets:
-
Filename matching criterion.
-
Conversion rule.
The filename matching criterion set of properties defines the criteria used to check if the current TextureDetailLevel applies to the texture being checked. They are described below:
-
contains_
Matched strings for a string contained in the texture filename.
-
postFixes_
Matched strings for the postfixes of the texture filename.
-
preFixes_
Matched strings for the prefixes of the texture filename.
Only one string from each list of strings has to match the texture name for the TextureDetailLevel to consider it a match. If there are no strings in one of the lists, that will be considered a match as well.
The conversion rule set of properties defines how matching textures will be converted. They are described below:
-
compressedFormat_
Format to which convert the texture (when texture compression is enabled).AB
-
format_
The format to convert the texture to.
-
lodMode_
Defines how texture responds to the texture quality settings.
Texture quality is set via TEXTURE_QUALITY graphics setting.AB
-
maxDim_
The maximum width/height dimension of the texture.
-
minDim_
The minimum width/height dimension of the texture.
-
noResize_
Determines that the texture will not be scaled to be a power of two, and will not have mipmapping, compression or a .dds version.
-
reduceDim_
The number of times to halve the dimensions of the texture when compression is disabled.A
A — Texture compression can be toggled via TEXTURE_COMPRESSION graphics setting.B
B — For details, see Graphics settings.
The texture detail level can be read from a datasection, as displayed in the example below:
<prefix> objects/ </prefix> <postfix> tga </postfix> <postfix> bmp </postfix> <contains> norms </contains> <contains> normals </contains> <maxDim> 512 </maxDim> <minDim> 128 </minDim> <reduceDim> 1 </reduceDim> <format> A8R8G8B8 </format>
Example texture detail level format
The example above results in any texture loaded from a sub-tree of folder objects/ with the extension .tga or .bmp and that contains the string norms or normals to have its dimensions reduced by half once, as long as the smallest dimension does not fall below 128. If the format is different, it will be changed to a 32-bit colour with alpha.
The default detail levels are:
-
Any file with a filename ending in norms.tga or norms.bmp will be converted to an A8R8G8B8 texture (so as to not compress BigWorld's normal maps).
-
Any other .tga file is converted to the DXT3 format.
-
Any other .bmp file is converted to the DXT1 format.
By default textures are only scaled down if their dimensions are bigger than 2048.
Moo supports simple animated textures by texture swapping.
When Texture Manager loads a texture, it will look for a file with the same name as the one being loaded, but with a .texanim extension. If such file is found, then it will be loaded as an animated texture.
The .texanim file is a simple XML file that references a number of textures, contains an animation string and a frames-per-second value.
The format of a .texanim file is described below:
<frames>string
</frames> <fps>.f
</fps> +<texture>TEXTURE_RESOURCE
</texture>
File .texanim format
An example of a .texanim file is displayed below:
<frames> abcdefgh </frames> <fps> 10.0 </fps> <texture> maps/fx/fx_dirt01.tga </texture> <texture> maps/fx/fx_dirt02.tga </texture> <texture> maps/fx/fx_dirt03.tga </texture> <texture> maps/fx/fx_dirt04.tga </texture> <texture> maps/fx/fx_dirt05.tga </texture> <texture> maps/fx/fx_dirt06.tga </texture> <texture> maps/fx/fx_dirt07.tga </texture> <texture> maps/fx/fx_dirt08.tga </texture>
Example file .texanim format
In this case, the animating texture will play the fx_dirt textures back in order at a rate of ten frames per second.
You can change the order in which the frames are played back by changing the frames tag . The a in the tag's value refers to the first texture stored in the XML file, b refers to the second texture stored, and so on.
To apply a code-generated texture to a model, follow the steps below:
-
Create an automatic .fx variable (e.g., customTexture).
-
Update the character's shaders so that they render using the new .fx variable, instead of the diffuseMap property.
-
You will need a single TextureSetter, which is a Moo::EffectConstantValue. This provides the "current custom texture" to .fx files.
-
Write a PyFashion that sets up the "current custom texture" when drawing an instance of a PyModel.
-
Create a Moo::BaseTexture that wraps the custom texture creation process.
When loading texture from disk, it is recommended to have the loading thread running in the background, so that it does not interrupt the rendering thread.
The example below illustrates a texture loader using the BackgroundTask and BGTaskManager classes. Note that the code provides two features — threaded texture loading, and providing the texture to the .fx file system.
#include "pch.hpp" #include "cstdmf/bgtask_manager.hpp" #include "cstdmf/concurrency.hpp" DECLARE_DEBUG_COMPONENT2( "romp", 0 ); // ------------------------------------------------------------------------- // Section: Texture Setter // ----------------------------------------------------------------------- /** * This class sets textures on the device. It is also multi-threaded. * When it is told to use a new texture, it uses the background loading thread * to do so. While it is doing this, the textureName refers to the new * texture, but isLoading() will return true. And in this state, it will be * sneakily using the pre-existing texture until the new one is ready. */ class ThreadedTextureSetter : public Moo::EffectConstantValue { public: ThreadedTextureSetter(): pTexture_( NULL ), bgLoader_( NULL ), textureName_( "" ) { } /** * This method is called by the effect system when a material needs * to draw using a texture with the given automatic semantic. */ bool operator()(ID3DXEffect* pEffect, D3DXHANDLE constantHandle) { SimpleMutexHolder holder( mutex_ ); if (pTexture_ && pTexture_->pTexture()) pEffect->SetTexture(constantHandle, pTexture_->pTexture()); else pEffect->SetTexture(constantHandle, NULL); return true; } /** * This method sets our texture. If the texture is different then * the existing one, we schedule the new one for loading, and set * the textureName and the isLoading() flag. In an unspecified amount * of time, the new texture will be loaded and used. */ void texture( const std::string& texName ) { if (textureName_ == texName) return; if (this->isLoading()) return; textureName_ = texName; bgLoader_ = new BackgroundTask( &ThreadedTextureSetter::loadTexture, this, &ThreadedTextureSetter::onLoadComplete, this ); #ifndef EDITOR_ENABLED BgTaskManager::instance()->addTask( *bgLoader_ ); #else ThreadedTextureSetter::loadTexture( this ); ThreadedTextureSetter::onLoadComplete( this ); #endif } /** * This class-static method is called by the background loading thread * and allows us to load the texture resource in a blocking manner. */ static void loadTexture( void* s ) { ThreadedTextureSetter* setter = static_cast<ThreadedTextureSetter*>(s); Moo::BaseTexturePtr pTex = Moo::TextureManager::instance()->get( setter->textureName() ); setter->pTexture(pTex); } /** * This class-static method is called when the background loading thread * has finished. */ static void onLoadComplete( void* s ) { ThreadedTextureSetter* setter = static_cast<ThreadedTextureSetter*>(s); setter->onBgLoadComplete(); } /** * This method returns the name of the texture we are currently * drawing with. If isLoading() is true, then the textureName * refers to the texture we would like to draw with (however we * will be actually drawing with the previous texture ptr). */ const std::string& textureName() const { return textureName_; } /** * This method returns true if we are currently waiting for the * background loading thread to load our texture. */ bool isLoading() { SimpleMutexHolder holder( mutex_ ); return (bgLoader_ != NULL); } private: //only called by the background loading thread void pTexture( Moo::BaseTexturePtr pTex ) { SimpleMutexHolder holder( mutex_ ); pTexture_ = pTex; } //only called by the background loading thread void onBgLoadComplete() { SimpleMutexHolder holder( mutex_ ); delete bgLoader_; bgLoader_ = NULL; } Moo::BaseTexturePtr pTexture_; std::string textureName_; //store a copy for use while loading. BackgroundTask* bgLoader_; SimpleMutex mutex_; };
Example of texture loader
To manipulate pixel within a code-generated texture, there are at least two available options:
-
Create the texture in the managed pool
This way there will be a system memory copy and a video memory copy. You can then lock the texture and manipulate it as needed — DirectX will update the changes to video memory.
The only drawback to this option is that on some hardware configurations, the system memory texture may be stored swizzled, meaning that the lock operation would have to unswizzle it before you can make changes — a potentially costly lock operation.
Note that to use the texture, you will need to have mipmaps available, so when performing the lock you will have to either:
-
Update each surface of the texture individually.
— or —
-
Use stretch rect to supply the mipmap chain from the top surface.
-
-
Create the texture in video memory as a render target
You will have to use shaders to write your changes to the texture.
The drawback to this method is that if the device is reset, then your changes will be lost. If that happens, you will have to handle the CreateUnmanagedObjects callback (from the DeviceCallback interface) and recreate the custom texture.
Unfortunately, you cannot just copy the data to system memory, because a CTRL+ALT+DEL will lose the device without giving you a chance to save the video memory data first.
Note again that to use the texture, you will need to have mipmaps available. So perhaps in this instance you can create a separate mipmap texture in video memory, and use stretch rect to supply the mipmap chain from the source render target. The source render target might be a 'scratch pad' used in building all the custom character textures.
The closest example on how to achieve this is provided by the flora light map, which uses a variation of the terrain shaders to render the lighting information to a render target. For details, see bigworld/src/lib/romp/flora_light_map.cpp.
Note that to use shaders you will need a video memory/render target surface as described in the section above.
The custom texture is needed to implement the Moo::BaseTexture interface, so that it can add itself to the Texture Manager. However, depending on the following step (applying custom textures to models), you may not even need to use the TextureManager, as it simply provides a 'retrieve texture by name' access to textures.
If you are creating several custom textures for characters, then you may have an internal (hidden) naming scheme, which would result in a minimal benefit for using the texture cache. It may be good enough simply to use smart pointers to handle caching.
Assuming that you have one model that you want display many times, each with a unique custom texture, then you will have to implement a class deriving from the PyFashion class.
Such classes are created from Python, assigned to a PyModel instance, and given an opportunity to alter how a shared model renders (i.e., to set the custom texture on the model). The PyFashion class will become the main interface to your scripts, so in Python you can construct the PyFashion instance with the names of the texture you want to combine, and then assign it to a player's model by simply setting the fashion as any named attribute on its PyModel (PyModel::pySetAttribute automatically detects when a fashion is set on itself, and incorporates it into its rendering chain).
To actually set the custom texture on the model, we recommend creating a class deriving from Moo::EffectConstantValue, and that provides the custom texture to .fx files by name. In the .fx files, use the automatic variable semantic (e.g., Texture diffuseMap :customCharacterTexture), instead of the existing artistEditable property.
For an example code on creating a texture setter, see Loading textures from disk.
Vertex declarations are used by Direct3D to map vertex stream data to vertex shaders.
Moo uses the VertexDeclaration class to ease the handling of vertex declarations used by Direct3D. Vertex declarations are stored on disk in XML format and loaded as needed. The vertex declarations stored on disk can be retrieved by calling method VertexDeclaration::get().
By default, the vertex declarations are stored under folder bigworld/res/shaders/ formats.
Two declarations can be combined with VertexDeclaration::combine() as long as the elements of both declarations are mutually exclusive.
The format of the vertex declaration file is described below:
<root> +<USAGE> (usage index, optional defaults to 0) ?<stream> (strm #, opt, dflt is strm used by the prev elmnt) </stream> ?<offset> (ofst into strm, opt, dflt is nxt ofst aft prev elmnt) </offset> ?<type> (data type, opt, defaults to FLOAT3) </type> </USAGE> </root>
Vertex declaration file format
The USAGE tag maps to the enumerated type D3DDECLUSAGE, and its possible values are listed below:
-
POSITION
-
BLENDWEIGHT
-
BLENDINDICES
-
NORMAL
-
PSIZE
-
TEXCOORD
-
TANGENT
-
BINORMAL
-
TESSFACTOR
-
POSITIONT
-
COLOR
-
FOG
-
DEPTH
-
SAMPLE
The data types entered in the type tag map to enumerated type D3DDECLTYPE, and its possible values are listed below:
-
D3DCOLOR
-
DEC3N
-
FLOAT1
-
FLOAT16_2
-
FLOAT16_4
-
FLOAT2
-
FLOAT3
-
FLOAT4
-
SHORT2
-
SHORT2N
-
SHORT4
-
SHORT4N
-
UBYTE4
-
UBYTE4N
-
UDEC3
-
USHORT2N
-
USHORT4N
As an example, the xyznuv_d vertex format is defined like this:
<xyznuv_d.xml> <POSITION/> <NORMAL/> <TEXCOORD> <type> FLOAT2 </type> </TEXCOORD> <COLOR> <stream> 1 </stream> <offset> 0 </offset> <type> D3DCOLOR </type> </COLOR> </xyznuv_d.xml>
Vertex declaration file xyznuv_d.xml
To allow the game client to run as smoothly as possible in the widest range of systems, BigWorld's 3D engine exposes several parameters. These can be tweaked by the player to achieve the optimal balance between visual quality and game responsiveness for his particular hardware configuration.
These parameters are known as graphics settings, and are listed below:
-
FAR_PLANEA
Available options: FAR, MEDIUM, NEAR Customising options
Modifies the viewing distance. The viewing distance is defined per space and this graphics option modifies the viewing distance by a factor. The factors and options are configurable in the file bigworld/res/system/data/graphics_settings.xml
-
FLORA_DENSITYA
Available options: HIGH, MEDIUM, LOW, OFF Customising options
Sets the density of the flora detail objects by a factor. The factors and options are configurable in the file bigworld/res/system/data/graphics_settings.xml.
-
FOOT_PRINTS
Available options: ON, OFF
Toggles footprints on and off.
-
OBJECT_LODA
Available options: HIGH, MEDIUM, LOW Customising options
Modifies the relative distance from the camera for LOD transitions by a factor.
-
SHADER_VERSION_CAP
Available options: SHADER_MODEL_3, SHADER_MODEL_2, SHADER_MODEL_1, SHADER_MODEL_0
Sets the maximum shader model version available to the engine.
SHADER_MODEL_0 is disabled if client is running with a graphics card supports Shader Model 1 only. SHADER_MODEL_0 need vertex shader 2.0 capability, no matter it is software or hardware vertex processing. SM1 graphics card such as nVidia TI4400 enables hardware vertex processing but only support vertex shader 1.1, so SHADER_MODEL_0 option can’t be applied.
-
SHADOWS_COUNTA
Available options: From 1 to maxCount (defined in shadows.xml — for details on this file's grammar, see the document File Grammar Guide's section shadows.xml)
Sets the number of simultaneously visible dynamic entity shadows.
-
SHADOWS_QUALITY
Available options: HIGH, MEDIUM,LOW, OFF
Sets entity shadow quality. HIGH uses a 12-tap filter for shadows, MEDIUM uses a 4-tap filter for shadows, LOW uses a 1-tap filter for shadows and OFF turns shadows off
-
SKY_LIGHT_MAPB
Available options: ON, OFF
Toggles the cloud shadows on and off.
-
TERRAIN_SPECULARB
Available options: ON, OFF
Toggles terrain specular lighting on and off.
-
TERRAIN_LOD
Available options: FAR, MEDIUM,NEAR
Modifies the terrain geo-morphing distances by a factor. The factors and options are configurable in the file bigworld/res/system/data/terrain2.xml
-
TERRAIN_MESH_RESOLUTION
Available options: HIGH, MEDIUM,LOW
Selects the terrain resolution to use. HIGH uses the highest available resolution, MEDIUM uses half the available resolution, LOW uses a quarter of the available resolution
-
TEXTURE_COMPRESSIONAC
Available options: ON, OFF Customising options
Toggles texture compression on and off
-
TEXTURE_FILTERING
Available options: ANISOTROPIC_16X, ANISOTROPIC_8X, ANISOTROPIC_4X, ANISOTROPIC_2X, TRILINEAR, BILINEAR, LINEAR, POINT
Selects texture filtering. Shaders can be modified to take advantage of this setting by using the automatic variables MinMagFilter, MipFilter, and MaxAnisotropy to set the MINFILTER , MAGFILTER, MIPFILTER and MAXANISOTROPY sampler states. For details, see bigworld/res/shaders/speedtree/speedtree.fx.
-
TEXTURE_QUALITYAC Customising options
Available options: HIGH, MEDIUM, LOW
Sets texture quality level.
-
SPEEDTREE_QUALITY
Available options: VERYHIGH, HIGH, MEDIUM, LOW, LOWEST
Sets the quality of the speedtree rendering. VERYHIGH Enables per-pixel lighting (normal mapped) on all tree parts, HIGH Enables per-pixel lighting (normal mapped) on only the tree branches, MEDIUM Trees use simple lighting, LOW Trees use simple animation and lighting, using the fixed function pipeline.
-
WATER_QUALITY
Available options: HIGH, MEDIUM, LOW, LOWEST
Sets the quality of water reflection rendering. HIGH Enables drawing of all object types, MEDIUM Disables drawing of dynamic objects, LOW Disables drawing of dynamic objects and halves the resolution of the render target. LOWEST only renders specular reflections.
-
WATER_SIMULATION
Available options: HIGH, LOW, OFF
Sets the quality of the water simulation. HIGH Enables inter-cell water simulation, MEDIUM enables water simulation on a cell by cell basis, OFF turns water simulation off.
-
POST_PROCESSING
Available options: HIGH, MEDIUM, LOW, OFF
Sets the default post-processing chain. These are selected from the chains folder, for example : bigworld/res/system/post_processing/chains/high_graphics_setting.xml. If you want to edit the default post-processing then edit the three chain files there. There are two versions of each chain, one version with FXAA and one without, see FXAA_PROCESSING below.
-
FXAA_PROCESSING
Available options: ON, OFF
Sets if FXAA (Fast approXimate Anti-Aliasing) is in the post-processing chain.
-
MRT_DEPTH
Available options: ON, OFF
Enables creation of the depth texture (exposed to .fx files via the DepthTex semantic.) This enables a variety of advanced post-processing effects such as depth-of-field and depth-fades, as well as the depth-based colouring of the water.
A — Adjustable via configuration files. For details, see Customising options.
B — Requires restart of the client. For details, see Settings that require restarting the client.
C — Delayed setting. For details, see Delayed settings.
Although most of these settings have their options determined in the engine, some settings can have their options customised via configuration files.
These settings and their customisation are discussed in the following topics.
Both TEXTURE_QUALITY and TEXURE_COMPRESSION settings are customised by the way of the texture format (.texformat) and detail levels (texture_detail_level.xml) files (for details on this file's grammar, see the document File Grammar Guide's section .texformat).
Lowering the texture quality and using compressed formats helps improving engine performance, by reducing the amount of texture memory required to store them. This means that less data needs to be sent to the graphics card at each frame, ultimately improving frame rate.
TEXURE_QUALITY adjusts the resolution of a texture by preventing its topmost mipmap levels from being loaded. This means that, at the highest level of quality, the texture will be at the same resolution as the original texture map. At medium level, it will be at half its original size, and at a quarter of it at the lowest level of quality.
How many mipmap levels are skipped in each quality level for each texture can be controlled by the lodMode tag in the texture's detailLevel section.
The table below lists the values lodMode can assume, next to the number of mipmaps skipped for each of the texture quality setting levels:
lodMode | # of skipped mipmaps | |||
---|---|---|---|---|
Value | Description | High quality | Medium quality | Low quality |
1 | Normal | 0 | 1 | 2 |
2 | Low bias | 0 | 1 | 1 |
3 | High bias | 0 | 0 | 1 |
Number of skipped mipmaps per quality setting level/ LOD level
TEXURE_COMPRESSION affects the format in which texture maps are stored in memory. When texture compression is disabled, all textures are stored using the format defined by the format tag in the texture's detailLevel section. When texture compression is enabled, the format defined by the formatCompressed is used. If formatCompressed is not defined for a texture, then format is used, whatever the compression setting is.
Note that there is no restriction to what texture format is used for format or formatCompressed, but for the texture compression setting to yield any significant performance results, formatCompressed should define a texture format that uses less texture memory than its non-compressed format counterpart.
For details on how to setup a texture's level of detail, see Texture detail levels/compression. For details on the configuration file's grammar, see the document File Grammar Guide's section .texformat.
SHADOWS_COUNT defines the maximum number of simultaneous dynamic entity shadow casters in a scene.
Shadows are rendered using shadow buffers, thus consuming texture memory. Filling the buffers up at every frame requires rendering the scene again for each shadow caster. Reducing the number of simultaneous dynamic shadow casters reduces the memory requirements and the amount of processing used to update the buffers at every frame.
Value ranges from 1 to value specified in maxCount shadows.xml file, in power of two steps (defined in shadows.xml — for details on this file's grammar, see the document File Grammar Guide's section shadows.xml).
FLORA_DENSITY defines the size of the vertex buffer used to render the flora detail objects.
Since the flora drawing distance to the camera is fixed, defining the size of the vertex buffer also determines the flora density. Because it uses alpha blending, drawing the flora can negatively influence the frame rendering time, especially on hardware with limited fill rate performance. Reducing the amount of flora rendered at any one time may help improving the frame rate.
Flora density options are defined in
<graphics_settings>.xml (for details on this
file's grammar, see the document File Grammar Guide's section <graphics_settings>
.xml) as a multiplier of the
vertex buffer, which actual size is defined per space in
<flora>.xml (for details on this file's
grammar, see the document File Grammar Guide's
section <flora>
.xml).
<graphics_settings.xml> <flora> <option> <label> HIGH </label> <value> 1.0 </value> </option> <option> <label> LOW </label> <value> 0.5 </value> </option> <option> <label> OFF </label> <value> 0 </value> </option> </flora> </graphics_settings.xml>
Example <graphics_settings>.xml — Configuring flora density
FAR_PLANE defines the maximum viewing distance when rendering the 3D world.
Decreasing the viewing distance reduces the amount of geometry sent to the rendering pipeline, resulting in higher frame rates.
Because the far plane distance can be defined on a per-space basis (in space.settings file — for details on this file's grammar, see the document File Grammar Guide's section space.settings), FAR_PLANE is actually multiplied by the space's specific far plane value before it is applied to the camera.
Specified in
<graphics_settings>
.xml
(for details on this file's grammar, see the document File Grammar Guide's section <graphics_settings>
.xml), the far plane can be
configured as in the example below:
<graphics_settings.xml> <farPlane> <option> <value> 1.0 </value> <label> FAR </label> </option> <option> <value> 0.75 </value> <label> MEDIUM </label> </option> <option> <value> 0.5 </value> <label> NEAR </label> </option> </farPlane> </graphics_settings.xml>
Example
<graphics_settings>
.xml
— Configuring far plane
OBJECT_LOD defines the relative distance to the camera before LOD transitions occur.
For standard BigWorld models, LOD distances are defined using the Model Editor. Particle Editor is used to set the LOD distance for particle systems (the maximum distance to which the system is still visible). LOD levels and transition distances for SpeedTrees are defined inside SpeedTreeCAD (although they can be overridden by the SpeedTree's XML configuration file, which is specified in resources.xml file's speedTreeXML tag. For details on this file, see File resources.xml).
The OBJECT_LOD setting specify multipliers that will modify those distances during runtime, allowing the user to trade some visual quality for better performance.
The LOD multipliers are defined in
<graphics_settings>
.xml
(for details on this file's grammar, see the document File Grammar Guide's section <graphics_settings>
.xml):
<graphics_settings.xml> <objectLOD> <option> <value> 1.0 </value> <label> HIGH </label> </option> <option> <value> 0.66 </value> <label> MEDIUM </label> </option> <option> <value> 0.33 </value> <label> LOW </label> </option> </objectLOD> </graphics_settings.xml>
Example
<graphics_settings>
.xml
— Configuring object LOD
Upon startup, the client automatically tries to load the graphics
settings from disk. All graphics settings are stored in the
graphicsPreferences section of the file specified in
preferences tag of the file specified in
resources.xml's engineConfigXML
tag (for details, see File
<preferences>
.xml). The
first time the application is run, and when the graphics card or its
driver has changed, the graphics settings will try to auto-detect the
most appropriate settings for the device.
Saving, on the other hand, is not performed automatically; it must be controlled from the scripts, using the BigWorld.savePreferences method — it will save both the graphics settings and the video and script preferences.
The game scripts can use the functions BigWorld.graphicsSettings and BigWorld.setGraphicsSettings to query and change the current state of the settings (usually trough a graphical user interface).
Auto-detecting of settings is supported through an xml configuration file specified by the tag graphicsSettingsPresets in resources.xml. This file defines matching criteria to attempt to match a group of settings to a specific device (graphics card). There are three different ways of matching a group of settings to a device. All matching is done against the D3DADAPTER_IDENTIFIER9 structure. The auto-detection itself is performed in the method Moo::GraphicsSetting::init
-
GUID
Matches a specific device type and driver version to a settings group, this is useful when there are known issues with a certain driver/device pair and you can adjust your graphics settings accordingly
-
VendorID/DeviceID pair
Matches a specific device type to the settings this is useful when you know the vendor and device id's for a specific device
-
Device description string
Matches the strings to the device description, all the strings need to match for the setting to be selected
<graphicsPreferences> HIGH <=== Name of the preset, if no name is present, the preset will not appear in the list of settings, but it will still be used when auto-detecting settings for the graphics card <entry> <=== a graphics setting to change <label> CLASSIC_TERRAIN_QUALITY </label> <=== the name of the graphics setting <activeOption> 0 </activeOption> <===the selected option </entry> <GUIDMatch> 01234567.89abcdef.01234567.89abcdef </GUIDMatch> <=== Combined GUID of device and driver version, this is the value from DeviceIdentifier in the D3DADAPTER_IDENTIFIER9 structure saved out using the BigWorld UniqueID class. If this value matches, the setting will be used. <VendorDeviceIDMatch> <VendorID> 4318 </VendorID> <=== the VendorId from D3DADAPTER_IDENTIFIER9 <DeviceID> 1554 </DeviceID> <=== the DeviceId from D3DADAPTER_IDENTIFIER9 </VendorDeviceIDMatch> <=== If these two values match the current device, the setting will be selected unless there is a GUIDMatch with the current device <DeviceDescriptionMatch> <string> nvidia </string> <=== Any number of strings that will be matched against the <string> 6800 </string> <=== Description property from D3DADAPTER_IDENTIFIER9 </DeviceDescriptionMatch> <=== If these values match the current device, the setting will be selected unless there is a GUIDMatch or VendorDeviceIDMatch with the current device <defaultSetting> true </defaultSetting> <=== this value is true for the value to be used as the default setting, the default setting is used when no other settings match. </graphicsPreferences>
Example
<graphics_settings_presets>
.xml
— Setting up device matches
A simple python graphics presets class is also supplied. This
class helps with grouping several graphics settings together so that
you can have pre-defined settings for multiple graphics options for a
specific level of hardware or performance. The
GraphicsPresets
class can be found in the folder
bigworld/res/scripts/GraphicsPresets.py.
Most settings take effect immediately after calling BigWorld.setGraphicsSettings, but some are just flagged as delayed. That means that after being set they are added to a list of pending settings, and that they will only come into effect when that list gets committed.
This was designed to give the interface programmer a chance to warn the user that processing the new settings may take a while to complete before the client application blocks for a few seconds (currently, there is no support for displaying a progress bar while the settings are being processed).
The following functions allow the scripts to manage the pending settings list:
-
BigWorld.hasPendingGraphicsSettings
-
BigWorld.commitPendingGraphicsSettings
-
BigWorld.rollBackPendingGraphicsSettings
The BigWorld client is able to take screenshots and save them to a
number of different formats. It does this by retrieving the current
content of the back buffer at the time the screenshot operation is called.
To take an in-game screenshot, press the PrtScn button,
or use the
BigWorld.screenShot(extension
,
name
) Python API function.
The default image type, filename prefix, and output location are all
configured within the engine_config.xml
(see File
<engine_config>
.xml). The schema for the
<screenShot>
tag is:
<engine_config.xml> ... <screenShot> <path>relativePath
<pathBase>basePathName
</pathBase> </path> <name>prefixName
</name> <extension>extension
</extension> </screenShot> ... </engine_config.xml>
-
relativePath — This is the output path relative to basePath (outlined below). For example, if relativePath is
MY_DOCS,
you may want to set this to something like"My Company/Game Name/Screenshots"
. Leave blank or specify "./" to place directly in basePathName (which is the default behaviour). -
basePathName — This configures the base output location for the screenshots. This can be one of the following values:
-
EXE_PATH
— Screenshots relative to the location of the client executable. This is the default location if none is supplied. -
CWD
— Screenshots will be stored relative to the current working directory. Note that if the working directory changes during runtime, it will save in the new working directory. -
ROAMING_APP_DATA
— Screenshots will be stored relative to the current user's roaming AppData directory. In other words, if the user is on a domain the data will be syncronised with the domain controller when the user logs in and out of Windows. -
LOCAL_APP_DATA
— Screenshots will be stored relative to the current user's local AppData directory. -
APP_DATA
— This is the same asROAMING_APP_DATA
. -
MY_DOCS
— Screenshots will be stored relative to the current user's My Documents directory. -
MY_PICTURES
— Screenshots will be stored relative to the current user's My Pictures directory. -
RES_TREE
— Screenshots will be stored relative to the first resource path found inpaths.xml
.
The default value is
EXE_PATH
. -
-
prefixName — Specifies the prefix to use when generating a numbered screenshot. The default value is "shot".
-
extension — Specifies the file format to use when saving the screenshot. This can be one of "bmp", "jpg", "tga", "png" or "dds". The default value is "bmp".
The full path of the generated screenshot will therefore be
basePathName/relativePath/prefixName_
,
where <sequence>
.extension<sequence>
is a
four-digit non-negative integer, padded with leading zeros
(e.g., shot_0012.bmp). The screen
capture mechanism will not overwrite pre-existing files.
Normally the back buffer is the same size as the window or the screen resolution when in full-screen mode. However, when running in windowed mode it is possible to have a back buffer that is larger than the window itself, thus increasing the size of the screenshot.
The size of the back buffer can be changed (via Debug (Watchers)
Console) by the backBufferWidthOverride
watcher.
The values specified to the watcher, and their effect on the back buffer are described below:
-
Watcher's value: 0 (default)
Resulting dimensions of the back buffer: Same as those of the window (when in windowed mode) or screen (when in full-screen mode).
-
Watcher's value: Between 1 and the maximum surface width (4096 high-end cards)
Resulting dimensions of the back buffer: Width of the back buffer will be as specified. Height of the back buffer will be the specified width divided by the aspect ratio of the window.
-
Watcher's value: Greater than supported by hardware
Resulting dimensions of the back buffer: Maximum value supported by the hardware (typically 2048 or 4096). Specified value will be ignored.
To take a high-resolution screenshot
-
Open engine_config.xml (for details on this file, see File
<engine_config>
.xml) and check the settings in <supershot> tag. If you have a video card with a large amount of memory you may be able to change hRes to 4096. -
Load the space/level and navigate to the place of which you want the screenshot.
-
Press ctrl+PrtScn to enable high resolution screenshot settings.
-
Press PrtScn to take a screenshot.
-
Press ctrl+PrtScn to restore regular render settings.
The list below describes some errors that you might come across when taking high-resolution screenshots and how to solve them:
-
Back buffer's size did not change to the value that I specified.
When setting backBufferWidthOverride, client checks if specified size is larger than the hardware can support. If that is the case, then hardware will ignore the specified size and use its maximum (typically 2048 or 4096).
— or —
When very large numbers are specified in the Debug (Watchers) Console, parsing may wrap the value. If this is the case of the value specified for backBufferWidthOverride, then it will be set to 0.
-
There is a glow covering the screen.
Sometimes, limited video memory resources will stop the renderer from allocating some of the buffers that it uses, or from drawing full-screen post-processing.
This is particularly common when changing to a lower resolution after using a very large one.
To solve this, you can either:
-
Set buffer to a smaller width (an application restart may also be necessary).
-
Turn off post-processing through the graphics settings
-
Press DEBUG+P to open the Python Console.
-
Type BigWorld.setGraphicsSetting( "POST_PROCESSING", 3 )
-
-
-
Changing back buffer's size had no effect when working in full-screen mode.
When in full-screen mode, the back buffer must always have the same dimensions as the screen resolution — this is a hardware/API limitation.
Hence, backBufferWidthOverride will always be disabled (value equals 0) when running in full-screen mode.
To produce high-resolution screenshots, a very capable video card is necessary — the two key requirements are:
-
Maximum texture resolution
-
Available video memory
DirectX 9 requires 2048 resolution as a minimum, but 4096 is available on nVidia GeForce3+ (7800+ recommended) and ATI 1X800+ series cards. It is recommended that you have a minimum of 256MB video memory when taking screenshots at resolutions in the order of 4096x3072.
The client supports two different ways to allow entity models to cast shadows into the scene. The method you choose to use will depend on the target hardware as they differ greatly in cost.
This system works by drawing a special "splodge" texture onto the geometry below the feet of the entity model, projected in the direction of the sun (they are only visible while in outside chunks). This is a good low-end solution as they are inexpensive to draw, however they will only provide a crude approximation of a shadow.
Splodges can be added to an entity model by using the PySplodge API. The PySplodge class is a type of attachment, and are attached to the feet of the entity model (one per foot). For example:
>>> lsplodge = BigWorld.Splodge() >>> rsplodge = BigWorld.Splodge() >>> model.node( "biped L Toe0" ).attach( lsplodge ) >>> model.node( "biped R Toe0" ).attach( rsplodge )
While all splodges use the same material to draw (this can be configured by modifying the environment/splodgeMaterial section in resources.xml), each PySplodge instance can modify the following parameters:
-
The maximum LOD distance from the camera, after which they are culled. Defaults to 50 metres.
-
The size of the individual splodge.
Note
Since the collision scene is used to determine where to draw a splodge, only solid objects will receive splodge shadows.

An example of splodge shadows
Entity models can be configured so that they cast a shadow into
the scene based on the direction of the sun light, utilising a dynamic
shadow map. Each frame the engine will select a set of shadow casting
entities closest to the camera, the number of which is configured via
the SHADOWS_COUNT
graphics setting. For each shadow caster
it will render the caster into a texture from the direction of the light
and then project this texture into the scene by re-rendering each object
that intersects the shadow (using the shadow map as input).
In order to cast shadows, an entity must be explicitly added to the entity shadow manager. Two Python API's are provided:
-
BigWorld.addShadowEntity
- this is usually called from theonEnterWorld
entity callback. -
BigWorld.delShadowEntity
- this is usually called from theonLeaveWorld
entity callback.
Global shadow settings (e.g. shadow map resolution, intensity, and shaders) are configured in the shadows XML file (defined in shadows.xml — for details on this file's grammar, see the document File Grammar Guide's section shadows.xml).
User controllable graphics settings are SHADOWS_COUNT
and SHADOWS_QUALITY
. See Graphics settings for details.
Note
Shadows will be cast onto terrain, solid models, and flora. Sorted triangles (i.e. translucent objects) will not cast or receive shadows.
Note
Keep in mind that the expense of using entity shadows will
increase as the number of rendered shadowed entities increases, so it
is recommended to keep the SHADOWS_COUNT
setting as low
as possible to maintain performance. As such this is not designed to
be a general purpose full-scene shadowing system.

An example of dynamic entity shadows