DGUnreal Home

Site

Home

Map Portfolio
Mesh Portfolio

Map Awards and Reviews
Map Hosting Sites

Old News:
2007
2006
2005
2004
2003
2002
2001

LCS·AVS online Resumé

See our Readme page for information regarding installing and playing our maps, and use of our custom content.





Red Orchestra

David's Maps:

Petros coming soon

Level Design:

Information & Tutorials


Tribes:Vengeance

David's Maps:

MP-Assassinate-DGSP
MP-Mercy-DGSP
MP-Truth-DGSP


Unreal II and XMP

David's Maps:

XMP-DG_Alaska

Level Design:

Meshes
Textures


Unreal Tournament

David's Maps:

DM-DG_Dyscus
DM-DG_Illusion
DM-DG_Io
DM-DG_Octagon
DM-DG_SkyScraper
DM-DG_Vapour

Jason's Maps:

DM-DG_Haunted
DM-DG_Ruins

Level Design:

Custom Scripts
Custom Sounds
Custom 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.

GridType


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.

FSI UVTiles


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.

FSI Opacity

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.

FSI Shader


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.

FluidSurfaceInfo DecoLayer Z-error

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.

FluidSurfaceInfo StaticMesh Z-error


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.




0611.21 · 1408 page accesses · Copyright ©2008 David R. Green · All Rights Reserved.