菲涅耳对射线追踪的影响

时间:2016-10-27 14:40:39

标签: javascript raytracing fresnel

我必须对菲涅尔效应进行建模,但我认为结果不正确。我能够计算出反射光线和透射光线。我的代码是用JavaScript编写的。

function shade(objPoint,ray,depth){

color = rgb(0,0,0);
shadowRay = calc_shadowRay(objPoint,light);

if(!inShadow(shadowRay,objPoint)) 
    color = summvv(color,lighting_object(objPoint.closestPoint,objPoint.object,light,ray));

if(depth <= 3){     
    if(objPoint.object.material.kr > 0.0 && objPoint.object.type == "sphera"){
        nHit = normalize(diff(objPoint.closestPoint,objPoint.object.o));
        outside = dot(nHit,ray.d) < 0;
        bs = prodvs(nHit,bias);
        reflectedRay = new Object();
        reflectedRay.o =(!outside)? diff(objPoint.closestPoint,bs):summvv(objPoint.closestPoint,bs);
        reflectedRay.d = normalize(calc_reflectedRay(ray,nHit));
        reflectionColor = trace(reflectedRay,++depth).color;
        color = summvv(color, prodvs(reflectionColor,objPoint.object.material.kr));
    }

if(objPoint.object.material.kt > 0.0 && objPoint.object.type == "sphera"){  
        nHit = normalize(diff(objPoint.closestPoint,objPoint.object.o));
        outside = dot(nHit,ray.d) < 0;
        bs = prodvs(nHit,bias);
        fe = fresnel(ray,nHit);

        reflectedRay = new Object();            
        reflectedRay.o = (!outside)? diff(objPoint.closestPoint,bs):summvv(objPoint.closestPoint,bs);
        reflectedRay.d = normalize(calc_reflectedRay(ray,nHit));
        reflectionColor = trace(reflectedRay,++depth).color;

        if(fe < 1){ 
            refractedRay = new Object();
            refractedRay.o = (outside)? diff(objPoint.closestPoint,bs):summvv(objPoint.closestPoint,bs);
            dirRefraction = calc_refractedRay(ray,nHit);
            refractedRay.d = normalize(dirRefraction);              
            refractionColor = trace(refractedRay,++depth).color;

        }

        rfl = prodvs(reflectionColor,fe);
        rfr = prodvs(refractionColor,1-fe);
        finalColor = summvv(rfl,rfr);
        color = summvv(color,finalColor);

    } 
}

计算菲涅尔效应:

function fresnel(_ray,nHit){
cosi = clamp(dot(nHit,_ray.d),-1,1);
etai = 1.0; etat = 1.3;

if(cosi > 0){
    temp = etai;
    etai = etat;
    etat = temp;
}

eta = etai/etat;
sint = eta * Math.sqrt(1 - cosi*cosi);

if(sint >= 1) return 1.0;
else{
    cost = Math.sqrt(1 - sint*sint);
    cosi = Math.abs(cosi);
    Lperp = (etai*cosi - etat*cost)/(etai*cosi + etat*cost);
    Lparal = (etat*cosi - etai*cost)/(etat*cosi + etai*cost);
    return (Lperp*Lperp + Lparal*Lparal)/2.0;
}

}

计算折射光线是:

function calc_refractedRay(_ray,nHit){
cosi = clamp(dot(nHit,_ray.d),-1,1);
etai = 1.0; etat = 1.3;

if(cosi < 0) cosi = -cosi;
else{
    nHit = prodvs(nHit,-1);
    temp = etai;
    etai = etat;
    etat = temp;
}

eta = etai/etat;
cost2 = 1 - eta*eta*(1 - cosi*cosi);

if(cost2 < 0) return;
else return summvv(prodvs(_ray.d,eta) , prodvs(nHit , (eta*cosi - Math.sqrt(cost2))));

}

生成的图像如下:

enter image description here

我无法理解为什么它是正确的。

0 个答案:

没有答案