Provides coordinate transformation methods between terrain-space, light-space and material-space.
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.
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.
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)
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.
// 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;
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
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.
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.
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.
Sets the terrain-space transformations.
Use this method to restore all transformations to a previous state, for example after loading a scene. This will make sure that material-based texturing will look exactly the same.
Allow Move to modify the material coordinate space?
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).