Ejemplo n.º 1
0
void renderFunction()
{
	Image *image = new Image(width, height);

	image->SetAllPixels(sceneParser->getBackgroundColor());

	Camera *camera = sceneParser->getCamera();

	int max = (width > height) ? width : height;
	for (int i = 0; i < width; i++)
	for (int j = 0; j < height; j++)
	{
		//float x = ((i + 0.5) - width / 2.0) / float(max) + 0.5;
		//float y = ((j + 0.5) - height / 2.0) / float(max) + 0.5;
		float x = i*1.0 / width;
		float y = j*1.0 / height;
	//float x = 0.2f;
	//float y = 0.325f;
		Ray ray = camera->generateRay(Vec2f(x, y));
		Vec3f init_normal(0, 0, 0);
		Hit hit(0.0f, NULL, init_normal);
		//ray:带入参数  hit:带出信息
		Vec3f canswer = rayTracer->traceRay(ray, 1e-3, 0, 1.0f, 0, hit);
		image->SetPixel(i, j, canswer);
	}
	image->SaveTGA(output_file);
}
Ejemplo n.º 2
0
static void	init_server(t_info *inf)
{
  init_normal(inf);
  inf->type = TYPE_SERVER;
  inf->port = 2121;
  inf->nbr_thread = 1;
}
Ejemplo n.º 3
0
void traceRayFunction(float u,float v)
{
	printf("当前发出坐标:%f,%f\n", u, v);
	Camera *camera = sceneParser->getCamera();
	printf("当前camera信息:\n");
	camera->print();
	Ray ray = camera->generateRay(Vec2f(u, v));
	Vec3f init_normal(0, 0, 0);
	Hit hit(0.0f, NULL, init_normal);
	//ray:带入参数  hit:带出信息
	Vec3f canswer = rayTracer->traceRay(ray, 1e-2, 0, 1.0f, 1.0f, hit);
	//RayTree::Print();
}
Ejemplo n.º 4
0
bool Group::intersect(const Ray &r, Hit &h, float tmin)
{
	float minn = numeric_limits<float>::max();

	Vec3f init_normal(0, 0, 0);

	Hit tempHit(0.0f, NULL , init_normal);
	Hit currHit(0.0f, NULL , init_normal);

	/*
	With the intersect routine, we are looking for the closest intersection along a Ray,
	parameterized by t. tmin is used to restrict the range of intersection.
	If an intersection is found such that t > tmin and t is less than the value of the
	intersection currently stored in the Hit data structure, Hit is updated as necessary.
	Note that if the new intersection is closer than the previous one, both t and Material
	must be modified. It is important that your intersection routine verifies that t >= tmin.
	tmin depends on the type of camera (see below) and is not modified by the intersection
	routine.
	*/
	for (int i = 0; i < num; i++)
	{
		if (objects[i]->intersect(r, tempHit, tmin))//获取碰撞当前物体的碰撞信息
		{
			float t = tempHit.getT();
			if (t < minn){
				minn = t;
				currHit = tempHit;
			}
		}
	}

	if (minn == numeric_limits<float>::max())
		return false;//没有碰撞到物体
	else
		h = currHit;//碰撞信息
	return true;
}
Ejemplo n.º 5
0
Vec3f RayTracer::traceRay(Ray &ray, float tmin, int bounces, float weight,
	float indexOfRefraction, Hit &hit) const
{
	//printf("当前已有光线:\n");
	//RayTree::Print();

	Vec3f canswer;
	if (bounces > max_bounces)
		return Vec3f(0.0f, 0.0f, 0.0f); 
	Camera *camera = sceneParser->getCamera();
	Group *group = sceneParser->getGroup();
	int num_lights = sceneParser->getNumLights();
	Vec3f cambient = sceneParser->getAmbientLight();
	//原来最后是这里出了问题,一旦碰到有转换的物体,那么hit带出来的值是
	//转换后的视线看到的值,而非本来视线看到的值
	//所以解决方案是:距离不变,根据距离重新计算焦点
	if (group->intersect(ray, hit, tmin))//撞到了
	{
		if (is_view_ray)
		{
			RayTree::SetMainSegment(ray, 0, hit.getT());
			is_view_ray = false;
		}
		Vec3f cobject = hit.getMaterial()->getDiffuseColor();
		Vec3f hitPoint = hit.getIntersectionPoint();
		//环境光部分
		canswer = cambient * cobject;
		Vec3f clight;//光的颜色
		Vec3f light_dir;//指向光的方向
		Vec3f normal_dir = hit.getNormal();//交点法线向量
		float distolight;//距离光源的距离
		for (int i = 0; i < num_lights; i++)
		{
			Light *light = sceneParser->getLight(i);
			//light_dir : the direction to the light
			// 该方法用于获得指向光的方向,光的颜色,和到达光的距离
			// 第一个参数传递的是焦点信息
			light->getIllumination(hitPoint, light_dir, clight, distolight);

			Ray ray2(hitPoint, light_dir);
			Vec3f init_normal(0, 0, 0);
			Hit hit2(distolight, NULL, init_normal);
			//阴影检测
			if (shadow)
			{
				if (group->intersect(ray2, hit2, tmin)){
					RayTree::AddShadowSegment(ray2, 0, hit2.getT());
					continue;
				}
				RayTree::AddShadowSegment(ray2, 0, hit2.getT());
			}
			//cpixel  =  cambient * cobject + SUMi [ clamped(Li . N) * clighti * cobject ]
			//返回局部光
			canswer = canswer + hit.getMaterial()->Shade(ray, hit, light_dir, clight);
		}

		//printf("当前已有光线:\n");
		//RayTree::Print();

		
		//反射光
		Material *material = hit.getMaterial();
		Vec3f rc = material->getReflectiveColor();
		if (rc.r() > 0 && rc.g() > 0 && rc.b() > 0)
		{
			Vec3f mirrorDir;
			Vec3f incoming = ray.getDirection();
			mirrorDir = mirrorDirection(normal_dir, incoming);
			// The ray weight is simply multiplied by the magnitude of the reflected color
			Ray ray3(hitPoint, mirrorDir);
			Vec3f init_normal(0, 0, 0);
			Hit hit3(distolight, NULL, init_normal);
			//忘记乘以本身的反射光系数%…………
			canswer += traceRay(ray3, tmin, bounces + 1, weight*rc.Length(), indexOfRefraction, hit3)*rc;
			if (bounces + 1 < max_bounces)
				RayTree::AddReflectedSegment(ray3, 0, hit3.getT());
		}

		//printf("当前已有光线:\n");
		//RayTree::Print();


		//从这里开始还都存在问题!!!!!
		//折射光
		Vec3f transmitted;
		Vec3f tc = material->getTransparentColor();
		float index = material->getIndexOfRefraction();
		if (tc.r() > 0 && tc.g() > 0 && tc.b() > 0)
		{
			Vec3f init_normal(0, 0, 0);
			Hit hit4(distolight, NULL, init_normal);
			//在判断折射光的存在之后,要考虑光线的位置:物体内还是物体外
			//这里根据normal和incoming的点积来判断
			Vec3f incoming = ray.getDirection();
			float judge = normal_dir.Dot3(incoming);
			if (judge < 0)//光线在外
			{
				if (transmittedDirection(normal_dir, incoming, 1, index, transmitted))
				{
					Ray ray4(hitPoint, transmitted);
					canswer += traceRay(ray4, tmin, bounces+1, weight*rc.Length(), index, hit4)*tc;
					RayTree::AddTransmittedSegment(ray4, 0, hit4.getT());
				}
			}
			else//光线在内
			{
				normal_dir.Negate();
				if (transmittedDirection(normal_dir, incoming, index, 1, transmitted))
				{
					Ray ray4(hitPoint, transmitted);
					canswer += traceRay(ray4, tmin, bounces+1, weight*rc.Length(), 1, hit4)*tc;
					RayTree::AddTransmittedSegment(ray4, 0, hit4.getT());
				}
			}
		}

		//printf("当前已有光线:\n");
		//RayTree::Print();

	}
	else
		canswer = sceneParser->getBackgroundColor();

	canswer.Clamp();
	return canswer;
}