cubeToUV
Maps a 3D direction vector for cubemap lookups to 2D “Cube-UV” texture coordinates, and offsets near cube-face edges by the texel size to avoid seams and sampling bleed.
Core Advantages
Converts cubemap sampling to 2D texture-atlas sampling. Stable across platforms and works with PMREM-generated Cube-UV environment maps. Built-in per-pixel edge padding removes the need for custom unwrapping logic.
Common Uses
Implement IBL reflections and refractions on platforms without hardware cubemap LOD
Serve as the direction→UV mapping utility behind textureCubeUV
Customize direction-based 2D environment-map sampling and effects
How to adjust
The only tunable parameter is texelSizeY. Set it to 1 / texture height. With linear filtering use a 2-texel edge offset (this implementation uses 2). With NEAREST you can reduce to 1. Too little padding causes seams or mis-sampling at cube borders; too much reduces the usable sampling area.
Code Examples
1// Compute reflection direction
2const dir = reflect( positionViewDirection.negate(), normalWorld );
3
4// Compute per-pixel height using the base mip level size
5const texSize = textureSize( pmremTexture, int(0) );
6const texelSizeY = float(1.0).div( texSize.y );
7
8// Direction → Cube-UV
9const uvCube = cubeToUV( dir, texelSizeY );
10
11// Sample the 2D environment map with the resulting UV
12const envColor = texture( pmremTexture, uvCube );