UnrealEd Texture Projection System
Technical Reference (UT2004)

============================================================ INTRODUCTION ============================================================ UnrealEd (UT2004 / UE2) does not store UV coordinates per vertex for BSP brushes. Instead, each polygon stores a planar texture projection defined by: Origin (world-space anchor point) TextureU (world-space unit vector) TextureV (world-space unit vector) Flags (texture size, rotation, etc.) TexMatrix (2×2 texture-space transform: UU, UV, VU, VV) PanU / PanV (world-space panning via Origin) Texture coordinates are computed at render time using: 1) Project world position into base U/V: U0 = (P - Origin) dot TextureU V0 = (P - Origin) dot TextureV 2) Apply the 2×2 texture matrix: U1 = UU * U0 + UV * V0 V1 = VU * U0 + VV * V0 3) Convert to texture repeats using texture size (Flags). Where P is the vertex position in world space. This means texture alignment is fundamentally WORLD-SPACE, with an additional per-surface 2×2 texture transform that can scale, rotate, and SKEW. ============================================================ 1. TEXTUREU AND TEXTUREV ============================================================ TextureU and TextureV are ALWAYS: • Unit-length vectors • Orthogonal to each other • Defined in WORLD SPACE • Independent of any per-vertex UVs They define the base directions in which U and V increase across the polygon before the texture matrix is applied. Examples: Unrotated: TextureU = (-1, 0, 0) TextureV = ( 0,-1, 0) Rotated 45 degrees: TextureU = (-0.7071, -0.7071, 0) TextureV = ( 0.7071, -0.7071, 0) These vectors encode ONLY the base orientation of the texture space. ============================================================ 2. TEXTURE SIZE (FLAGS) ============================================================ Base scale is determined by the texture’s size flag: Flags = 256 → 256×256 texture Flags = 128 → 128×128 texture Flags = 512 → 512×512 texture One full texture repeat corresponds to “texture size” world units along TextureU or TextureV when the texture matrix is the identity: UU = 1, VV = 1, UV = 0, VU = 0 Example: Texture size = 256 Moving 256 world units along TextureU increases U0 by +256. With UU=1, UV=0, this corresponds to one texture repeat. ============================================================ 3. THE 2×2 TEXTURE MATRIX (UU, UV, VU, VV) ============================================================ UT2004 extends the classic system with a full 2×2 texture-space transform: [ U1 ] [ UU UV ] [ U0 ] [ V1 ] = [ VU VV ] [ V0 ] Where: U0, V0 = base coordinates from world projection: U0 = (P - Origin) dot TextureU V0 = (P - Origin) dot TextureV U1, V1 = transformed texture coordinates used for sampling Matrix components: UU = scale along U axis VV = scale along V axis UV = shear of V into U (skew component) VU = shear of U into V (skew component) Special cases: Identity (no extra scaling/skew): UU = 1, VV = 1, UV = 0, VU = 0 Pure uniform scale: UU = s, VV = s, UV = 0, VU = 0 Pure skew (shear): UU = 1, VV = 1, UV ≠ 0 or VU ≠ 0 Because UV and VU can be non-zero, UT2004 can produce true SKEWING of textures. ============================================================ 4. ORIGIN ============================================================ Origin is the anchor point of the texture projection. It is stored in WORLD SPACE. Origin is chosen so that one vertex of the polygon has a specific base U0/V0 coordinate (usually 0,0) before the texture matrix is applied. Conceptually: U0 = (P0 - Origin) dot TextureU V0 = (P0 - Origin) dot TextureV For a reference vertex P0 where we want U1=0, V1=0 and the matrix is identity, Origin is: Origin = P0 - TextureU * U0 - TextureV * V0 In practice, UnrealEd snaps Origin to the nearest texel grid in world space. ============================================================ 5. PAN COMMAND (POLY TEXPAN) ============================================================ Panning is implemented by shifting the projection in WORLD SPACE via Origin. UT2004 exposes this via the POLY TEXPAN command, which adjusts the texture position by moving Origin along TextureU and TextureV. Conceptual behavior: POLY TEXPAN U= V= Origin ← Origin - TextureU * du - TextureV * dv Where du and dv are world-space distances along the base U/V directions. Use cases: • Shifting a texture by a fixed amount without changing scale or rotation. • Nudging alignment after Box/Planar alignment. • Offsetting patterns (e.g., bricks, tiles) relative to geometry. Because the 2×2 matrix is applied AFTER projection, panning is independent of UU/UV/VU/VV: it always moves the base projection. ============================================================ 6. SCALE AND SKEW COMMAND (POLY TEXSCALE) ============================================================ UT2004 exposes the full 2×2 texture matrix via: POLY TEXSCALE UU= VV= UV= VU= This command operates on the selected surfaces and directly sets the matrix: [ UU UV ] [ VU VV ] Effects: • UU, VV control scaling along the base U and V axes. • UV, VU control skew (shear) between U and V. • Non-zero UV or VU produces SKEWED textures. Examples: 1) Uniform scale (texture appears smaller, more tiling): POLY TEXSCALE UU=2 VV=2 UV=0 VU=0 → U1 = 2 * U0 V1 = 2 * V0 Texture repeats twice as often in both directions. 2) Non-uniform scale: POLY TEXSCALE UU=2 VV=1 UV=0 VU=0 → U1 = 2 * U0 V1 = 1 * V0 Texture is compressed in U, unchanged in V. 3) Pure skew (shear): POLY TEXSCALE UU=1 VV=1 UV=0.5 VU=0 → U1 = 1 * U0 + 0.5 * V0 V1 = 0 * U0 + 1 * V0 The U axis is “tilted” into V, producing a skewed pattern. 4) Combined skew and scale: POLY TEXSCALE UU=1.5 VV=0.75 UV=0.25 VU=-0.25 → Arbitrary affine transform in texture space. Use cases: • Precise tiling control (UU/VV). • Creating skewed textures that follow non-orthogonal geometry. • Correcting perspective-like distortions on slanted surfaces. • Matching complex patterns across multiple faces. ============================================================ 7. ROTATION COMMAND (POLY TEXROT) ============================================================ Rotation in UT2004 can be applied in two ways: 1) By rotating TextureU and TextureV (world-space basis). 2) By using POLY TEXROT, which effectively rotates the texture matrix. Conceptual behavior of POLY TEXROT: POLY TEXROT This applies a 2D rotation R(θ) to the texture matrix: [ UU' UV' ] [ cosθ -sinθ ] [ UU UV ] [ VU' VV' ] = [ sinθ cosθ ] [ VU VV ] Or equivalently, rotates the U1/V1 space. In practice, UT2004 quantizes rotation to degree increments and combines it with the existing matrix, allowing rotated + skewed + scaled textures. Use cases: • Rotating textures by arbitrary angles. • Combining rotation with TEXSCALE skew for complex effects. • Aligning diagonal patterns to slanted geometry. ============================================================ 8. ALIGNMENT MODES ============================================================ UnrealEd provides several alignment modes. Each mode determines how TextureU, TextureV, Origin, and the INITIAL texture matrix are chosen. ------------------------------------------------------------ 8.1 BOX ALIGNMENT ------------------------------------------------------------ Used for cubes, most brushes, and the default alignment. Rules: • TextureU and TextureV are chosen from world X/Y/Z axes based on face normal. • Origin is snapped to world grid in texel units. • Initial matrix is identity: UU = 1, VV = 1, UV = 0, VU = 0 • Rotation is applied around world axes (by rotating TextureU/V). • Panning is world-space (via Origin or TEXPAN). This is the most predictable and widely used mode. ------------------------------------------------------------ 8.2 PLANAR ALIGNMENT ------------------------------------------------------------ Used for sheets and planar surfaces. Rules: • TextureU and TextureV lie in the polygon’s plane. • Origin is snapped to world grid. • Initial matrix is identity: UU = 1, VV = 1, UV = 0, VU = 0 • Rotation is applied around the polygon normal. • Still world-space, not brush-local. ------------------------------------------------------------ 8.3 FLOOR / WALL / CEILING ALIGNMENT ------------------------------------------------------------ These modes choose TextureU and TextureV based on world up/down/side axes. Examples: Floor: U = world X, V = world Y Wall: U = world X, V = world Z Ceiling: U = world X, V = world Y (flipped) Initial matrix is again identity, and further scaling/skewing is done via POLY TEXSCALE. ------------------------------------------------------------ 8.4 FIT ALIGNMENT ------------------------------------------------------------ Scales the texture so it fits exactly within the polygon bounds. Rules: • Computes polygon extents in U/V directions. • Sets UU/VV (and possibly UV/VU) so that exactly one texture repeat spans the polygon. • Origin is adjusted so that the texture fits tightly. This is the only mode that explicitly modifies the texture matrix to match geometry. ============================================================ 9. WORLD-SPACE NATURE OF ALIGNMENT ============================================================ Texture alignment depends on: • Brush world position • Brush world rotation • World grid snap • Texture size (Flags) • TextureU / TextureV (world-space basis) • Texture matrix (UU, UV, VU, VV) • Alignment mode • Panning (Origin / TEXPAN) • Rotation (TextureU/V and TEXROT) Because alignment is world-space: Moving a brush changes its texture alignment. Rotating a brush changes its texture alignment. Rebuilding geometry may re-snap Origin. ============================================================ 10. WHY BRUSH POSITION MATTERS ============================================================ Because texture alignment is world-space, not local: • Origin is stored in world coordinates. • TextureU/V are world-space vectors. • Panning is world-space movement of Origin. • Rotation is world-space rotation of U/V and/or the texture matrix. • The texture matrix (UU, UV, VU, VV) acts on world-projected coordinates. Therefore: A brush exported from any external tool must be placed at the same world coordinates in UnrealEd to preserve alignment. If the brush is moved after import, the perceived alignment changes. ============================================================ 11. FULL T3D BRUSH EXAMPLE (WITH FLAGS, BOX ALIGNMENT) ============================================================ Below is a complete, valid T3D brush demonstrating texture alignment fields, including the Flags field in the correct location. The texture matrix is conceptually identity (UU=1, VV=1, UV=0, VU=0) for this example. Begin Map Begin Actor Class=Brush Name=Brush1 Begin Brush Name=Model1 Begin PolyList Begin Polygon Item=Sheet Texture=MyPackage.MyTexture Flags=256 Origin +00000.000000,+00000.000000,+00000.000000 Normal +00000.000000,+00000.000000,-00001.000000 TextureU -00001.000000,+00000.000000,+00000.000000 TextureV +00000.000000,-00001.000000,+00000.000000 Vertex -00128.000000,-00128.000000,+00000.000000 Vertex -00128.000000,+00128.000000,+00000.000000 Vertex +00128.000000,+00128.000000,+00000.000000 Vertex +00128.000000,-00128.000000,+00000.000000 End Polygon End PolyList End Brush End Actor End Map This example represents a 256×256 sheet with a 256×256 texture aligned 1:1: • Vertices span 256 units in X and Y. • Flags=256 (texture size 256). • TextureU and TextureV are axis-aligned. • Origin is at (0,0,0). • Effective matrix: UU=1, VV=1, UV=0, VU=0. ============================================================ END OF DOCUMENT ============================================================