OpenGL/GLSL で kd ツリーを実装する方法を理解しようとして 1 日を過ごした後、私はかなりイライラしています ...
GLSL で KD ノードを次のように宣言します。
layout(std140) uniform node{
ivec4 splitPoint;
int dataPtr;
} nodes[1024];
SplitPoint は kd ツリーの分割点を保持し、ベクトルの 4 番目の要素は 3d 空間で平面を形成する splitDirection を保持します。DataPtr は現在、ツリーの葉にあるランダムな値のみを保持しています。
配列全体がAhnentafel Listを形成します。
C++ では、構造は次のようになります。
struct Node{
glm::ivec4 splitPoint;
GLint dataPtr;
GLint padding[3];
};
私はそれが正しいと信じており、構築されたツリーをバッファにアップロードします。チェックとして、バッファをメインメモリにマップし、値を調べます。
0x08AB6890 +0 +256 +0 +1 -1 -858993460 -858993460 -858993460
0x08AB68B0 +256 +0 +0 +0 -1 -858993460 -858993460 -858993460
0x08AB68D0 +256 +256 +0 +0 -1 -858993460 -858993460 -858993460
[...]
0x08AB7070 +0 +0 +0 +0 +2362 -858993460 -858993460 -858993460
よく見えます (実際には、ノード 0 の y 方向に (0,256,0) でボリュームが分割されていると表示されます。-1 はデータがないことを示します)。
ツリートラバーサルのために、私はこれを試しました:
float distanceFromSplitPlane;
while(nodes[n].dataPtr == -1){
// get split direction
vec3 splitDir = vec3(0,0,0);
if(nodes[n].splitDir == 0)
splitDir.x = 1;
else if(nodes[n].splitDir == 1)
splitDir.y = 1;
else
splitDir.z = 1;
// calculate distance of ray starting point to the split plane
distanceFromSplitPlane = dot(startP.xyz-(nodes[n].splitPoint.xyz/511.0), splitDir);
// depending on the side advance in the tree
if(distanceFromSplitPlane >= 0)
n = 2 * n + 1;
else
n = 2 * n + 2;
}
// we should new be located in a leaf node and therefor have a value in dataPtr
gl_FragColor = vec4(dataPtr/6000.0, 0,1,1);
この時点で、画面上にランダムな色のパターンが表示されます。しかし、ほとんどの場合、目に見えるものは何もありません。
ノードから直接値を取得して正しい結果を得ようとしました...だから、均一なブロックデータの動的インデックス付けに何か問題があると思います。
誰かがここで私を助けてくれることを願っています...アイデアが不足しているため:/
フロリアン