Color Raytracer::RayTracing( Vector3 ray_O , Vector3 ray_V , int dep , bool refracted , int* hash, int rc, Color weight) {
	if ( dep > MAX_RAYTRACING_DEP ) return Color();
	if ( hash != NULL ) *hash = ( *hash * HASH_FAC ) % HASH_MOD;

	Color ret;
	Collider* collider = scene->FindNearestCollide(ray_O, ray_V);
	LightCollider* lightCollider = scene->FindNearestLight(ray_O, ray_V);
	
	if (lightCollider != NULL) {
		Light* nearest_light = lightCollider->GetLight();
		if (collider == NULL || lightCollider->dist < collider->dist) {
			if ( hash != NULL ) *hash = ( *hash + nearest_light->GetSample() ) % HASH_MOD;
			ret += nearest_light->GetColor() / nearest_light->GetColor().RGBMax();
		}
		delete lightCollider;
	}
	
	if ( collider != NULL ) {
		Primitive* nearest_primitive = collider->GetPrimitive();		
		if ( hash != NULL ) *hash = ( *hash + nearest_primitive->GetSample() ) % HASH_MOD;
		if ( nearest_primitive->GetMaterial()->diff > EPS ) ret += CalnDiffusion( collider , hash, rc, weight);
		if (camera->GetAlgorithm() != "RC") {
			if ( nearest_primitive->GetMaterial()->refl > EPS ) ret += CalnReflection( collider , ray_V , dep , refracted , hash, rc, weight);
			if ( nearest_primitive->GetMaterial()->refr > EPS ) ret += CalnRefraction( collider , ray_V , dep , refracted , hash, rc, weight);
		}
		delete collider;
	}

	if ( dep == 1 ) ret = ret.Confine();
	return ret;
}