2013-05-09 9 views
6

C++ 'da bir raytracer yazıyorum ve kırılmalarla ilgili bir sorun yaşıyorum. Bir küre ve bir yer düzlemi oluşturuyorum ve küre kırılmalı. Bununla birlikte, bir kürenin içindeki bir küreye daha çok benziyor: "dış" küre düzgün bir şekilde gölgelenmiş görünüyor, ancak kırılma değil, "iç" küre ise kendinden gölgelenmiş gibi görünüyor. İşte neye benzediğine dair bir bağlantı: http://imgur.com/QVGkeBT.Raytracer Refraksiyon Hata

İşte ilgili kod.

//inside main raytrace function 
    if(refraction > 0.0f){ //the surface is refractive 
     //calculate refraction vector 
     Ray refract(intersection, 
      objList[bestObj]->refractedRay(
      ray.dir,intersection,&cos_theta,&R0)); 
     //recurse 
     refrColor = raytrace(refract); 
     } 
     else{ //no refraction 
     refrColor = background; 
     } 


//refractedRay(vec3,vec3,float*,float*) 
    //...initialize variables, do geometric transforms 
    //into air out of obj 
    if(dot(ray,normal) < 0){ 
    n1 = ior; 
    n2 = 1.0f; 
    *cos = dot(ray,-normal); 
    } 
    //into obj out of air 
    else{ 
    n1 = 1.0f; 
    n2 = ior; 
    *cos = dot(ray,normal); 
    normal = -normal; 
    } 

    //check value under sqrt 
    float n = n1/n2; 
    float disc = 1-(pow(n,2)*(1-pow(*cos,2))); 
    if(disc < 0){ //total internal reflection 
    return ray - 2*-(*cos)*normal; //reflection vector 
    } 

    return (n*ray)+(((n*(*cos))-sqrt(disc))*normal); 

kötü bakmak için kullanılan küre, sonra ben vektörleri normalleştirmek için hatırladı ve bu gibi görünüyor. Daha önce, tüm boyunca sadece iç küreye benziyordu. Ana raytrace fonksiyonunun içinde, refraksiyonu yansıma ile aynı şekilde yapıyorum, bunun yerine sadece kırılan ışını kullanıyorum. Ayrıca, gölgede alabileceğiniz gibi kendi kendine kırılmayı kontrol etmek için epsilon ile kavşak ve ışın noktasını değiştirmeyi de denedim.

Herhangi bir yardım senin kırılma formülleri kontrol etmedim

+0

Düzeltdikten sonra bunun için doğru cevabı koyabilir misiniz? Teşekkürler –

cevap

3

:) mutluluk duyacağız ama bu yanlış görünür:

olay ışınının nokta ürünü ve normalden daha az olduğu
//into air out of obj 
if(dot(ray,normal) < 0){ 
    n1 = ior; 
    n2 = 1.0f; 
    *cos = dot(ray,-normal); 
} 

ise Sıfır ve nesnenin dışına normal noktaları varsayarsak (muhtemelen bu), bu durumda air -> inside'a karşılık gelir, böylece refraktif indeksleriniz değiştirilmelidir. Şimdi ior 1/ior ile bir küre oluşturuyorsunuz ve bu kırılma indeksi 1'den az olduğundan, kenarlardaki toplam iç yansımayı gözlemliyorsunuz. Herhangi bir şeyin eksik olup olmadığını görmek için bir göz atabilirsiniz (daha fazla özelliğe sahiptir, ancak ilgilendiğiniz parçaları tanımlayabilmeniz ve hesaplarınızın eşleştiğini kontrol edebilmeniz gerekmektedir). Bana göre her şey yolunda görünüyor, bu yüzden kırılma indekslerini düzeltmem gerektiğini düşünüyorum. Yine de, kürenin merkezindeki nondeterministik model, kesinlikle kendi kendine kesişimine benzemektedir. Yansıma durumunda, yansıma ışınını yansıma ışınını kesişen yüzey üzerinde hafifçe ittiğinizden emin olun ve kırılma durumunda kırılan ışın kendi kendine kesişimden kaçınmak için hafifçe içeri itin.

+0

İçerdeki değerleri, eğer/else bloğunun içinde değiştirdim, ama bir nedenden ötürü onları birinden diğerine taşımanın işe yaramayacağını hiç düşünmemiştim! Sanırım matematik bilgim biraz kapalıydı. Teşekkürler bir ton, daha fazla saatlerce mücadele beni kurtardı :) –

+0

@BhargavB Hoş Geldiniz! Ve raytracer ile iyi şanslar, bir yazma gerçekten çok eğlenceli bir deneyim :) – Thomas

+0

@Thomas Ben benzer bir sorum var ve bana bir cevap olabilir lütfen bana cevap verebilir düşünüyorum. http://stackoverflow.com/questions/19548384/refraction-vector-ray-tracing?noredirect=1#comment29006102_19548384 –