/**
	* The fresnel rayTrace function creates a fresnel effect for the objects it affects.
	*/
	glm::vec3 rayTrace(Ray &ray, const float& t, const glm::vec3& normal, RayTracerState& state) {

		glm::vec3 n = glm::normalize(normal);
		glm::vec3 v = glm::normalize(ray.getDirection());

		if(glm::dot(n, v) < 0.0f){
			glm::vec3 refl_dir = reflect(n, v);
			glm::vec3 refract_dir = refract(n, v, eta_in);

			float fresnel = RF0_in + (1.0f-RF0_in)*glm::pow((1.0f-glm::dot(-v, n)), 5.0f);

			float reflect_contribution = ray.getColorContribution()*fresnel;
			float refract_contribution = ray.getColorContribution()*(1.0f-fresnel);

			glm::vec3 reflect = state.rayTrace(ray.spawn(t, refl_dir, reflect_contribution));
			glm::vec3 refract = state.rayTrace(ray.spawn(t, refract_dir, refract_contribution));

			return glm::mix(refract, reflect, fresnel);
		}
		else {
			glm::vec3 refl_dir(glm::reflect(v, n));
			glm::vec3 refract_dir = refract(-n, v, eta_out);

			float fresnel = RF0_out + (1.0f-RF0_out)*glm::pow((1.0f-glm::dot(refract_dir, n)), 5.0f);
			
			float reflect_contribution = ray.getColorContribution()*fresnel;
			float refract_contribution = ray.getColorContribution()*(1.0f-fresnel);

			glm::vec3 reflect = state.rayTrace(ray.spawn(t, refl_dir, reflect_contribution));
			glm::vec3 refract = state.rayTrace(ray.spawn(t, refract_dir, refract_contribution));

			return glm::mix(refract, reflect, fresnel);
		}
	}
예제 #2
0
    float PointInShadow(const glm::vec3& point, RayTracerState& state) {
        Ray shadow_ray(point, position-point);

        const float z_offset = 10e-4f;
        float t = -1;
        float t_min = std::numeric_limits<float>::max();
        int k_min=-1;
        //Loop through all the objects, to find the closest intersection, if any
        for (unsigned int k=0; k<state.getScene().size(); ++k) {
            t = state.getScene().at(k)->intersect(shadow_ray);

            //skipping the cubemap
            if(t >= (std::numeric_limits<float>::max()))
                continue;

            if (t > z_offset && t <= t_min) {
                k_min = k;
                t_min = t;
            }
        }

        if (k_min >= 0) {
            glm::vec3 q = point + shadow_ray.getDirection()*t_min;
            float light_length = glm::length(position-point);
            float q_lenght = glm::length(q);

            if(q_lenght < light_length)
                return 0.0f;
        }
        return 1.0f;
    }
	glm::vec3 rayTrace(Ray &ray, const float& t, const glm::vec3& normal, RayTracerState& state) {
		std::vector<std::shared_ptr<LightObject>>::iterator iter;
		glm::vec3 color;

		glm::vec3 p = ray.getOrigin() + t*ray.getDirection();

		for(iter = state.getLights().begin(); iter != state.getLights().end(); iter++){
			float shadow_value;
			shadow_value = (*iter)->PointInShadow(p, state);
			//skipping contribution from this light if the object is fully shadowed by it
			if(shadow_value <=0.00001f)
				continue;

			glm::vec3 pos = (*iter)->position;

			glm::vec3 diff = (*iter)->diff;
			glm::vec3 spec = (*iter)->spec;

			glm::vec3 v = glm::normalize(ray.getOrigin() - p);
			glm::vec3 l = glm::normalize(pos - p);
			glm::vec3 h = glm::normalize(v+l);
			glm::vec3 n = glm::normalize(normal);

			float diffuse = glm::max(0.0f, glm::dot(n, l));
			float specular = glm::pow( glm::max(0.0f, glm::dot(n, h)), 50.0f);

			glm::vec3 new_color = glm::vec3( (diff*diffuse)+(spec*specular) ) * shadow_value ;
			color += new_color;
		}
		color/=state.getLights().size();
		//glm::vec3 absnormal = glm::vec3(abs(normal.x),abs(normal.y),abs(normal.z)); 
		return color;//*shadefactor;
	}
	glm::vec3 rayTrace(Ray &ray, const float& t, const glm::vec3& normal, RayTracerState& state) {
		glm::vec3 p = ray.getOrigin() + (t*ray.getDirection());
		Ray reflected_ray(p, glm::reflect(ray.getDirection(), normal));

		float dotval = glm::dot(normal, -ray.getDirection());
		float s = 0.7f;
		dotval = s*1.0f + (1.0f-s) * dotval;

		return state.rayTrace(reflected_ray) * dotval;
	}
예제 #5
0
	glm::vec3 rayTrace(Ray &ray, const float& t, const glm::vec3& normal, RayTracerState& state) {
		glm::vec3 n = glm::normalize(normal);
		glm::vec3 v = glm::normalize(ray.getDirection());

		glm::vec3 reflect = glm::reflect(v, n);

		Ray reflect_ray = ray.spawn(t, reflect, 10);

		glm::vec3 reflect1 = state.rayTrace(reflect_ray);
		return glm::vec3(reflect1);
	}
예제 #6
0
	glm::vec3 rayTrace(Ray &ray, const float& t, const glm::vec3& normal, RayTracerState& state) {
		const float eta_air = 1.000293f;
		const float eta_carbondioxide = 1.00045f;
		const float eta_water = 1.3330f;
		const float eta_ethanol = 1.361f;
		const float eta_pyrex = 1.470f;
		const float eta_diamond = 2.419f;

		const float eta0 = eta_air;
		const float eta1 = eta_water;

		float eta = eta0/eta1;
		float R0 = pow((eta0-eta1)/(eta0+eta1), 2.0f);

		glm::vec3 n = normal;
		glm::vec3 v = ray.getDirection();

	
		float fresnel;

		glm::vec3 reflect;
		glm::vec3 refract;
		/*
		if(glm::dot(v, n) <= 0) { 
			// enter
			R0 = pow((eta0-eta1)/(eta0+eta1), 2.0f);
			eta = eta0/eta1;

			newRefractDir = glm::refract(v, n, eta);
			newReflectDir = glm::reflect(v, n);
			fresnel = R0 + (1.0f-R0)*glm::pow((1.0f-glm::dot(-v, n)), 5.0f);
		} else { 
			// exit
			R0 = pow((eta1-eta0)/(eta0+eta1), 2.0f);
			eta = eta1/eta0;

			newRefractDir = glm::refract(v, -n, eta);
			newReflectDir = glm::reflect(v, -n);
			fresnel = R0 + (1.0f-R0)*glm::pow((1.0f-glm::dot(newRefractDir, n)), 5.0f);
		}
		
		if(glm::dot(v, n) <= 0) { // enter
			R0 = pow((eta0-eta1)/(eta0+eta1), 2.0f);
			eta = eta0/eta1;
			refract = glm::refract(v, n, eta);
			reflect = glm::reflect(v, n);
			fresnel = R0 + (1.0f-R0)*glm::pow((1.0f-glm::dot(-v, n)), 5.0f);
			
		} else { //exit
			R0 = pow((eta1-eta0)/(eta0+eta1), 2.0f);
			eta = eta1/eta0;
			//reflect = glm::reflect(v, n);
			//refract = glm::refract(v, n, eta);
			refract = glm::refract(v, -n, eta);
			reflect = glm::reflect(v, -n);
			fresnel = R0 + (1.0f-R0)*glm::pow((1.0f-glm::dot(refract, n)), 5.0f);
		} */
		if(glm::dot(v, n) >= 0) { // exiting
			
			R0 = pow((eta1-eta0)/(eta0+eta1), 2.0f);
			eta = eta1/eta0;
			//fresnel = R0 + (1.0f-R0)*pow((1.0f-glm::dot(v, n)), 5.0f);
			
			//reflect = glm::reflect(v, n);
			//refract = glm::refract(v, n, eta);
			refract = glm::refract(v, -n, eta);
			reflect = glm::reflect(v, -n);
			fresnel = R0 + (1.0f-R0)*glm::pow((1.0f-glm::dot(refract, n)), 5.0f);
		} else { //entering
			
			R0 = pow((eta0-eta1)/(eta0+eta1), 2.0f);
			eta = eta0/eta1;
			refract = glm::refract(-v, n, eta);
			reflect = glm::reflect(-v, n);
			fresnel = R0 + (1.0f-R0)*glm::pow((1.0f-glm::dot(-v, n)), 5.0f);

		}

		Ray reflect_ray = ray.spawn(t, reflect, 10);
		Ray refract_ray = ray.spawn(t, refract, 10);

		glm::vec3 reflect1 = state.rayTrace(reflect_ray);
		glm::vec3 refract1 = state.rayTrace(refract_ray);

		refract1 *= glm::vec3(eta, 1.0f, eta);

		//return normal;
		return glm::mix(refract1, reflect1, fresnel);
		//return refract1;
	}
	glm::vec3 rayTrace(Ray &ray, const float& t, const glm::vec3& normal, RayTracerState& state) {
		return state.rayTrace(ray.spawn(t, glm::reflect(ray.getDirection(), normal), ray.getColorContribution() - absorb_amount));
	}