2017-03-23 14 views
0

The repository (GitHub)레이 추적 OBJ 파일은 음영 문제를 확산

나는 프리미티브를 렌더링 할 때이 발생하지 않습니다 (내 모델 내 확산 음영에 문제가 있어요.

은 무엇주의하는 것이 여기에서 흥미로운 것은 내가 때 생각입니다

왼쪽 반사 영역을보고, 음영 (나는 관찰에 내놓고, 이에 대한 잘못된 수 있습니다) 정상 나타납니다.

Low poly bunny and a triangle

Low poly bunny and 2 reflective spheres

Cube and 2 reflective spheres

나는 법선 내가 생성자에있는 삼각형을 만들 때마다 계산으로 내가 잘못 뭘하는지 모르겠어요. 내 모델을로드하기 위해 tinyobjloader를 사용하고 있습니다. 여기는 the TriangleMesh intersection algorithm입니다.

FPType TriangleMesh::GetIntersection(const Ray &ray) 
{ 
    for(auto &shape : shapes) 
    { 
     size_t index_offset = 0; 
     for(size_t f = 0; f < shape.mesh.num_face_vertices.size(); ++f) // faces (triangles) 
     { 
      int fv = shape.mesh.num_face_vertices[f]; 
      tinyobj::index_t &idx0 = shape.mesh.indices[index_offset + 0]; // v0 
      tinyobj::index_t &idx1 = shape.mesh.indices[index_offset + 1]; // v1 
      tinyobj::index_t &idx2 = shape.mesh.indices[index_offset + 2]; // v2 

      Vec3d &v0 = Vec3d(attrib.vertices[3 * idx0.vertex_index + 0], attrib.vertices[3 * idx0.vertex_index + 1], attrib.vertices[3 * idx0.vertex_index + 2]); 
      Vec3d &v1 = Vec3d(attrib.vertices[3 * idx1.vertex_index + 0], attrib.vertices[3 * idx1.vertex_index + 1], attrib.vertices[3 * idx1.vertex_index + 2]); 
      Vec3d &v2 = Vec3d(attrib.vertices[3 * idx2.vertex_index + 0], attrib.vertices[3 * idx2.vertex_index + 1], attrib.vertices[3 * idx2.vertex_index + 2]); 
      Triangle tri(v0, v1, v2); 
      if(tri.GetIntersection(ray)) 
       return tri.GetIntersection(ray); 
      index_offset += fv; 
     } 
    } 
} 

The Triangle Intersection algorithm.

FPType Triangle::GetIntersection(const Ray &ray) 
{ 
    Vector3d v0v1 = v1 - v0; 
    Vector3d v0v2 = v2 - v0; 
    Vector3d pvec = ray.GetDirection().Cross(v0v2); 
    FPType det = v0v1.Dot(pvec); 

    // ray and triangle are parallel if det is close to 0 
    if(abs(det) < BIAS) 
     return false; 

    FPType invDet = 1/det; 
    FPType u, v; 
    Vector3d tvec = ray.GetOrigin() - v0; 
    u = tvec.Dot(pvec) * invDet; 
    if(u < 0 || u > 1) 
     return false; 

    Vector3d qvec = tvec.Cross(v0v1); 
    v = ray.GetDirection().Dot(qvec) * invDet; 
    if(v < 0 || u + v > 1) 
     return false; 

    FPType t = v0v2.Dot(qvec) * invDet; 

    if(t < BIAS) 
     return false; 

    return t; 
} 

나는 이것이 내가 내 모든 객체 교차로를 처리하고있을 때 때문에, 삼각형 메쉬 1 등의 개체에만 간주 생각, 그래서 그것은 단지 내가 객체 법선을 얻으려고 할 때, 일 정상 반환 code

Color Trace(const Vector3d &origin, const Vector3d &direction, const std::vector<std::shared_ptr<Object>> &sceneObjects, const int indexOfClosestObject, 
       const std::vector<std::shared_ptr<Light>> &lightSources, const int &depth = 0) 
{ 
    if(indexOfClosestObject != -1 && depth <= DEPTH) // not checking depth for infinite mirror effect (not a lot of overhead) 
    { 
     std::shared_ptr<Object> sceneObject = sceneObjects[indexOfClosestObject]; 
     Vector3d normal = sceneObject->GetNormalAt(origin); 

screenshot of debug

편집 : 나는이 문제를 해결 한 지금 음영이 제대로 작동합니다 https://github.com/MrCappuccino/Tracey/blob/testing/src/TriangleMesh.cpp#L35-L48

+0

부적절한 편집! 단지'TriangleMesh :: GetIntersection'에서 즉시 돌아 오지 말고 히트의 거리를 계산하십시오. 거리가 현재 저장된 히트보다 짧고 마지막에 돌아 오면 현재 히트를 기억하십시오. – Darklighter

+0

@Darklighter는 모든 삼각형을 순환하고 가장 가까운 것을 반환해야 함을 의미합니까 ** ** TriangleMesh :: GetIntersection? –

+0

Object가 TriangleMesh 또는 삼각형 인 경우 C++에서 보는 방법이 있습니까? –

답변

1

모든 얼굴을 반복하고 첫 얼굴에 돌아 오는 경우, 다른 얼굴 뒤에있는 얼굴을 칠 수 있으므로 실제로 얼굴을 공격하지 않을 수 있으므로 광선 길이를 측정해야합니다 가장 짧은 광선에 대한 교차점을 반환합니다.