Skip to content

Instantly share code, notes, and snippets.

@hypernewbie
Last active December 6, 2020 21:17
Show Gist options
  • Save hypernewbie/f80958de2cb262f8de2d00e52e1a0052 to your computer and use it in GitHub Desktop.
Save hypernewbie/f80958de2cb262f8de2d00e52e1a0052 to your computer and use it in GitHub Desktop.
Manual GLSL cubemap lookup. Hopefully correct maybe.
#include <cstdio>
#include <cmath>
struct float2
{
float x = 0.0f;
float y = 0.0f;
float2() {}
float2( float _x, float _y ) { x = _x; y = _y; }
};
struct float3
{
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
float3() {}
float3(float _x, float _y, float _z ) { x = _x; y = _y; z = _z; }
};
float3 normalize( float3 v )
{
float length = sqrt( v.x * v.x + v.y * v.y + v.z * v.z );
v.x /= length;
v.y /= length;
v.z /= length;
return v;
}
// ref: https://www.gamedev.net/forums/topic/687535-implementing-a-cube-map-lookup-function/5337475/
float2 sampleCube( const float3 v, float& faceIndex )
{
float3 vAbs = float3( fabs( v.x ), fabs( v.y ), fabs( v.z ) );
float ma;
float2 uv;
if( vAbs.z >= vAbs.x && vAbs.z >= vAbs.y ) {
faceIndex = v.z < 0.0 ? 5.0 : 4.0;
ma = 0.5 / vAbs.z;
uv = float2( v.z < 0.0 ? -v.x : v.x, -v.y );
} else if( vAbs.y >= vAbs.x ) {
faceIndex = v.y < 0.0 ? 3.0 : 2.0;
ma = 0.5 / vAbs.y;
uv = float2( v.x, v.y < 0.0 ? -v.z : v.z );
} else {
faceIndex = v.x < 0.0 ? 1.0 : 0.0;
ma = 0.5 / vAbs.x;
uv = float2( v.x < 0.0 ? v.z : -v.z, -v.y );
}
return float2(
uv.x * ma + 0.5f,
uv.y * ma + 0.5f
);
}
float3 unsampleCube( float2 uv, int faceIndex )
{
float3 v;
float ma;
uv.x -= 0.5f; uv.y -= 0.5f;
if ( faceIndex == 0 || faceIndex == 1 ) {
v.x = faceIndex == 0 ? 0.5f : -0.5f;
v.z = faceIndex == 0 ? -uv.x : uv.x; v.y = -uv.y;
} else if ( faceIndex == 2 || faceIndex == 3 ) {
v.y = faceIndex == 2 ? 0.5f : -0.5f;
v.z = faceIndex == 2 ? uv.y : -uv.y; v.x = uv.x;
} else if ( faceIndex == 4 || faceIndex == 5 ) {
v.z = faceIndex == 4 ? 0.5f : -0.5f;
v.x = faceIndex == 4 ? uv.x : -uv.x; v.y = -uv.y;
}
return normalize( v );
}
int main() {
for( float x = -1; x <= 1; x += 0.25f ) {
for( float y = -1; y <= 1; y += 0.25f ) {
for( float z = -1; z <= 1; z += 0.25f ) {
float3 v = normalize( float3( x, y, z ) );
float idx = 0;
float2 uv = sampleCube( v, idx );
float3 v2 = unsampleCube( uv, idx );
bool ok = ( fabs( v2.x - v.x ) + fabs( v2.y - v.y ) + fabs( v2.y - v.y ) ) < 0.001f;
printf(
"%.2f %.2f %.2f = %.2f %.2f, %.1f = %.2f %.2f %.2f, %s\n",
v.x, v.y, v.z,
uv.x, uv.y, idx,
v2.x, v2.y, v2.z,
ok ? "OK" : "WRONG"
);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment