CPU Ray Casting - PullRequest
       25

CPU Ray Casting

2 голосов
/ 08 августа 2011

Я пытаюсь наложить луч на октревое дерево на ЦП (я знаю, что графический процессор лучше, но сейчас я не могу заставить его работать, я думаю, что моя текстура октодерева создана неправильно).

Я понимаю, что нужно сделать, и до сих пор я отбрасываю луч для каждого пикселя и проверяю, пересекает ли этот луч какие-либо узлы внутри октодерева.Если это так и узел не является листовым, я проверяю, пересекает ли луч его дочерние узлы.Я продолжаю делать это до тех пор, пока не ударится листовой узел.Как только листовой узел ударил, я получил цвет для этого узла.

Мой вопрос: как лучше всего нарисовать это на экране?В настоящее время я сохраняю цвета в массиве и рисую их с помощью glDrawPixels, но это не дает правильных результатов, с пробелами в визуализации, а также с неправильной проекцией (я использую glRasterPos3fv).

Редактировать:Вот некоторый код, который нужно очистить, извините.Я пропустил код приведения луча октри, так как не уверен, что он нужен, но я опубликую его, если это поможет:)

void Draw(Vector cameraPosition, Vector cameraLookAt)
{
// Calculate the right Vector
Vector rightVector = Cross(cameraLookAt, Vector(0, 1, 0));

// Set up the screen plane starting X & Y positions
float screenPlaneX, screenPlaneY;
screenPlaneX = cameraPosition.x() - ( ( WINDOWWIDTH / 2) * rightVector.x());
screenPlaneY = cameraPosition.y() + ( (float)WINDOWHEIGHT / 2);

float deltaX, deltaY;
deltaX = 1;
deltaY = 1;

int currentX, currentY, index = 0;
Vector origin, direction;

origin = cameraPosition;
vector<Vector4<int>> colours(WINDOWWIDTH * WINDOWHEIGHT);

currentY = screenPlaneY;

Vector4<int> colour;

for (int y = 0; y < WINDOWHEIGHT; y++)
{
    // Set the current pixel along x to be the left most pixel
    // on the image plane
    currentX = screenPlaneX;

    for (int x = 0; x < WINDOWWIDTH; x++)
    {
        // default colour is black
        colour = Vector4<int>(0, 0, 0, 0);

        // Cast the ray into the current pixel. Set the length of the ray to be 200
        direction = Vector(currentX, currentY, cameraPosition.z() + ( cameraLookAt.z() * 200 ) ) - origin;
        direction.normalize();

        // Cast the ray against the octree and store the resultant colour in the array
        colours[index] = RayCast(origin, direction, rootNode, colour);

        // Move to next pixel in the plane
        currentX += deltaX;
        // increase colour arry index postion
        index++;
    }

    // Move to next row in the image plane
    currentY -= deltaY;
}

// Set the colours for the array
SetFinalImage(colours);

// Load array to 0 0 0 to set the raster position to (0, 0, 0)
GLfloat *v = new GLfloat[3];
v[0] = 0.0f;
v[1] = 0.0f;
v[2] = 0.0f;

// Set the raster position and pass the array of colours to drawPixels
glRasterPos3fv(v);
glDrawPixels(WINDOWWIDTH, WINDOWHEIGHT, GL_RGBA, GL_FLOAT, finalImage);
}

void SetFinalImage(vector<Vector4<int>> colours)
{
    // The array is a 2D array, with the first dimension
    // set to the size of the window (WINDOW_WIDTH * WINDOW_HEIGHT)
    // Second dimension stores the rgba values for each pizel

    for (int i = 0; i < colours.size(); i++)
    {
        finalImage[i][0] = (float)colours[i].r;
        finalImage[i][1] = (float)colours[i].g;
        finalImage[i][2] = (float)colours[i].b;
        finalImage[i][3] = (float)colours[i].a;
    }
}

Ответы [ 2 ]

1 голос
/ 08 августа 2011

Ваш код рисования пикселей выглядит хорошо. Но я не уверен, что ваши процедуры RayCasting верны. Когда я писал свой raytracer, у меня была ошибка, которая приводила к появлению горизонтальных артефактов на экране, но это было связано с ошибками округления в коде рендеринга.

Я бы попробовал это ... создать результирующий набор vector<Vector4<int>>, где все цвета - красные. Теперь визуализируйте это на экране. Если это выглядит правильно, то процедуры opengl верны. Разделяй и властвуй всегда хороший метод отладки.

Вот вопрос, хотя .... почему вы используете Vector4, когда позже пишете изображение как GL_FLOAT? Я не вижу здесь никакого преобразования int-> float ....

0 голосов
/ 21 октября 2011

Ваша проблема может быть в вашем 3DDDA (octree raycaster), а именно с адаптивным завершением. Это происходит из-за квантования лучей в форму ячеек сетки, что приводит к тому, что определенные узлы октодерева, которые находятся немного позади узлов переднего плана (то есть с большей глубиной z), и которые, таким образом, должны быть частично видимыми и частично перекрытыми, вообще не будут визуализироваться. Чем меньше ваши воксели, тем менее заметно это будет.

Существует очень простой способ проверить, является ли это проблемой - закомментируйте строку (и) адаптивного завершения в вашем 3DDDA и посмотрите, есть ли у вас те же артефакты гэпа.

...