Я пытаюсь реализовать то, что объясняется в этой статье:
http://devblogs.nvidia.com/parallelforall/thinking-parallel-part-iii-tree-construction-gpu/
// Expands a 10-bit integer into 30 bits
// by inserting 2 zeros after each bit.
unsigned int expandBits(unsigned int v)
{
v = (v * 0x00010001u) & 0xFF0000FFu;
v = (v * 0x00000101u) & 0x0F00F00Fu;
v = (v * 0x00000011u) & 0xC30C30C3u;
v = (v * 0x00000005u) & 0x49249249u;
return v;
}
// Calculates a 30-bit Morton code for the
// given 3D point located within the unit cube [0,1].
unsigned int morton3D(float x, float y, float z)
{
x = min(max(x * 1024.0f, 0.0f), 1023.0f);
y = min(max(y * 1024.0f, 0.0f), 1023.0f);
z = min(max(z * 1024.0f, 0.0f), 1023.0f);
unsigned int xx = expandBits((unsigned int)x);
unsigned int yy = expandBits((unsigned int)y);
unsigned int zz = expandBits((unsigned int)z);
return xx * 4 + yy * 2 + zz;
}
когда я пытаюсь использовать функцию Morton3D с приведенным примером,
(0.1010, 0.0111, 0.1100) он возвращает 1479990 вместо 101011110010.
Я что-то упустил, что здесь не объясняется
Спасибо!
-D
Вам не хватает двух основных моментов:
Номера выборок, приведенные в статье (0.1010, 0.0111, 0.1100), фактически записаны в двоичный. Это означает, что 0,1010 на самом деле 0,5 + 0,125 =0,625, 0,0111 0,25 + 0,125 + 0,0625 =0,4375 а также 0,1100 0,5 + 0,25 =0,75. Вставьте это, и вы увидите.
Образец рисунка использует только 4 бита для каждого компонента, в общей сложности 12 в кодировании Мортона, в то время как фактический код использует 10 битов на компонент в общей сложности 30. Таким образом, в результате, который вы получаете, не обращайте внимания на верхние 2 бита результат, и посмотрите на остальные биты и посмотрите, сможете ли вы понять это.
Кстати, код в статье правильный и делает то, что говорит.