“Omniplanar” Mapping
A texturing method that is somewhat similar in concept to tri-planar, only using one texture sample and without transitions or axis biases.
I made this a couple of years ago for a project that I haven’t had time to work on, so I figured that I might as well simplify and publish it in case anyone else would find it useful. It seems to be ideally used for voxels or similarly lenient styles where procedural texture mapping is desired and the caveats are acceptable.
Here are the essential differences from tri-planar and other similar approaches:
- The texture is ‘projected’ from the origin to the surface at any angle instead of the usual three.
- This maintains a pure look for pixelated textures at in-between angles.
- One compromise with this is that seams are visible between faces at different angles.
- Another is that it does not interact well with interpolated (smooth) normals.
- The texture appears to rotate with the object instead of being locked entirely to the world.
- It is very dependent on well-formed geometry data; tangents especially.
To prevent distortion from happening alongside scale transforms, the vertex/normal/tangent space conversions can be done manually within the shader.
Shader code
shader_type spatial;
render_mode world_vertex_coords;
uniform sampler2D albedo;
void vertex() {
UV = vec2(dot(VERTEX,TANGENT),dot(VERTEX,cross(TANGENT,NORMAL)));
}
void fragment() {
ALBEDO = texture(albedo,UV).rgb;
}