2015-04-15 3 views
1

Что он делает, это в основном проверка на столкновение с массивом треугольников и рисование изображения в зависимости от цвета треугольника, который он попадает. Я думаю, что моя проблема заключается в обнаружении столкновения. Код здесь:Проблемы с простым raytracer в C++

for (int i = 0; i < triangles.size(); i++){ 
    vec3 v0 = triangles[i].v0; 
    vec3 v1 = triangles[i].v1; 
    vec3 v2 = triangles[i].v2; 
    vec3 e1 = v1 - v0; 
    vec3 e2 = v2 - v0; 
    vec3 b = start - v0; 
    mat3 A(-dir, e1, e2); 
    vec3 x = glm::inverse(A) * b; 

    if (x.x > 0 && x.y > 0 && (x.x + x.y < 1) && (x.z - start.z>= 0)){ 
     return true; 
    } 
} 

... где "реж" направление луча, выходящего из камеры, рассчитанные как "х - SCREEN_WIDTH/2, у - SCREEN_HEIGHT/2, focalLength". SCREEN_WIDTH, SCREEN_HEIGHT и focalLength - константы. Начало - положение камеры, установленное на 0,0,0.

Что я не уверен в том, что действительно на самом деле и что я должен проверить, прежде чем вернусь. «хх> 0 & & ху> 0 & & (хх + ху < 1)» должен проверить, если луч попадает не только на одной и той же плоскости, но на самом деле внутри треугольника, и последней части (»хт - start.z> = 0 ", о котором я менее всего знаю), если столкновение произошло перед камерой.

Я получаю изображения, но независимо от того, насколько я стараюсь, это никогда не будет правильным. Он должен быть классическим TestModel комнаты с разными цветными стенами и двумя формами. Самое близкое, что я думаю, что у меня есть четыре из пяти стен справа, с отсутствующим и частью одной из фигур на другой стороне.

ответ

1

Я не знаком с матричной формулировкой для пересечения треугольников - это звучит довольно дорого.

Мой собственный код ниже, где мой e1 и e2 эквивалентны твой - то есть они представляют собой краевые векторы из v0 в v1 и v2 соответственно:

// NB: triangles are assumed to be in world space 
vector3 pvec = vector3::cross(ray.direction(), e2); 
double det = e1.dot(pvec); 
if (::fabs(det) < math::epsilon) return 0; 

double invDet = 1.0/det; 
vector3 tvec(p0, ray.origin()); 

double u = tvec.dot(pvec) * invDet; 
if (u < 0 || u > 1) return 0; 

vector3 qvec = vector3::cross(tvec, e1); 
double v = ray.direction().dot(qvec) * invDet; 
if (v < 0 || u + v > 1) return 0; 

double t = e2.dot(qvec) * invDet; 
if (t > math::epsilon) {  // avoid self intersection 
    // hit found at distance "t" 
} 

Я подозреваю, что проблема в вашем расчете вектор луча, который должен быть нормализован.

Смежные вопросы