Vấn đề Raytracing - Đúc bóng


7

Vì vậy, tôi được giao nhiệm vụ tạo ra một mô hình của Cornell Box. Tôi đã xoay sở để làm mọi thứ cho đến khi đổ bóng, trong trường hợp đó, một số bóng được tạo ra khi không nên có bóng. Dưới đây là những hình ảnh về những gì nó trông giống như bây giờ và một hình ảnh lớn hơn về những gì nó sẽ trông như thế nào:

nhập mô tả hình ảnh ở đây

Tôi đã thấy rằng vì một số lý do, các bức tường hộp cũng đang đổ bóng.

Tóm tắt về cách thức hoạt động của nó: chúng tôi có một máy ảnh pinhole chiếu tia sáng và tìm điểm va chạm gần nhất, đó là tất cả mọi thứ bạn nhìn thấy. Nó lưu các điểm này cũng như khoảng cách từ một số pt khởi động (camera trong trường hợp này) đến điểm va chạm trong cấu trúc dữ liệu được xác định trước được gọi là Giao lộ. Sau đó, nó sử dụng dữ liệu này để tính toán khoảng cách với ánh sáng để tạo ra cường độ trong ánh sáng. Phương pháp tương tự được sử dụng để tìm điểm va chạm gần nhất được sử dụng để tìm vật thể gần nhất cho bóng tối cũng như sử dụng điểm va chạm ban đầu làm điểm bắt đầu và nguồn sáng làm hướng của vectơ tia.

Tôi đã thu hẹp vấn đề để raytracing; khi kiểm tra xem liệu có vật thể nào đổ bóng từ khu vực phía trên bên phải của bức tường màu xám phía sau không, trần màu lục lam được nhặt tại một điểm từ cùng một phía của ánh sáng. Ví dụ, nói nguồn sáng ở giữa và điểm ban đầu nằm ở phía bên phải của ánh sáng. Phương pháp này bằng cách nào đó nhặt được một điểm nằm cùng phía với ánh sáng khi vectơ phải đi thẳng qua nguồn sáng và kết thúc ở đâu đó ở phía bên trái của chúng ta.

Đây là mã nguồn của tôi cho các chức năng được đề cập:

bool ClosestIntersection( vec3 start, vec3 dir, const vector<Triangle>& triangles, Intersection& it ) {

    vec3 least;
    vec3 e1, e2, b, v0;
    mat3 A;

    least[0] = m;

    int index = triangles.size()-1;

    for(int i = 0; i < int(triangles.size()); i++) {

        v0 = triangles[i].v0;
        e1 = triangles[i].v1 - v0;
        e2 = triangles[i].v2 - v0;
        b = start - v0;

        A = mat3( -dir, e1, e2);

        if(!getInverse(A,b)) {continue;}

        vec3 x = A * b;

        if(x[0] <= least[0] && x[1] + x[2] <= 1.f && x[1] >= 0.f && x[2] >= 0.f && x[0] >= 0.00001f) {
            least = x;
            index = i;
        }
    }

    if (least[0] == m) {
        return false;
    }
    else {
        it.position = least[0] * dir + start;
        const vec3 t = it.position-start;
        it.distance = sqrt(t[0]*t[0] + t[1]*t[1] + t[2]*t[2]);
        it.triangleIndex = index;
        return true;
    }
}

vec3 DirectLight( const Intersection& i ){
    const Triangle T = triangles[i.triangleIndex];
    const vec3 r = lightPos - i.position;
    const float dist = sqrt(r[0]*r[0] + r[1]*r[1] + r[2]*r[2]);

    Intersection t;
    t.distance = dist;
    t.position = i.position;
    t.triangleIndex = i.triangleIndex; 

    //ClosestIntersection( i.position, lightPos, triangles, t);

    /*
    if(!ClosestIntersection( lightPos, i.position, triangles, t)) {return vec3(1,0,0);}
    else { return vec3(0,0,0); } */

    if(ClosestIntersection( i.position, lightPos, triangles, t) && (dist-t.distance > 1.f)) {

        return vec3(0,0,0);
    } else {
        const vec3 B = 14.f * T.color * (float(max(dot(r,T.normal),float(0)) / float(4*3.14 * dist* dist)));

        return B; 
    }

}

Tôi đã dành hơn mười hai giờ để cố gắng tìm ra vấn đề này. Ngay cả giảng viên của tôi cũng không thể tìm ra vấn đề. Bất kì sự trợ giúp nào đều được đánh giá cao!

Câu trả lời:


3

Bạn có chắc chắn rằng bạn không giao nhau trên cùng một bề mặt khi kiểm tra ngăn chặn ánh sáng? đây là một vấn đề chính xác cổ điển. Có nhiều cách để giải quyết nó:

  • Đầu tiên, hãy điều chỉnh tốt điểm giao nhau, bằng cách tính lại lần thứ hai: coi khoảng cách đánh đầu tiên của bạn là gần đúng, tạo điểm E '= Eye + (d-eps) *, tính toán lại giao điểm từ đây. (biến thể: cho giao lộ đầu tiên, chỉ cần sử dụng hộp giới hạn).

  • Thứ hai, đối với góc chăn thả, tùy thuộc vào hình dạng, độ chính xác lưu trữ và tính toán của bạn, tỷ lệ, bạn cũng có thể có sự thiếu chính xác nguy hiểm ở đây, và vẫn phải đảm bảo bạn sẽ không tái hiện bề mặt tương tự. Nếu phẳng hoặc lồi hoặc tàu, bạn có thể gắn thẻ nó không thể giao nhau cho thử nghiệm tia sáng. Một mẹo đơn giản hơn (gần đúng hơn) là thay thế điểm bắt đầu của tia bóng bằng epsilon theo hướng thông thường.


1

Có một mẹo mà nhiều người trong thực tế cho phép bạn vượt qua vấn đề hoàn toàn *. Khung cảnh và tập hợp những thứ được chiếu tia không nhất thiết phải giống nhau. Hầu hết các công cụ dò tia cho phép các đối tượng không tham gia vào việc tạo bóng, phản xạ, v.v.

Trong trường hợp của bạn, bạn chỉ có thể lấy các bức tường bên ngoài từ bóng đổ và do đó chúng sẽ không tự tạo bóng cho phép bạn đặt đèn bên ngoài hộp mà không gặp vấn đề gì.

Dù sao, bạn có thể thêm một chút sai lệch cho việc lấy mẫu và xem xét các đối tượng xa hơn một chút so với kết quả tính toán của bạn, vì việc tạo bóng này sẽ tránh được tất cả các loại vấn đề.

* Có bạn có một vấn đề bạn nên khắc phục điều đó. Nhưng đôi khi nhanh chóng và thực hiện là tất cả những gì cần thiết

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.