Skip to content

Instantly share code, notes, and snippets.

@vassvik
Created December 5, 2025 14:10
Show Gist options
  • Select an option

  • Save vassvik/6a01359fa6158ee1d1473f4726deeeb3 to your computer and use it in GitHub Desktop.

Select an option

Save vassvik/6a01359fa6158ee1d1473f4726deeeb3 to your computer and use it in GitHub Desktop.
// Bsky thread: https://bsky.app/profile/vassvik.bsky.social/post/3m7anve2mt22t
// Converted to GLSL from https://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/
// 5 &
// 4 |
// 4 >>
// 13 total
uvec2 _compact_1_by_1(uvec2 x) {
x = x & 0x55555555u; // x = -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0
x = (x | (x >> 1u)) & 0x33333333u; // x = --fe --dc --ba --98 --76 --54 --32 --10
x = (x | (x >> 2u)) & 0x0f0f0f0fu; // x = ---- fedc ---- ba98 ---- 7654 ---- 3210
x = (x | (x >> 4u)) & 0x00ff00ffu; // x = ---- ---- fedc ba98 ---- ---- 7654 3210
x = (x | (x >> 8u)) & 0x0000ffffu; // x = ---- ---- ---- ---- fedc ba98 7654 3210
return x;
}
// 10 &
// 8 |
// 8 >>
// 1 <<
// 27 total
uvec2 decode_morton2_65536x65536(uint x) {
return _compact_1_by_1(uvec2(x, x << 1u));
}
// 5 &
// 4 |
// 4 >>
// 1 <<
// 14 total
//
// or
//
// 5 &
// 3 |
// 4 >>
// 1 IMAD
// 13 total
//
// if x | (x << 15u) written as 32768 * x + x
uvec2 decode_morton2_256x256(uint x) { // -y-y -y-y -y-y -y-y -x-x -x-x -x-x -x-x
x = (x | (x << 15u)) & 0x55555555u; // -7-6 -5-4 -3-2 -1-0 -7-6 -5-4 -3-2 -1-0
x = (x | (x >> 1u)) & 0x33333333u; // --76 --54 --32 --10 --76 --54 --32 --10
x = (x | (x >> 2u)) & 0x0f0f0f0fu; // ---- 7654 ---- 3210 ---- 7654 ---- 3210
x = (x | (x >> 4u)); // ---- 7654 7654 3210 ---- 7654 7654 3210
return uvec2(x, x >> 16u) & 0xffu; // Note: ^--- duplicates ---^, must be masked
}
// 4 &
// 3 |
// 3 >>
// 1 <<
// 11 total
//
// or
//
// 4 &
// 2 |
// 3 >>
// 1 IMAD
// 10 total
//
// if x | (x << 7u) written as 128 * x + x
uvec2 decode_morton2_16x16(uint x) { // -y-y -y-y -x-x -x-x
x = (x | (x << 7u)) & 0x5555u; // -3-2 -1-0 -3-2 -1-0
x = (x | (x >> 1u)) & 0x3333u; // --32 --10 --32 --10
x = (x | (x >> 2u)); // --32 3210 --32 3210
return uvec2(x, x >> 8u) & 0xfu;
}
// 6 &
// 4 |
// 5 >>
// 2 <<
// 17 total
//
// or
//
// 6 &
// 2 |
// 5 >>
// 2 IMAD
// 15 total
//
// if x | (x << 16u) written as 65536 * x + x, and x | (x << 7u) written as 128 * x + x
uvec4 decode_morton2_16x16_x2(uvec2 v) {
uint x = v.x | v.y << 16u; // -y-y -y-y -x-x -x-x -y-y -y-y -x-x -x-x
x = (x | (x << 7u)) & 0x55555555u; // -3-2 -1-0 -3-2 -1-0 -3-2 -1-0 -3-2 -1-0
x = (x | (x >> 1u)) & 0x33333333u; // --32 --10 --32 --10 --32 --10 --32 --10
x = (x | (x >> 2u)); // --32 3210 --32 3210 --32 3210 --32 3210
return uvec4(x, x >> 8u, x >> 16u, x >> 24u) & 0xfu;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment