Ray raioRefletido(Object object, Ray ray){ Ray retorno; //achando a normal Vec ponto = calcularPonto(object, ray); Vec normal = calcularNormal(object, ponto); normal = normalize(normal); //vetor oposto ao raio Vec rIn = ray.dir; rIn = svmpy(-1, rIn); rIn = normalize(rIn); //cosseno entre a normal e o raio incidente double cos = dot(normal, rIn); Vec temp = normal; temp = svmpy(2*cos, temp); temp = vsub(temp, rIn); temp = normalize(temp); retorno.dir.x = temp.x; retorno.dir.y = temp.y; retorno.dir.z = temp.z; retorno.org = ponto; retorno.depth = ray.depth + 1; return retorno; }
Ray raioTransmitido(Object object, Ray ray){ Ray retorno; //achando a normal Vec ponto = calcularPonto(object, ray); Vec normal = calcularNormal(object, ponto); normal = normalize(normal); //vetor oposto ao raio Vec rIn = ray.dir; Vec temp = svmpy(-1, rIn); rIn = temp; rIn = normalize(rIn); //vetor eixo Vec eixo = multVetorial(rIn, normal); //cos1, sen1, sen2, cos2 e angulo2 double cos1 = dot(normal, rIn); double sen1 = sqrt(1 - pow(cos1, 2)); double n1 = 0; double n2 = 0; if(!inside) { n1 = 1; n2 = object.ir; inside = true; } else { n1 = object.ir; n2 = 1; inside = false; } double sen2 = (sen1*n2)/n1; double cos2 = sqrt(1 - pow(sen2, 2)); retorno.dir = svmpy(-1, normal); retorno.dir.x = ((eixo.x*eixo.x*(1-cos2)+ cos2)*retorno.dir.x) + ((eixo.z*eixo.y*(1-cos2)-(eixo.z*sen2))*retorno.dir.y) + ((eixo.x*eixo.z*(1-cos2)+(eixo.y*sen2))*retorno.dir.z); retorno.dir.y = ((eixo.y*eixo.x*(1-cos2)+(eixo.z*sen2))*retorno.dir.x) + ((eixo.z*eixo.x*(1-cos2)+ cos2)*retorno.dir.y) + ((eixo.y*eixo.z*(1-cos2)-(eixo.x*sen2))*retorno.dir.z); retorno.dir.z = ((eixo.z*eixo.x*(1-cos2)-(eixo.y*sen2))*retorno.dir.x) + ((eixo.z*eixo.x*(1-cos2)-(eixo.x*sen2))*retorno.dir.y) + ((eixo.z*eixo.z*(1-cos2)+ cos2)*retorno.dir.z); retorno.org = ponto; retorno.depth = ray.depth + 1; return retorno; }
double calcularIntensidadeDifusa(Object object, Ray rayOlho, Light luz) { double retorno = 0; //achando a normal Vec ponto = calcularPonto(object, rayOlho); Vec normal = calcularNormal(object, ponto); normal = normalize(normal); //vetor oposto à luz Vec rIn = luz.dir; rIn = svmpy(-1, rIn); rIn = normalize(rIn); //se não for raio de sombra Ray raySombra; raySombra.dir = rIn; raySombra.org = ponto; if(!isRaioSombra(raySombra)) { //intensidade = I * kd * cos double cos = dot(normal, rIn); if(cos < 0) cos = 0; retorno = luz.Int * (object.quad->m.Kd * cos); } return retorno; }
double calcularIntensidadeEspecular(Object object, Ray rayOlho, Light luz) { double retorno = 0; //achando a normal Vec ponto = calcularPonto(object, rayOlho); Vec normal = calcularNormal(object, ponto); normal = normalize(normal); //achando o vetor oposto à luz Vec rIn = luz.dir; rIn = svmpy(-1, rIn); rIn = normalize(rIn); //R = 2N(N.L) - L ou R = N * 2*cos - L double cos = dot(normal, rIn); if(cos < 0) cos = 0; Vec r = vsub(svmpy(2 * cos, normal), rIn); r = normalize(r); //achando v (vetor do olho) Vec v = rayOlho.dir; v = svmpy(-1, v); v = normalize(v); //se não for raio de sombra Ray raySombra; raySombra.dir = rIn; raySombra.org = ponto; if(!isRaioSombra(raySombra)) { //intensidade = I * ks*cosª double cos2 = dot(r, v); if(cos2 < 0) cos2 = 0; retorno = luz.Int*(object.quad->m.Ks * (pow(cos2, object.quad->m.n))); } return retorno; }
Vec calcularPonto(Object object, Ray ray){ Vec retorno; Vec temp; temp.x = ray.dir.x; temp.y = ray.dir.y; temp.z = ray.dir.z; temp = normalize(temp); double dist = intersect(ray, object.quad); temp = svmpy(dist, temp); retorno.x = temp.x + ray.org.x; retorno.y = temp.y + ray.org.y; retorno.z = temp.z + ray.org.z; return retorno; }
/*----------------------------------------------------------------------------*/ Vector Vector::normalize() { return svmpy( 1/veclength() ); } /* normalize() */