OpenGL Ray Tracer и BVH в вычислительном шейдереC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 OpenGL Ray Tracer и BVH в вычислительном шейдере

Сообщение Anonymous »

Я реализую Ray Tracer в OpenGL 4.3 и уже был доволен результатом, если только не загрузил какую-нибудь 3D-модель с несколькими сотнями треугольников. Результат был правильным, но ужасно медленным (около 1,6FPS). Поэтому я прибег к оптимизации с помощью BVH, вдохновленной видео Себастьяна Лиги. Однако результат очень странный и похоже, что материалы назначены неправильно. Нет проблем с отправкой форм или материалов через SSBO, поскольку трассировщик лучей отлично работает без BVH. Для сравнения, вот как это работает без BVH (извините за дополнительные вкладки, у меня есть еще один оператор if для использования BVH):

Код: Выделить всё

void main() {
ivec2 texelCoord = ivec2(gl_GlobalInvocationID.xy);

vec3 bgColor = mix(vec3(0.5, 0.7, 1.0), vec3(0.0), texelCoord.y / screenRes.y); // Gradient
vec4 value = vec4(bgColor, 1.0); // background color

// Get ray from camera
Ray ray = getRay(
camera,
2. * texelCoord.x / screenRes.x - 1,
1. - 2.  * texelCoord.y / screenRes.y);

// No BVH
vec3 accumulatedColor = vec3(0);
vec3 attenuation = vec3(1);

for (int depth=0; depth 0.0;
};

Intersection intersectScene(Ray ray) {
int stack[10];       // Traversal stack
int stackIdx = 0;
stack[stackIdx++] = bvhNodes.length() - 1; // Push root node index

bool foundHit = false;
float closestDist = 1e20;

Intersection hit;
hit.intersect_type = NONE;

while (stackIdx > 0) {
int nodeIdx = stack[--stackIdx];
Node node = bvhNodes[nodeIdx];

float tMin, tMax;
if (!rayIntersectsAABB(ray, node.boundsMin, node.boundsMax, tMin, tMax)) {
continue; // Skip node if ray misses bounding box
}

if (node.numShapes > 0) {
// Leaf node: test shapes
for (int i = 0; i < node.numShapes; ++i) {
int shapeIdx = bvhIndices[node.startShapeIdx + i];
hit = get_intersection(shapes[shapeIdx], ray);

if (hit.intersect_type == INNER) {
float dist = distance(ray.start, hit.hit_point);

if (dist < closestDist){
closestDist = dist;
foundHit = true;
hit.hit_normal = getNormalFromShape(shapes[shapeIdx], hit.hit_point);
hit.hit_material = shapes[shapeIdx].material;
}
}
}
} else {
// Internal node: push children
if (node.rightChild != -1) stack[stackIdx++] = node.rightChild;
if (node.leftChild != -1) stack[stackIdx++] = node.leftChild;
}
}

return hit;
};

Код: Выделить всё

void main() {
ivec2 texelCoord = ivec2(gl_GlobalInvocationID.xy);

vec3 bgColor = mix(vec3(0.5, 0.7, 1.0), vec3(0.0), texelCoord.y / screenRes.y); // Gradient
vec4 value = vec4(bgColor, 1.0); // background color

// Get ray from camera
Ray ray = getRay(
camera,
2. * texelCoord.x / screenRes.x - 1,
1. - 2. * texelCoord.y / screenRes.y);

vec3 accumulatedColor = vec3(0);
vec3 attenuation = vec3(1);

for (int depth = 0; depth < maxBounces; ++depth){
// Traverse BVH
Intersection hit = intersectScene(ray);

if (hit.intersect_type != INNER){
// Nothing hit, add background color
accumulatedColor += attenuation * bgColor; // not necessary imo
break;
}

///// TODO: material is not properly calculated                    /////

// Use hit data
vec3 hitPoint = hit.hit_point;
vec3 hitNormal = hit.hit_normal;
Material hitMaterial = hit.hit_material;
vec3 hitColor = hitMaterial.color;

accumulatedColor += attenuation * hitColor;

}

value.xyz = accumulatedColor;

imageStore(imgOutput, texelCoord, value);
}
На этот раз я пропустил затенение Фонга, тени и отражения для более простого кода. И результат:
Изображение

Я предполагаю, что алгоритм обхода BVH работает правильно, потому что при использовании с несколькими сотнями треугольников я получаю падение FPS при взгляде на модель и высокую частоту кадров при взгляде в сторону. Что мне не хватает? Почему кажется, что пересечения с фигурами внутри обхода BVH рассчитываются неправильно, а снаружи?
Может ли кто-нибудь указать здесь на ошибку? Кстати, это должна быть трассировка лучей в реальном времени.

Подробнее здесь: https://stackoverflow.com/questions/793 ... ute-shader
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Работа с буфером вершин с несколькими потоками в вычислительном шейдере
    Anonymous » » в форуме C#
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Чтение текстуры трафарета в вычислительном шейдере
    Anonymous » » в форуме C++
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous
  • Сетчатая конструкция с DDA трансверслом не работает должным образом в Ray Tracer
    Anonymous » » в форуме C++
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous
  • Я получаю сообщение «TypeError: попытка вызвать get со значением 0, которое не является ray.ObjectRef». в ray.get после
    Anonymous » » в форуме Python
    0 Ответы
    27 Просмотры
    Последнее сообщение Anonymous
  • Как отменить работу Ray, представленную в кластер Ray?
    Anonymous » » в форуме Python
    0 Ответы
    31 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C++»