示例#1
0
/*Sends a ray through all of the lenses, and gives the ray emerging from the other side.
  Warning: this assumes the lenses do not overlap each other, like an actual
  camera lens system. It also assumes the lenses are sorted.*/
Vector3D traceLenses(Vector3D ray, int iterationLevel){
    Vector3D endVector = ray;
    Point3D rayLensIntersection;
    int i;

    for(i = 0; i < globals.numberOfLenses; i++){
        rayLensIntersection = lensIntersection(globals.lenses[i], endVector);

        if(isNullPoint(rayLensIntersection) == false){
            if(globals.lenses[i].isConvex == true){
                endVector = getRefraction(endVector, lensNormal(globals.lenses[i], rayLensIntersection), 1.0, globals.lenses[i].refractionIndex, rayLensIntersection);
            }
            else{
                endVector = getRefraction(endVector, lensNormal(globals.lenses[i], rayLensIntersection), globals.lenses[i].refractionIndex, 1.0, rayLensIntersection);
            }
            /*printf("Lens %d traced: ", i);
            printVector(endVector);*/
        }
        else{
            /*This shouldn't happen, but if it does, the ray is unaffected by the lens*/
            //printf("Lens %d passed\n", i);
        }
    }

    return(endVector);
}
示例#2
0
Vector refract(Vector vec, Vector normal, ItemPtr item, real refractiveIndexA) {
	real refractiveIndexB = getRefraction(item, ZERO);
	//http://en.wikipedia.org/wiki/Refractive_index
	//http://en.wikipedia.org/wiki/Refraction
	real refractiveRatio = refractiveIndexA / refractiveIndexB;
	real cosThetaA = -dot(normal, vec);
	real sinThetaA2 = 1 - cosThetaA * cosThetaA;
	real cosThetaB2 = 1 - refractiveRatio * refractiveRatio * sinThetaA2;

	if(cosThetaB2 < 0) {
		//no refraction
		return ZERO;
	}
	real cosThetaB = sqrt(cosThetaB2);
	return vec * refractiveRatio + normal * (refractiveRatio * cosThetaA - cosThetaB);
}
示例#3
0
int Sphere::refractionDirection(Ray &refraction_ray, Point &hitPoint, Vector &normal, double &t) {
	/*
	Water	1.33
	Glass	1.50
	Quartz crystal	1.54
	Glycerin	1.47
	Diamond	2.42
	*/
	Ray aux;
	aux.direction = -refraction_ray.direction;
	aux.normalizar();
	
	double cosTetaI = aux.direction*normal; /* Producto interno */
	double n = 1.0/getRefraction();
	
	/* sin2 + cos2 = 1 */
	double cosTetaR = sqrtf(1-pow((n* sqrtf(1-pow(cosTetaI,2)) ),2));
	
	if(cosTetaR ==0.0f)
		return 0;
	
	Vector refractado = refraction_ray.direction*(n) - normal*(n*cosTetaI - cosTetaR );
	
	refraction_ray.direction = refractado;
	refraction_ray.start = hitPoint;
	refraction_ray.normalizar();
	
	return 1;
	/*
	if( intersection(aux,t) ) {
		Point hitPoint2;
		hitPoint2 = aux.start + aux.direction*t;
		
		/* direcção é a mesma de antes */
		/*refraction_ray.start = hitPoint2;
		return 1;
	} else {
		return 0;
	}*/
}
示例#4
0
Vector getPixel(Ray ray, Stack * stack, real magnitude, real refractiveIndex, int depth, ulong *seed) {
	ItemPtr item = getClosestItem(ray);

	if(item==NULL) {
		return ZERO;
	}

	Vector point = getIntersectPoint(item, ray) + ray.from;
	int specularRoughness = getSpecularRoughness(item, point);
	Vector normal = getNormal(item, ray, point);

	Vector diffuseColor = ZERO;
	Vector specularColor = ZERO;

	Ray reflection;
	reflection.ray = reflect(ray.ray, normal);
	reflection.from = point+(reflection.ray*.001f);

	if(length2(getDiffuse(item, point))>0 || length2(getSpecular(item, point))>0) {
		for(int i=0;i<lightNumber;i++) {
			ItemPtr light = &lights[i];
			Vector lightVector = light->center-point;
			Vector lightPixel = fast_normalize(lightVector);

			real diffuseFactor = dot(normal, lightPixel);
			real specularFactor = dot(reflection.ray, lightPixel);

			if(diffuseFactor>0 || specularFactor>0) {
				int hitLight=0;
				
				Ray movedLightRay;
				movedLightRay.from=reflection.from;
				
				Vector right = getRight(lightPixel);
				Vector up = getUp(lightPixel, right);
				for(int i=0;i<SHADOW_RUNS;i++) {
					//TODO:  this can be much faster methinks
					real r = random(seed)*2-1;
					real u = random(seed)*sqrt(1-r*r);
					movedLightRay.ray = fast_normalize(lightVector+right*r*light->radius+up*u*light->radius);

					ItemPtr closestItem = getClosestItem(movedLightRay);
					if(closestItem!=NULL && closestItem->type==LIGHT) {
						hitLight++;
					}
				}
				if(hitLight > 0) {
					real lightValue = ((real)hitLight) / SHADOW_RUNS;
					if(diffuseFactor>0) {
						diffuseFactor *= lightValue;
						diffuseColor = diffuseColor+light->light*diffuseFactor;
					}
					if(specularFactor>0) {
						specularFactor = lightValue * pow(specularFactor, specularRoughness);
						specularColor = specularColor+light->light*specularFactor;
					}
				}
			}
		}
	}

	Vector color = (diffuseColor*getDiffuse(item, point)+specularColor*getSpecular(item, point)) * magnitude;

	if(depth > 0) {
		Ray refraction;
		if(getRefraction(item, point)) {
			refraction.ray = refract(ray.ray, normal, item, refractiveIndex);
			refraction.from = point+(refraction.ray*.001f);
			if(length2(refraction.ray)>0) {
				push(stack, depth-1, refraction, magnitude, getRefraction(item, point));
			}
		}

		if(getReflection(item, point) > 0) {
			push(stack, depth-1, reflection, magnitude * getReflection(item, point), refractiveIndex);
		}
	}

	return color;
}