TerrainSpace
Description
Provides coordinate transformation methods between terrain-space, light-space and material-space.
Terrain-space is the coordinate system that is established by IGeometry.
See TerrainMesh.Mesh and IMesh.Geometry.
Light-space is the coordinate system used to perform lighting calculations, e.g. light directions vectors and normal vectors are transformed into this coordinate system. Also, IEnvironmentMap backgrounds are applied in light-space.
See TerrainView.LightingNorth.
Material-space is the coordinate system that is used to perform tri-planar material-based texturing; it is similar to light-space, but not identical: in order to avoid texture swimming, material-space must be translated and/or rotated. Also, a non-linear projection must be applied for small planetary terrains.
See TerrainLayerMaterial.Chunks.
The steps for transforming light-space into material-space are described below.
The initial material coordinates m0
are computed as follows:
// Transform to light-space, centered at material origin. m0 = lightSpace * (point - origin)
where lightSpace
is the inverse of LightToTerrainMatrix, origin
is Origin and point
is the terrain-space point for which material coordinates need to be computed.
This step establishes the orientation of material-space, with respect to horizontal and vertical textures for tri-planar mapping. Also, floating-point precision issues are fixed for large planetary terrains.
The projected material coordinates m1
are computed as follows:
If Projection is true
and the terrain geometry is geocentric (see IGeometry.ToGeocentric):
// Compute coefficients. horizontal = length(m0.X, m0.Z) vertical = radius + m0.Y angle = atan2(horizontal, vertical) scale = horizontal > 0 ? angle * radius / horizontal : 0 // Use height above geocentric sphere as vertical coordinate. m1.y = length(m0.X, vertical, m0.Z) - radius // Scale horizontal vector to length of corresponding arc on sphere. m1.xz = m0.xz * scale;
where offset
is Offset and radius
is Radius.
Otherwise, no projection is performed and the initial material coordinates are used:
m1 = m0
This step ensures that material-space is invariant to camera movement and rotation. For large planetary terrains, material coordinate projection is not necessary, since the visual error resulting from using unprojected material coordinates is not apparent.
The adjusted material coordinates m2
are computed as follows:
// Get sine and cosine of rotation angle. s = sin(-rotation) c = cos(-rotation) // Rotate around Y-axis. m2.x = c * m1.X + s * m1.Z + offset.X m2.y = m1.y + offset.Y m2.z = -s * m1.X + c * m1.Z + offset.Z
where rotation
is Rotation.
This step ensures that material coordinates stay in place, when the coordinate frame is moving. Not doing so would result in texture swimming artefacts, which visually intolerable.
Public / Methods
Move
Updates the terrain-space transformations.
Use this method when moving over the terrain. This will keep material-space in place, avoiding texture swimming artefacts. If AllowMove returns true
, this method will do nothing and will return silently.
Reset
Resets the accumulated adjustment of material-space.
Material-space is being adjusted in order to keep material textures in place. Otherwise, texture swimming artefacts would occur. As a side-effect, this adjustment may result in different material-spaces being used for the same location in terrain-space, when visited at different points in time.
Public / Attributes
Projection
Enable projection of material-space for geocentric terrains?
The Y-coordinate of projected material-space is the height above the geocentric sphere. The X- and Y-coordinates are obtained by applying a map projection (a variant of CoordinateOperationMethod.PolarStereographic).
Defaults to false
.