Unreal II and XMP
David's Maps:
XMP-DG_Alaska
Level Design:
Meshes
Textures
|
The Team
David R. Green
- mapper, mesher, audio/music,
- scripter, texturizer
Jason 'FRaK' Dudley - tester
See the map Readme for other testers
|
Contact
You can email us at
dgunreal@lilchips.com
|
|
Unreal Tournament 2004 Level Design -
FluidSurfaceInfo Actor
Actor Classes - Actor - Info - *FluidSurfaceInfo
The FluidSurfaceInfo actor provides your map with a fluid wave motion mesh that is useful
for simulating everything from oceans and lakes to lava and slime.
The FluidSurfaceInfo is effectively a dynamically created staticmesh sheet that has an
xProcMesh style water effect applied to it.
The texture assigned to the Display.Skins slot is mapped to this staticmesh sheet
according to the UTiles/VTiles and UOffset/VOffset properties.
Adding the Actor
Select the actor class in the browser, go to your map [T]op view and right-click at the
desired map location, and choose "Add FluidSurfaceInfo here" from the popup
menu.
Make sure that the editor's grid settings are at least 16 or smaller, otherwise the actor
may not place in the map or it may place in an odd location.
Once placed and when all of the desired properties are set, it is a good idea to lock the
FluidSurfaceInfo actor so that it cannot be accidentally moved. This is accomplished
by setting the Advanced.bLockLocation property to True.
Notes
Display.DrawScale should normally be left alone at the default of 1.0, as should the
Display.DrawScale3D.X/Y/Z. These properties should not be used to change the shape
of the FluidSurfaceInfo.
Use the FluidSurfaceInfo's FluidGridSpacing and FluidXSize/FluidYSize properties to adjust
the entire size and shape of the FluidSurfaceInfo.
The FluidSurfaceInfo effect can be previewed in the 3D viewport using Realtime Preview.
If your FluidSurfaceInfo is looking too much like jello, keep in mind that larger bodies
of water usually have larger waves, so try increasing the FluidGridSpacing to 128 or 256
or 512 and lowering the FluidSpeed to 75, as chances are the waves are just too small and
jiggly. Lowering the FluidTimeScale to between 0.7 and 1 can also help.
FluidSurfaceInfo Rendering Speed and LOD
FluidSurfaceInfo's do not support LOD (Level of Detail), the entire FluidSurfaceInfo will
render whenever any portion of it is not culled by other optimization methods.
Due to this fact, all FluidSurfaceInfos in a map should be as optimized as possible by
using a large FluidGridSpacing and a FluidXSize/FluidYSize just large enough to fit the
fluid surface area requirements.
FluidSurfaceInfo Size
Since the FluidSurfaceInfo is effectively a staticmesh sheet, if any vertex of the sheet
is in the frustum, the entire FluidSurfaceInfo will be rendered.
Because of this, if the FluidSurfaceInfo is being used to create a large body of water
such as an ocean that fills a large area on a map, the FluidSurfaceInfo properties should
be adjusted to optimize the number of triangles to the minimum possible or a framerate
penalty will be incurred.
You can change the FluidSurfaceInfo size by adjusting the FluidGridSpacing property.
This property specifies the number of Unreal Units between the FluidSurfaceInfo triangle
vertices.
The default value of 24 for FluidGridSpacing is almost always too small for a river or
lake or ocean in a map, and should be increased to somewhere between 64 and 512 depending
on the size of the map and the water area you are trying to cover.
You almost always need to adjust this because the FluidSurfaceInfo usually is not culled
due to most map designs and the entire FluidSurfaceInfo renders all of the time. So
keep the gridspacing as large as you can while still maintaining the look of the water
waves reasonably sized. Note that small ponds can use small values, and depending on
map design they will be culled if possible by the engine.
Use the [T]op view in UnrealEd to get an idea of how large each triangle is in the
FluidSurfaceInfo. If there are many thousands of triangles, chances are it is going
to impact your framerate.
Multiply the FluidXSize by the FluidYSize to get the approximate number of triangles*, and
if this is more than 4000 to 8000, increase the FluidGridSpacing and decrease the
FluidXSize/FluidYSize to reduce the total number of triangles.
If you double the FluidGridSpacing, simply half the FluidXSize and FluidYSize and the
FluidSurfaceInfo will cover the same area on the map.
* The actual number of triangles is equal to (((FluidXSize-1) * (FluidYSize-1)) * 2) since
these values essentially specify the X and Y vertices counts.
FluidSurfaceInfo GridType
The FluidSurfaceInfo FluidGridType of Hex or Square simply determines the triangle layout
on the mesh sheet, with Hex providing a more realistic water look but Square renders
faster.
Hex is also not square in shape for a 1:1 FluidXSize/FluidYSize values, but is slightly
rectangular to a ratio of approximately 1.25:1.

FluidSurfaceInfo FluidXSize/FluidYSize
You can change the FluidSurfaceInfo shape itself from square to rectangular by adjusting
the FluidXSize and FluidYSize properties.
This is the number of vertices that it spans in the X and Y directions.
The maximum number of vertices supported is 256x256 (UDN codedrop changelog 2002.04.10).
For example, X=16 Y=16 would be square, while X=16 Y=32 would be rectangular.
You normally use the FluidXSize and FluidYSize to reduce the total number of
FluidSurfaceInfo triangles by reducing the overall width and length of the
FluidSurfaceInfo so that it just fills the area that you want.
Lakes would usually be square-ish, rivers would usually be rectangular.
For a river or rectangular water area, it would be pointless to keep the FluidSurfaceInfo
square and hide the edges under terrain or StaticMeshes or CSG Brushes, since that simply
increases the rendering time for the hidden triangles and impacts performance.
Since this adjustment to FluidXSize and FluidYSize may make the FluidSurfaceInfo
non-square resulting in a distorted (stretched) texture, adjust the UTiles and VTiles
appropriately to compensate for this.
So if the FluidSurfaceInfo FluidXSize and FluidYSize were 16,16 you would use a UTiles and
VTiles ratio of 1:1 for the texturing.
If the FluidSurfaceInfo FluidXSize and FluidYSize were 16,32 you would use a UTiles and
VTiles ratio of 1:2, otherwise the texture is stretched along the Y by two times if you
used a UTiles and VTiles of 1:1.
FluidSurfaceInfo UTiles/VTiles
UTiles and VTiles is how many times the texture is tiled in the appropriate direction (U
and V).
Technically you only want the UTiles and VTiles set to the same value if the
FluidSurfaceInfo is reasonably square in shape.
You can use the ratio of FluidXSize/FluidYSize to determine what your ratio of
UTiles/VTiles should be.
If the FluidXSize/FluidYSize is X=16 Y=16 (1:1) then the UTiles/VTiles should also be 1:1
(X=1 Y=1 or X=2 Y=2 or X=4 Y=4 etc.).
If the FluidXSize/FluidYSize is X=16 Y=32 (1:2) then the UTiles/VTiles should also be 1:2
(X=1 Y=2 or X=2 Y=4 or X=4 Y=8 etc.).
The example FluidSurfaceInfos in this screenshot have UTiles/VTiles values of 2/2, 2/2,
and 1/4.

FluidSurfaceInfo Texture
This can be a DXT3 or DXT5 Texture with a small amount of transparency to simulate seeing
through the water. The FireEngine package has numerous water style textures.
A Detail texture assigned to a custom water texture or to a Shader can also improve the
look of the water surface.
The UCGeneric.DetailTextures.detail03 works well for a raindrop surface detail, while
detail21 or detail51 or detail51d or detail51e work well for standard surface detail.
The Detail.bubbles or dripple or waterde also work well for standard surface detail.
To create a soft shoreline on a FluidSurfaceInfo, a shader must be created with an Opacity
texture based on the visible area of the fluid.
This is most easily accomplished by viewing the FluidSurfaceInfo and Terrain in the
editor's [T]op view and taking a screenshot. Then bringing this into a paint program
and using the outline of the fluid for the creation of a mask.
Apply a feathered soft edge to the mask.

To obtain a pleasing reflection off of the fluid surface, create a Shader that includes a
CubeMap and TexEnvMap. This can be applied to the Specular and SpecularityMask slots
of the Shader, or in the case of the Antalus map a Combiner was used.

Clamping FluidSurfaceInfo to Terrain, BSP, Blocking Volumes and StaticMeshes
To achieve a more realistic fluid surface effect, vertices of the fluid mesh that are
embedded in specific world objects are prevented from moving. This is called being
clamped.
Waves will also bounce off of these clamped areas.
To clamp the FluidSurfaceInfo vertices that pass under the terrain, set the
FluidSurfaceInfo.ClampTerrain property to the name of the related TerrainInfo.
UnrealEd supports picking of the terrain actor by choosing its icon.
BSP (CSG Brushes), Blocking Volumes and StaticMeshes with Simplified Collision Models will
all clamp FluidSurfaceInfo vertices automatically.
Unlike clamping to terrain, clamping to BSP, Blocking Volumes and StaticMesh Simplified
Collision Models occurs automatically in the engine and does not require specifying those
actors like you must do when clamping to a terrain.
For vertex clamping to occur, there must be sufficient FluidSurfaceInfo vertices within
the BSP, Blocking Volume or Simplified Collision Model for clamping to occur. In
other words, if a StaticMesh cylindrical post were placed in a FluidSurfaceInfo and none
of the FluidSurfaceInfo's vertices were inside of the post because its diameter was less
than the FluidSurfaceInfo's vertex-to-vertex grid spacing, then no clamping would occur.
You essentially should have at least four FluidSurfaceInfo vertices embedded within the
object that you wish to have clamp.
For Blocking Volumes be sure to set the BlockingVolume.bClampFluid property to True.
Note that True is the default value on Blocking Volumes.
Note that StaticMeshes themselves (ie. sets of raw triangles) cannot clamp the
FluidSurfaceInfo. They require a Simplified Collision Model to be present in the
StaticMesh.
This is due to the fact that it is too time intensive to check all of the StaticMesh's
faces to determine if a vertex is inside of or outside of the actual mesh object, since
StaticMeshes can be a mixture of convex and concave shapes.
StaticMesh Simplified Collision Models can be created with any of the UnrealEd supported
collision methods, which includes K-DOP, Save Brush As Collision, and creation in an
external 3D application using Type1 Collision Models such as MCDCX.
For StaticMeshes with Simplified Collision Models, both UseSimpleKarmaCollision and
UseSimpleBoxCollision must be True, otherwise the StaticMesh with Simplified Collision
Model will not clamp the FluidSurfaceInfo vertices.
Note: whenever you change the FluidSurfaceInfo's FluidXSize, the clamping information is
cleared until you do a Fluid Rebuild (Build All in UnrealEd). The Fluid Rebuild
recreates the fluid clamp bitmap.
Problem: Non-moving FluidSurfaceInfo
This usually occurs for one of two reasons:
1. The FluidSurfaceInfo is inside of solid BSP, a Blocking Volume or a StaticMesh with a
Collision Model, or during build it "thinks" it is inside of one of these.
BSP errors can easily cause this phenomenon.
This occurs because the fluid clamping bitmap will clamp the entire FluidSurfaceInfo (all
vertices) if it is located inside of BSP, a Blocking Volume or a StaticMesh Collision
Model.
A common reason for this occurence is a FluidSurfaceInfo attached to a mover -- both
actors must be located in a subtraction area during build, otherwise the creation of the
fluid clamp bitmap during build will clamp all vertices.
2. The Physics Detail Level (a property of LevelInfo) is set to "Low".
This level of detail setting turns off fluid for low-end computers.
In this instance, a FluidSurfaceInfo will usually show up as one large quad in wireframe
render mode (rmode 1).
Problem: Excessive bounce waves from Player or Projectile
This can occur when the FluidSurfaceInfo has vertices clamped, such as against a large
wall, and the player walks through the fluid.
When clamped, the waves bounce back off of the clamped vertices and can create an
exaggerated wave, that is excessively high.
There are three ways to deal with this if it occurs:
1. Decrease the FluidSurfaceInfo.ShootStrength, .ShootRadius, .TouchStrength values.
2. Decrease the thickness of the wall, so that it no longer clamps the FluidSurfaceInfo
vertices.
3. Change the fluid to an xProcMesh.
Problem: Z-Buffer Drawing Errors
The FluidSurfaceInfo actor can suffer from incorrect z-buffer drawing, in that objects may
not draw in the proper front-to-back order for things that are under the fluid surface
such as TerrainInfo Deco Layers, and for objects that pass through the fluid surface such
as StaticMesh bridge supports.
This is especially noticeable when attempting to create a translucent water surface.
The first step in trying to obtain a proper successful z-buffer draw, is to use a
FinalBlend as the material assigned to the FluidSurfaceInfo's Display.Skins property.
By setting the FinalBlend properties for FrameBufferBlending = FB_AlphaBlend and ZTest =
True, you will usually resolve most z-buffer drawing errors.
Terrain DecoLayers
Unfortunately, some deco layer issues cannot be solved by simply using a FinalBlend
Material on the FluidSurfaceInfo.
In the following example image, the deco layer rocks are always drawn in the incorrect
order, that is in front of the fluid surface, regardless of what FinalBlend properties are
used.
In this case, the only method available to resolve the issue is to use an xProcMesh for
the fluid surface instead of a FluidSurfaceInfo. The xProcMesh's staticmesh will
properly z-draw.

StaticMesh Objects
When placing staticmesh objects that pass through the FluidSurfaceInfo fluid, such as
bridge supports, at times they may not render correctly.
Instead of the lower half of a StaticMesh bridge support looking like it is submerged in
the water, it instead draws completely on top of the fluid.
In this case, it also normally changes its draw order depending on how far the object is
from the camera. In other words, it may draw correctly (submerged) when you are far
away from the object, but as you approach the object, it will pop into the foreground, now
being drawn in front of the fluid surface.
Depending on the staticmesh, I have yet to determine what exactly is responsible for this
occurrence. I have tried a wide variety of shapes (convex, concave, open, closed,
square, cylindrical, etc.) and designs (low poly, high poly, perpendicular faces, angular
faces, etc.).
Usually, if you have a staticmesh shape that is incorrectly drawing, you simply have to
discard the entire shape and try something different.

Properties
Only those properties that are commonly modified are covered here.
The additional FluidSurfaceInfo properties should usually be left at their defaults.
To see the complete description visit the Unreal Developer Network page.
| Display (specifies the fluid surface texture) |
| Skins.[0] |
Specifies the fluid
surface texture. |
| FluidSurfaceInfo (fluid related properties) |
| FluidDamping |
Specifies the damping
factor applied to the waves, or how quickly the surface returns to a flat state (how
quickly the waves die down).
The default is 0.5.
The value should be between 0.0 and 1.0. |
| FluidGridSpacing |
Specifies the number of
Unreal Units distance between "grid points" or the mesh triangle vertices.
Modify this property to change the FluidSurfaceInfo size, and the resulting XY size of
each wave triangle. |
| FluidGridType |
FGT_Hexagonal:
hexagonal triangle grid type. Better visually.
FGT_Square: square triangle grid type. Faster rendering. |
| FluidHeightScale |
Specifies the final
scaling factor for the wave height.
The default value is 1.0
The default value may be too high for small areas of water such as a water well, bird
feeder, etc. Lowering this value to between 0.25 and 0.75 may help. |
| FluidNoiseFrequency |
Specifies the frequency
per second of the random noise applied to the surface vertices.
The default value is 60.0, equivalent to 60Hz.
It is best to leave this value at the default and use the FluidSpeed to change the actual
wave speed.
Setting this value lower results in slower and smaller waves, while higher values result
in faster waves. If you go below 60.0 you will probably have to increase the
FluidHeightScale or FluidNoiseStrength to compensate.
Note that you will usually not be able to go below 51.0 or the motion stops, and values
above 70.0 start to make the motion very choppy. |
| FluidNoiseStrength |
Specifies the strength of
the wave noise applied to the vertices.
The defaults are Min=-70.0 Max=70.0.
The noise value applied to a vertex will be randomly chosen from within the specified
Min/Max range.
To achieve more natural looking water, these values should be identical with Min of course
being the negative value.
If you specify both positive or both negative values, it will not clamp the fluid motion
to only the positive or negative direction, since the fluid motion algorithm will always
move the vertex in the opposite direction to the initial noise value. |
| FluidSpeed |
Specifies the speed that
the waves travel across the water.
The default value is 170.0.
This is essentially how quickly the random noise value moves in an X/Y direction to the
adjacent vertices.
Lower values result in slower waves and a more viscose or thicker water (like jello).
Higher values result in faster waves, values over 300 start to look like jittering
jello. |
| FluidTimeScale |
Specifies the spatial time
scale between fluid mesh vertex movement updates.
The default value is 1.0.
A value of 0.0 is no vertex motion (freeze-frame).
Lower values increase the time between successive vertex movement updates, where 0.5
results in each wave taking twice as long to move through its vertical up-down motion.
Very low values such as 0.1 result in fluid that looks like it is moving in
slow-motion (a cool time-warp effect).
Values above 2.0 result in fluid that looks like it is running in high-speed fast-forward. |
| FluidXSize/FluidYSize |
Specifies the number of
mesh vertices in the X and Y directions.
The defaults are X=48 Y=48.
The minimum value is 2, maximum is 256, and you should not go higher than 128 at the
absolute maximum in-game (128x128 results in a FSI totalling 32258 triangles).
These values should be adjusted so that the FluidSurfaceInfo is just as large as required
to fill the desired area. Do not use a small FluidGridSpacing value and high
FluidXSize/FluidYSize values as that increases the number of triangles that must be
rendered and can impact the map's framerate.
These values do not have to be power-of-two, but can be any value from 2 through 256
(maximum). |
| FluidSurfaceInfo (player and projectile related properties) |
| ShootRadius |
Specifies how large a
radius is affected when the fluid surface is shot.
The default value is 0.0.
This value is normally not modified. |
| ShootStrength |
Specifies the strength of
the fluid motion as a result of being shot with a projectile.
The default value is -50.0.
This effectively adds another "ripple pling" at the nearest fluid surface vertex
to the projectile hit location.
This value should normally be set smaller such as between -20.0 and -10.0, otherwise
larger more powerful projectiles will cause massive waves in the fluid. |
| TouchStrength |
Specifies how large a
radius is affected when a player or vehicle passes through the fluid surface.
The default value is -50.0.
This value should normally be set smaller such as between -20.0 and -10.0, otherwise
larger more powerful projectiles will cause massive waves in the fluid. |
| FluidSurfaceInfo (surface texture related properties) |
| UOffset/VOffset |
Specifies the texture
coordinate offset for the U and V directions.
The defaults are U=0 V=0.
Normally these properties can be left at the defaults, but are available so that you can
pan the applied Skins texture in the U/V directions. |
| UTiles/VTiles |
Specifies the Skin texture
tiling amount in the U and V directions.
The defaults are U=1 V=1.
The Skins texture is applied with a 1:1 planar texture map equivalent to the full surface
area of the FluidSurfaceInfo.
The UTiles/VTiles properties allow you to increase or decrease the number of times that
the texture tiles across the surface.
If the FluidXSize and FluidYSize values are not identical, the UTiles and VTiles values
should be adjusted to the same ratio of XY to UV. |
|
|