I'm looking to optimize the following glsl function that does a cubmap face selection. It takes a 3 component vector and returns the face, texcoords for the face and the largest component.
vec4 cubemap( vec3 P )
{
vec4 Coord;
vec3 s = abs(P.xyz);
bvec3 b = greaterThan( P.xyz, vec3(0,0,0) );
if ( all( greaterThanEqual( s.xx, s.yz ) ) )
{
if ( b.x )
Coord = vec4( -P.z, -P.y, 0, s.x );
else
Coord = vec4( P.z, -P.y, 1, s.x );
} else
if ( all( greaterThanEqual( s.yy, s.xz ) ) )
{
if ( b.y )
Coord = vec4( P.x, P.z, 2, s.y );
else
Coord = vec4( P.x, -P.z, 3, s.y );
} else
{
if ( b.z )
Coord = vec4( P.x, -P.y, 4, s.z );
else
Coord = vec4( -P.x, -P.y, 5, s.z );
}
Coord.xy = ((Coord.xy / Coord.w) + 1.0) * 0.5;
return Coord;
}
This way might still be slow, but it doesn't do any branching:
vec2 directionToUV(vec3 v) {
vec3 abs = abs(v);
float max = max(max(abs.x, abs.y), abs.z); // Get the largest component
vec3 weights = step(max, abs); // 1.0 for the largest component, 0.0 for the others
float sign = dot(weights, sign(v)) * 0.5 + 0.5; // 0 or 1
// Find the uv coordinate
float sc = dot(weights, mix(vec3(v.z, v.x, -v.x), vec3(-v.z, v.x, v.x), sign));
float tc = dot(weights, mix(vec3(-v.y, -v.z, -v.y), vec3(-v.y, v.z, -v.y), sign));
vec2 uv = (vec2(sc, tc) / max) * 0.5 + 0.5;
// Offset into the right region of the texture
float offsetX = dot(weights, vec3(0.0, 1.0, 2.0));
float offsetY = sign;
uv.x = (uv.x + offsetX) / 3.0;
uv.y = (uv.y + offsetY) / 2.0;
return uv;
}
Where the cube maps is arranged like
+----+----+----+
| x | y | z |
+----+----+----+
| -x | -y | -z |
+----+----+----+
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With