Ejemplo n.º 1
0
	/**
	* 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);
		}
	}
Ejemplo n.º 2
0
// Found uncorrected value by solving equation. This is OK since
// unrefract is never called in loops.
//
// Convergence is quite fast just a few iterations.
double SkyPoint::unrefract(const double alt) {
    double h0 = alt;
    double h1 = alt - (refract( h0 ) - h0); // It's probably okay to add h0 in refract() and subtract it here, since refract() is called way more frequently.

    while( fabs(h1 - h0) > 1e-4 ) {
        h0 = h1;
        h1 = alt - (refract( h0 ) - h0);
    }
    return h1;
}
Ejemplo n.º 3
0
glm::vec3 indirect(const glm::vec3 &c, const glm::vec3 &p, const glm::vec3 &n, const Glass &glass, int iterations)
{
    float ior = 1.5f;

    // Calcul du rayon réfléchi
    glm::vec3 direction = reflect(c,n);
    glm::vec3 directionNorm = glm::normalize(direction);
    Ray rayReflexion{p+directionNorm*0.1f, directionNorm};

    // Calcul du rayon réfracté
    glm::vec3 vecRefract;
    refract(-c, n, ior, vecRefract);
    Ray rayRefraction{p+vecRefract*0.1f, vecRefract};

    // Calcul du coefficient reflechi/refracte

    float coeff = fresnelR(-c, n, ior);

    float rand = random_u();

    if (rand < coeff)
    {
        return radiance(rayReflexion, iterations-1);
    }
    return radiance(rayRefraction, iterations-1) * glass.color;

    //return radiance(rayReflexion, iterations-1) * coeff + radiance(rayRefraction, iterations-1) * (1- coeff);
}
Ejemplo n.º 4
0
Archivo: bsdf.cpp Proyecto: SsnL/Fluid
Spectrum GlassBSDF::sample_f(const Vector3D& wo, Vector3D* wi, float* pdf) {

  // TODO Part 5:
  // Compute Fresnel coefficient and either reflect or refract based on it.
  if (!refract(wo, wi, ior)) {
    reflect(wo, wi);
    *pdf = 1.0;
    return reflectance * (1.0 / fabs(wi->z));
  }
  double R = (ior - 1.0) * (ior - 1.0) / (ior + 1.0) / (ior + 1.0);
  double c = 1.0 - fabs(wi->z);
  R = R + (1.0 - R) * c * c * c * c * c;
  if (coin_flip(R)) {
    reflect(wo, wi);
    *pdf = R;
    return reflectance * (R / fabs(wi->z));
  }
  *pdf = 1.0 - R;
  double nr;
  if (wi->z > 0) {
    nr = ior;
  } else {
    nr = 1.0 / ior;
  }
  return transmittance * ((1.0 - R) * nr * nr / fabs(wi->z));
}
Ejemplo n.º 5
0
t_bool          dielectric(t_material *material, const t_ray *r, const t_hit_record *h, t_vec3 *attenuation, t_ray *scattered)
{
    t_vec3      outward_normal;
    t_vec3      reflected;
    t_vec3      refracted;
    float       ni_over_nt;
    float       reflect_probe;
    float       cosine;

    vec3_reflect(&reflected, &RAY_DIRECTION(r), &h->normal);
    vec3_assign(attenuation, &material->texture.albedo);
    if (vec3_dot(&RAY_DIRECTION(r), &h->normal) > 0)
    {
        vec3_mul_f(&outward_normal, &h->normal, -1.f);
        //TODO pass idx
        ni_over_nt = REF_IDX;
        cosine = REF_IDX * vec3_dot(&RAY_DIRECTION(r), &h->normal) / vec3_length(&RAY_DIRECTION(r));
    }
    else
    {
        vec3_assign(&outward_normal, &h->normal);
        ni_over_nt = 1.0f / REF_IDX;
        cosine = - vec3_dot(&RAY_DIRECTION(r), &h->normal) / vec3_length(&RAY_DIRECTION(r));
    }
    if (refract(&RAY_DIRECTION(r), &outward_normal, ni_over_nt, &refracted))
        reflect_probe = schlick(cosine, REF_IDX);
    else
        reflect_probe = 1.0f;
    if (drand48() < reflect_probe)
        ray_assign(scattered, &h->pos, &reflected);
    else
        ray_assign(scattered, &h->pos, &refracted);
    return (TRUE);
}
Ejemplo n.º 6
0
static void Vector4Refract(benchmark::State& state) {
    Vector4 a(0.2, 0.2, 0.3), n(0, 1, 0), r;
    benchmark::DoNotOptimize(a);
    benchmark::DoNotOptimize(n);
    for (auto _ : state) {
        r = refract(a, n, 1.0, 1.3);
        benchmark::DoNotOptimize(r);
    }
}
Ejemplo n.º 7
0
Color Refr::shade(const Ray& ray, const IntersectionInfo& info)
{
// ior = eta2 / eta1
	Vector refr;
	if (dot(ray.dir, info.normal) < 0) {
		// entering the geometry
		refr = refract(ray.dir, info.normal, 1 / ior);
	} else {
		// leaving the geometry
		refr = refract(ray.dir, -info.normal, ior);
	}
	if (refr.lengthSqr() == 0) return Color(0, 0, 0);
	Ray newRay = ray;
	newRay.start = info.ip - faceforward(ray.dir, info.normal) * 0.000001;
	newRay.dir = refr;
	newRay.depth++;
	return raytrace(newRay) * multiplier;
}
Ejemplo n.º 8
0
/*******
 Fonction à écrire par les etudiants
 ******/
Color trace_ray (Ray ray_) {
/**
 * \todo : recursive raytracing
 *
 * La fonction trace_ray() renvoie une couleur obtenue par la somme de l'éclairage direct (couleur calculée par la fonction 
 * compute_direct_lighting()) et des couleurs provenant des reflets et transparences éventuels aux points d'intersection. 
 * Dans la première partie du TP, seul l'éclairage direct sera calculé. Dans la seconde partie, les reflets et transparences seront rajoutés.
 *
 * Pour la première étape, la fonction trace_ray() ne calculant que les rayons primaires, l'intersection 
 * entre le rayon et la scène doit être calculée (fonction intersect_scene() du module \ref RayAPI).
 * S'il n'y a pas d'intersection, une couleur blanche (triplet RGB [1, 1, 1], élément neutre de la multiplication des couleurs) 
 * devra être retournée.
 * S'il y a une intersection, la couleur retournée sera la couleur résultante de l'éclairage direct du point d'intersection par les 
 * sources lumineuses de la scène et calculée par la fonction compute_direct_lighting() à écrire dans la suite.
 *
 * Pour la deuxième étape, à partir des fonctions définies dans le module \ref RayAPI et permettant d'accéder aux informations de 
 * profondeur et d'importance sur le rayon, définir un cas d'arêt dela récursivité et renvoyer si ce cas est vérifié la couleur 
 * résultante de l'éclairage direct. Si la récursivité n'est pas terminée, en utilisant les fonctions définies dans le module \ref LightAPI,
 * calculer la couleur réfléchie. Pour cela, il  faut tester si le matériau est réflechissant et, si c'est le cas, calculer le rayon 
 * réfléchi et le coefficient de réflexion (une couleur). La couleur calculée en lançant le rayon réfléchi devra alors être multipliée par ce coefficient avant d'être ajoutée
 * à la couleur renvoyée par trace_ray().
 *
 * Pour la troisème étape et de façon très similaire à la réflexion, utiliser les fonctions définies dans le module \ref LightAPI pour calculer la couleur réfractée.
 * Pour cela, il  faut tester si le matériau est transparent et, si c'est le cas, calculer le rayon réfracté et le coefficient de 
 * transparence (une couleur). La couleur calculée en lançant le rayon réfracté devra alors être multipliée par ce coefficient avant
 * d'être ajoutée à la couleur renvoyée par trace_ray().
 *
*/

	Color l = init_color (0.075f, 0.075f, 0.075f);
	Isect isect_;
	
	int isInter = intersect_scene (&ray_, &isect_ );
	
	if (isInter!=0){
	  l = compute_direct_lighting (ray_, isect_);
	}
	
	if (ray_depth(ray_)>10 || ray_importance(ray_)<0.01f)
	  return (l);
	
	//reflection
	if(isect_has_reflection(isect_)){
		Ray refl_ray;
		Color refl_col = reflect(ray_, isect_, &refl_ray);
		l = l+refl_col*(trace_ray(refl_ray));
	}
	//refraction
	if(isect_has_refraction(isect_)){
	 Ray rafr_ray;
	 Color rafr_col = refract(ray_, isect_, &rafr_ray);
	 if(color_is_black(rafr_col)==0)
	  l = l+rafr_col*(trace_ray(rafr_ray));
	}

	return l;
}
Ejemplo n.º 9
0
Spectrum RefractionBSDF::sample_f(const Vector3D& wo, Vector3D* wi, float* pdf) {

  // TODO:
  // Implement RefractionBSDF

  refract(wo,wi,this->ior);
  *pdf = 1;
  return this->transmittance;

  // return Spectrum();
}
Ejemplo n.º 10
0
void Refr::spawnRay(const IntersectionInfo& x, const Vector& w_in,
						Ray& w_out, Color& out_color, float& pdf)
{
	Vector refr;
	if (dot(w_in, x.normal) < 0) {
		// entering the geometry
		refr = refract(w_in, x.normal, 1 / ior);
	} else {
		// leaving the geometry
		refr = refract(w_in, -x.normal, ior);
	}
	if (refr.lengthSqr() == 0) {
		pdf = 0;
		return;
	}
	w_out.dir = refr;
	w_out.start = x.ip + w_out.dir * 1e-6;
	w_out.flags &= ~RF_DIFFUSE;
	out_color = Color(1, 1, 1) * multiplier;
	pdf = 1;
}
Ejemplo n.º 11
0
Spectrum GlassBSDF::sample_f(const Vector3D& wo, Vector3D* wi, float* pdf) {

  // TODO Part 5:
  // Compute Fresnel coefficient and either reflect or refract based on it.
  double no, ni;
  if (wo.z < 0) {
    //r = ior/1;
    no = ior;
    ni = 1.0;
  } else {
    //r = 1.0/ior;
    no = 1.0;
    ni = ior;
  }

  bool totalIR = refract(wo, wi, ior);
  if (!totalIR) {

    reflect(wo, wi);
    *pdf = 1.0;
    return reflectance / abs_cos_theta(*wi);

  } else {
    float Ro = ((no - ni)/ (no + ni)) * ((no - ni)/ (no + ni));
    float R = Ro + (1.0 - Ro)*pow((1.0 - abs_cos_theta(wo)), 5.0);
    R = clamp(R, 0.0, 1.0);
    if (coin_flip(R)) {
      reflect(wo, wi);
      *pdf = R;
      return R * (reflectance / abs_cos_theta(*wi));
    } else {
      refract(wo, wi, ior);
      *pdf = 1.0 - R;
      //double r;

      //printf("%s\n", "here");
      return (1.0 - R) * (transmittance * no/ni * no/ni) / abs_cos_theta(*wi);
    }
  }
}
Ejemplo n.º 12
0
void InspectionShader::shade( Scene & scene, RandomNumberGenerator & rng, RayIntersection & intersection )
{
    RGBColor color( 0.0f, 0.0f, 0.0f );
    const float index_in = intersection.ray.index_of_refraction;
    const float index_out = intersection.material->index_of_refraction;
    const Vector4 from_dir = intersection.fromDirection();

    switch( property ) {
        case FresnelDialectric:
            {
                Vector4 refracted = refract( from_dir, intersection.normal, index_in, index_out );
                float fresnel = 1.0f;
                if( refracted.magnitude() > 0.0001 ) {
                    fresnel = Fresnel::Dialectric::Unpolarized( dot( from_dir, intersection.normal ),
                                                                dot( refracted, intersection.normal.negated() ),
                                                                index_in,
                                                                index_out );
                }
                color = RGBColor( fresnel, fresnel, fresnel );
            }
            break;
        case FresnelConductor:
            {
                float absorptionCoeff = 2.0; // FIXME: material specific
                float fresnel = Fresnel::Conductor::Unpolarized( dot( from_dir, intersection.normal ), index_out, absorptionCoeff );
                color = RGBColor( fresnel, fresnel, fresnel );
            }
            break;
        case Normal:
            {
                auto shifted = add( scale( intersection.normal, 0.5 ),
                                    Vector4( 0.5, 0.5, 0.5 ) );
                color = RGBColor( shifted.x, shifted.y, shifted.z );
            }
            break;
        case IndexOfRefraction:
            {
                float v = index_out / 3.0;
                color = RGBColor( v, v, v );
            }
            break;
        case TextureUVCoordinate:
            {
                color = RGBColor( intersection.u, intersection.v, 0.0 );
            }
            break;
        default:
            ;
    }

    intersection.sample.color = color;
}
Ejemplo n.º 13
0
void Raytracer::Trace(const Ray& aRay, Color* aColor, int aDepth)
{
	aq_float T;
	
	Intersection RayIntersection;

	if (!mScene->Intersect(aRay, &T, &RayIntersection))
	{
		*aColor = mScene->Properties.BackgroundColor;
		return;
	}
	
	*aColor = COLOR::BLACK;

	for (Light* light : mScene->GetLights())
	{
		*aColor += Shade(aRay, RayIntersection, *light);
	}

	*aColor = clamp(*aColor, 0.0, 100.0);

	//Russian roulette for stopping recursive
	if (aDepth > mScene->Properties.RecursiveDepth)
	{
		aq_float AvgReflectance = sum(RayIntersection.Mat.kr) / 3;
		if (AvgReflectance < Utils::RandFloatInterval(0.0, 1.2))
		{
			return;
		}
	}

	//Ambient occlusion
	//*aColor += 0.2 * IndirectLighting(aRay, RayIntersection, aDepth);

	//Reflection
	if (sum(RayIntersection.Mat.kr) > 0)
	{
		Ray ReflectedRay(RayIntersection.Local.Pos, reflect(aRay.Dir, RayIntersection.Local.Normal));
		Color ReflectedColor;
		Trace(ReflectedRay, &ReflectedColor, aDepth + 1);
		*aColor = mix(*aColor, ReflectedColor, RayIntersection.Mat.kr);
	}

	////Refraction
	if (RayIntersection.Mat.Transparency > 0)
	{
		Ray RefractedRay(RayIntersection.Local.Pos, refract(aRay.Dir, RayIntersection.Local.Normal, RayIntersection.Mat.RefractiveIndex));
		Color RefractedColor;
		Trace(RefractedRay, &RefractedColor, aDepth + 1);
		*aColor = mix(*aColor, RefractedColor, RayIntersection.Mat.Transparency);
	}
}
Ejemplo n.º 14
0
    Color3f sample(BSDFQueryRecord &bRec, const Point2f &sample) const {        

        // sample the mirco scale normal
        Vector3f m = Microfacet::sample(m_alpha, sample);

        float pdf = Microfacet::pdf(m_alpha, m);
        if(pdf == 0.0) {
            std::cout << "sample pdf should nearly never be zero";
            return Color3f(0.0f);
        }

        float wiDotM = bRec.wi.dot(m);
        float cosThetaT = 0.0f;
        float F = dielectricReflectance(wiDotM, cosThetaT, m_intIOR / m_extIOR);


        bool sampleReflection = true;

        // check if reflection or refraction
        // for reuseable sample
        if(bRec.sampler->next1D() > F) {
            sampleReflection = false;
        }

        if (sampleReflection) {
            bRec.wo = 2.0f * wiDotM * m - bRec.wi;;
            bRec.eta = 1.0f;

            /* Side check */
            if (Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) <= 0)
                return Color3f(0.0f);

        } else {
            if (cosThetaT == 0)
                return Color3f(0.0f);
            bRec.wo = refract(bRec.wi, m, m_intIOR / m_extIOR, cosThetaT);
            bRec.eta = cosThetaT < 0 ? m_intIOR / m_extIOR : m_extIOR / m_extIOR;

            /* Side check */
            if (Frame::cosTheta(bRec.wi) * Frame::cosTheta(bRec.wo) >= 0)
                return Color3f(0.0f);


        }

        float G = Microfacet::G(m_alpha, bRec.wi, bRec.wo, m);
        float D = Microfacet::D(m_alpha, m);

        return std::abs(D * G * bRec.wi.dot(m) / (pdf * Frame::cosTheta(bRec.wi)));
    }
Ejemplo n.º 15
0
DistributionSample
RefractiveMaterial::sampleBxDF( RandomNumberGenerator & rng,
                                const RayIntersection & intersection ) const
{
    // Perfect Fresnel refractor
    DistributionSample sample;

    const float index_in = intersection.ray.index_of_refraction;
    const float index_out = index_of_refraction;
    const Vector4 from_dir = intersection.fromDirection();

    // FIXME: HACK - This assumes that if we hit the surface of an object with the same
    //        index of refraction as the material we're in, then we are moving back into
    //        free space. This might not be true if there are numerical errors tracing
    //        abutting objects of the same material type, or for objects that are intersecting.
    if( index_out == index_in ) {
        sample.new_index_of_refraction = 1.0f;
    }

    Vector4 refracted = refract( from_dir, intersection.normal, index_in, index_out );
    float fresnel = 1.0f; // default to total internal reflection if refract() returns
    // a zero length vector
    if( refracted.magnitude() > 0.0001 ) {
        fresnel = Fresnel::Dialectric::Unpolarized( dot( from_dir, intersection.normal ),
                                                    dot( refracted, intersection.normal.negated() ),
                                                    index_in,
                                                    index_out );
    }

    const float draw = rng.uniform01();

    // Use RNG to choose whether to reflect or refract based on Fresnel coefficient.
    //   Random selection accounts for fresnel or 1-fresnel scale factor.
    if( fresnel == 1.0f || draw < fresnel ) {
        // Trace reflection (mirror ray scaled by fresnel or 1 for total internal reflection)
        sample.direction = mirror( from_dir, intersection.normal );
        // FIXME - How do we determine pdf_sample for total internal reflection?
        sample.pdf_sample = fresnel;
        sample.new_index_of_refraction = index_in;
    }
    else {
        // Trace refraction (refracted ray scaled by 1-fresnel)
        sample.direction = refracted;
        sample.pdf_sample = 1.0 - fresnel;
        sample.new_index_of_refraction = index_out;
    }

    return sample;
}
Ejemplo n.º 16
0
bool Tracer::scatterRefractive(const IntersectDescr& node, Ray& ray) const
{
	// here we throw the dice to dices whether to reflect or to refract
	const double probability = ::uniform_distrib_( ::rand_gen_ );

	// heuristic to determine material transition
	// note, this assumes that only one type of refractive material exists AND
	// that two objects do not intersect, such that an interface within a
	// non-air material exists (well, its not that strict, but simpler to
	// explain this way)
	const double surface_dot = node.normal_.dot( node.incident_ );
	const bool is_entry = ( surface_dot <= 0. );
	// 1.52 is for crown glass
	const double refractive_idx_from = is_entry ? 1.0 : 1.52;
	const double refractive_idx_to = is_entry ? 1.52 : 1.0;

	// The reflectance and refract functions require the normal to point into
	// the direction of the first material. If this is not the case, we invert
	// its direction.
	const Vector corrected_normal = is_entry ? node.normal_ : -1. * node.normal_;
		
	const double reflect = reflectance(
		corrected_normal, node.incident_, refractive_idx_from, refractive_idx_to );

	if( probability <= reflect )
	{
		return scatterSpecular( node, ray );
	}
	else
	{
		Vector refracted_dir = refract( corrected_normal,
										node.incident_,
										refractive_idx_from,
										refractive_idx_to );

		if( refracted_dir.length() > 1e-4 )
		{
			ray = Ray{ node.point_, refracted_dir.normalized() };
			return true;
		}
		else
		{
			return false;
		}
	}

	return false; // should never get here, though
}
Ejemplo n.º 17
0
nex::color fresnel_refraction_btdf::sample(const lumen::sample& sample, const surface& surface,
        const nex::vector& wo, nex::vector* wi, float* pdf) const
{
        float eta = ni / nt;

        *wi = refract(wo, surface.normal, &eta);
        *pdf = 1.0f;

        // check for total internal reflection
        if (*wi == nex::vector(0.0f, 0.0f, 0.0f)) {
                return nex::color::black();
        }

        return (1.0f - fresnel(ni, nt, nex::dot(surface.normal, wo))) *
               transmittance / (eta * eta) / std::abs(nex::dot(surface.normal, *wi));
}
Ejemplo n.º 18
0
extern "C" void execute(void *params, BVHShader_functions *func, void *env)
{
	BVHShader_surface *surface = (BVHShader_surface*)env;
	BVHShader_params *p = (BVHShader_params*)params;

	float rayRefract[3];
	float rayReflect[3];
	BVHColor colorRefraction;
	BVHColor colorReflection;
	float fresnelFactor;

	// Calculate refraction ray
	refract(surface->normal, surface->rayInput, rayRefract, p->indexRel);
	invert(rayRefract);
	normalize(rayRefract);

	// Calculate reflection ray
	reflect(surface->normal, surface->rayInput, rayReflect);
	invert(rayReflect);
	normalize(rayReflect);

	// Normalize vector
	normalize(surface->rayOutput);

	// Get fresnel
	fresnelFactor = fresnel(surface->normal, surface->rayInput, p->indexRel);

	// Calculate reflection and refraction color
	if (dotAbs(surface->rayOutput, rayRefract) > 0.9999f)
	{
		colorRefraction.init(1.0f / dotAbs(surface->rayOutput, surface->normal));
		colorReflection.init(0.0f);
	}
	else if (dotAbs(surface->rayOutput, rayReflect) > 0.9999f)
	{
		colorRefraction.init(0.0f);
		colorReflection.init(1.0f / dotAbs(surface->rayOutput, surface->normal));
	}
	else
	{
		colorRefraction.init(0.0f);
		colorReflection.init(0.0f);
	}

	surface->color = p->color * (colorRefraction * (1.0f - fresnelFactor) + colorReflection * fresnelFactor);
	surface->emission.init(0.0f);
}
Ejemplo n.º 19
0
void propagate(ray_array& rays, const T& lens,
               double step_size, double max_vel,
               std::ofstream& output) {

    // move simulation every timestep
    for (auto& ray : rays) {
        for (size_t i = 0; i < TIME_RES; i+= 1) {
            if (ray.p.x > lens.origin.x + lens.radius + 1) {
                continue;
            }
            ray.p += ray.v * step_size;

            double n1 = ray.previous_index;
            double n2 = refractive_index_at(lens, ray.p);

            // If the ray passed through a refraction index change
            if (n1 != n2) {
                vec n = normal_at(lens, ray.p);
                vec l = normalize(ray.v);
                double ior = n1 / n2;

                if (dot(-n, l) < 0.0) {
                    n = -n;
                }

                vec speed = refract(l, n, ior);

                if (is_null(speed)) {
                    speed = reflect(l, n);
                }

                // Multiply with ior * length(ray.v) to get the proper velocity
                // for the refracted vector
                ray.v = normalize(speed) * ior * length(ray.v);
            }

            ray.previous_index = n2;

            if (i % 1000 == 0) {
                output << ray.p.x <<'\t'<< ray.p.y << '\t'
                       << ray.v.x <<'\t'<< ray.v.y << '\n';
            }
        }
        output << '\n' << '\n';
    }

}
Ejemplo n.º 20
0
glm::vec3 indirect(const Ray &rOrigine, const Ray &rReflect, const glm::vec3 &p,  const glm::vec3 & n, int countdown, const Glass &glass) {

    float fresnel = fresnelR(-rOrigine.direction,n, 1.5);
    glm::vec3 refracted;
    bool canRefract = refract(-rOrigine.direction, n, 1.5, refracted);
    Ray rRefracted{p+refracted*0.1f, refracted};
    if(canRefract) {
        float u = random_u();
        if(u < fresnel)
            return radiance(rReflect, countdown);
        else
            return radiance(rRefracted, countdown);
    }
        //return fresnel*radiance(rReflect, countdown)+(1-fresnel)*radiance(rRefracted, countdown);
    else
        return fresnel*radiance(rReflect, countdown);
}
Ejemplo n.º 21
0
a3Spectrum a3Dieletric::sample(const t3Vector3f& wi, t3Vector3f& wo, float* pdf, const a3Intersection& its) const
{
    static a3Random random;

    t3Vector3f n = its.getNormal();

    // 入射光 / 出射光所在折射率
    float etai = 1.0f, etat = its.shape->refractiveIndex;

    // 光密到光疏
    if(wi.dot(n) > 0)
    {
        t3Math::swap(etai, etat);
        // 翻转法线 保持与入射光线一个平面
        n = -n;
    }

    float eta = etai / etat;

    // 菲涅尔反射(反射的概率)
    //float Fr = a3FresnelDielectric(costhetai, costhetat, etai, etat);
    float Fr = reflectance(n, wi, etai, etat);
    //float P = 0.25 + 0.5 * Fr;

    float r = random.randomFloat();
    if(r > Fr)
    {
        bool TIR = false;
        wo = refract(n, wi, etai, etat, TIR);

        *pdf = 1.0f;

        eta = 1 / eta;
        return getColor(its) * specularTransmittance / t3Math::Abs(wo.dot(n));
    }
    else
    {
        wo = reflect(n, wi);

        *pdf = 1.0f;

        // 镜面反射
        return getColor(its) * specularReflectance / t3Math::Abs(wo.dot(n));
    }
}
Ejemplo n.º 22
0
bool RayBouncer::RefractionBounce( RayBounce& raybounce, const Ray& ray, const Scene& scene, const RayShader& shader, const PrimitiveHit& primitivehit, const real& ior1, const real& ior2, std::size_t depth ) const {
	const Primitive& primitive = primitivehit.first;
	const PrecalculatedMaterial& material = primitivehit.second;
	const Hit& hit = primitivehit.third;

	bool hastransparency = std::any_of( material.refractivity.begin( ), material.refractivity.end( ), real_compare<std::less<>, 1>( ) );
	if ( !hastransparency )
		return false;

	Fur::optional<vec3> oprefractionraydir = refract( ray.direction, hit.inside ? hit.normal * real_neg_one : hit.normal, ior1, ior2 );
	if ( !oprefractionraydir )
		return false;

	// Not total internal reflection
	const vec3& refractionraydir = *oprefractionraydir;
	Ray refractionray( hit.contact + refractionraydir * scene.Bias(), refractionraydir );
	raybounce.ray = refractionray;
	Bounce( raybounce, refractionray, scene, shader, primitivehit, depth + 1 );
	return true;
}
Ejemplo n.º 23
0
bool Dielectric::scatter(const Ray& r_in, const HitRecord& record, vec3& attenuation, Ray& scattered) const
{
	vec3 outward_normal;
	vec3 reflected = reflect(r_in.direction(), record.normal);
	float ni_over_nt;
	attenuation = vec3(1,1,1);
	vec3 refracted;
	float reflect_probability;
	float cosine;
	if (dot(r_in.direction(), record.normal) > 0)
	{
		outward_normal = -record.normal;
		ni_over_nt = refractive_index;
		cosine = refractive_index * dot(r_in.direction(), record.normal) / r_in.direction().length();
	}
	else
	{
		outward_normal = record.normal;
		ni_over_nt = 1.0f / refractive_index;
		cosine = -dot(r_in.direction(), record.normal) / r_in.direction().length();
	}

	if (refract(r_in.direction(), outward_normal, ni_over_nt, refracted))
	{
		reflect_probability = schlick(cosine, refractive_index);
	}
	else
	{
		reflect_probability = 1.0f;
	}

	if (drand48() < reflect_probability)
	{
		scattered = Ray(record.point, reflected); // REFLECT vs
	}
	else
	{
		scattered = Ray(record.point, refracted); // REFRACT !!
	}
	return true;
}
Ejemplo n.º 24
0
Vector3D Ray::Refract(Intersection &inter, Environment &env, int recursion) {
	Vector3D position = source + direction * inter.dist;

	double n1, n2;
	if(ior - 1.0 < 1.0e-6) {
		n1 = 1.0;
		n2 = inter.obj->surface().refracao;
	} else {
		n1 = inter.obj->surface().refracao;
		n2 = 1.0;
	}

	Vector3D refract_direction = refract(inter.obj->Normal(position), direction, n1, n2);
	if(refract_direction[0] <= -499) {
		return BACKGROUND_COLOR;
	}

	Ray refraction(position, refract_direction.Normalize());
	refraction.ior = n2;

	return refraction.Trace(env, recursion + 1);
}
Ejemplo n.º 25
0
Spectrum GlassBSDF::sample_f(const Vector3D& wo, Vector3D* wi, float* pdf) {

  // TODO:
  // Compute Fresnel coefficient and either reflect or refract based on it.
  *pdf = 1.f;
  if (!refract(wo, wi, ior)) {
      reflect(wo, wi);
      return this->reflectance * (1.f / fabs(wo.z));
    }

    double ni, nt;

    if (wo.z > 0) {
      ni = 1;
      nt = ior;
    } else {
      ni = ior;
      nt = 1;
    }

    double cosi = fabs(wo.z);
    double cost = fabs(wi->z);

    double rpar = ((nt*cosi) - (ni*cost)) / ((nt*cosi) + (ni*cost));
    double rver = ((ni*cosi) - (nt*cost)) / ((ni*cosi) + (nt*cost));

    double fresnel = (rpar*rpar + rver*rver) / 2.f;

    if((double)(std::rand()) / RAND_MAX <= fresnel){
      reflect(wo, wi);
      return this->reflectance * (1.f / fabs(wo.z));
    }
    else{
      return transmittance * double((nt*nt)/(ni*ni) * (1-fresnel) / fabs(cosi));
    }


  // return Spectrum();
}
Ejemplo n.º 26
0
bool RayTracer::shade(SbVec3f *ray_origin, SbVec3f *ray_direction, SbVec3f *retColor, int recursionDepth, int flag){
	float t_value, t_min = 999;
	float epsilon = 0.01;
	SbVec3f normal_at_intersection;
	SbVec3f normal_at_intersection1, actual_ray_direction ;
	bool should_color = false;
    SbVec3f color;
    color[0] = 0.0;
    color[1] = 0.0;
    color[2] = 0.0;
    //Cone *tempCone = new Cone();
    for(int k =0; k<objects.size(); k++){
        //Object temp1 ;
        //temp1 = spheres.at(k);
        Sphere tempSphere;
        Cube tempCube;
        Cone tempCone;
        Object temp;
        bool intersects = false;
        int shapetype = 0;
        shapetype = objects.at(k).shapeType ;
        if(shapetype == 1){
            tempSphere = objects.at(k);
            intersects = tempSphere.intersection(ray_origin, ray_direction, &t_value);
        }
        else if (shapetype ==2){
            //std::cout<<"cube";
            tempCube = objects.at(k);
            intersects = tempCube.intersection(ray_origin, ray_direction, &t_value);
            //temp = (Cube)tempCube;
        }else{
            tempCone = objects.at(k);
            intersects = tempCone.intersection(ray_origin, ray_direction, &t_value);

        }

        if(intersects)
        {
            if(t_value < t_min && t_value > 0 && t_value !=999) {
                t_min = t_value;
                SbVec3f V = -(*ray_direction); //view vector
                V.normalize();
                SbVec3f point_of_intersection ;

                if(shapetype == 1){
                    normal_at_intersection = tempSphere.calculate_normal(ray_origin, ray_direction, t_value);
                    normal_at_intersection.normalize(); // N vector at the point of intersection
                    point_of_intersection = tempSphere.point_of_intersection( ray_origin, ray_direction, t_value);
                    temp = tempSphere;
                }else if(shapetype == 2){
                    normal_at_intersection = tempCube.calculate_normal(ray_origin, ray_direction, t_value);
                    normal_at_intersection.normalize(); // N vector at the point of intersection
                    point_of_intersection = tempCube.point_of_intersection( ray_origin, ray_direction, t_value);
                    temp = tempCube;
                }
                else{
                    normal_at_intersection = tempCone.calculate_normal(ray_origin, ray_direction, t_value);
                    normal_at_intersection.normalize(); // N vector at the point of intersection
                    point_of_intersection = tempCone.point_of_intersection( ray_origin, ray_direction, t_value);
                    temp = tempCone;

                }


                for(int i = 0; i <3; i++) {// set the ambient color component
                        color[i] = (0.2 *  temp.material->ambientColor[0][i] * (1 - temp.transparency ));
                }
                //*retColor = color; return true;//ntc
                // iterate through all the lights and add the diffuse and specular component
                for(int j = 0; j < lights.size(); j++){
                        SbVec3f poi;

                        actual_ray_direction = lights.at(j).position - point_of_intersection ;
                        actual_ray_direction.normalize();
                        poi = point_of_intersection + (epsilon * actual_ray_direction);
                        bool shadowFlag = false;
                        if(shadow_on == 0 || shadow_on == 1)
                        {
                            if(shadow_on == 1)
                                shadowFlag = shadow_ray_intersection(&poi, &actual_ray_direction , j );
                            //shadowFlag = true;
                            if(!shadowFlag)
                            {
                                SbVec3f L = lights.at(j).position - point_of_intersection;
                                L.normalize();
                                SbVec3f R;
                                R = (2 * normal_at_intersection.dot(L) * normal_at_intersection) - L;
                                R.normalize();

                                float NdotL = normal_at_intersection.dot(L);
                                float cos_theta = V.dot(R);

                                for(int i = 0; i <3; i++){
                                    if(NdotL > 0)
                                        color[i] += (( NdotL * temp.material->diffuseColor[0][i] * lights.at(j).intensity * lights.at(j).color[i]  * (1 - temp.transparency )));
                                    if(cos_theta > 0)
                                        color[i] += (( pow(cos_theta, 50) * temp.material->specularColor[0][i]* lights.at(j).intensity * lights.at(j).color[i]) );
                                }
                            }
                        }
                    else
                    { // soft shadows
                            {

                         //shadowLevel = soft_shadow_ray_intersection(&point_of_intersection, j );
                            SbVec3f actual_ray_direction, offset_ray_direction;
                            SbVec3f tempu, tempv, tempn;
                            int number_of_shadow_rays;
                            number_of_shadow_rays = NUMBER_OF_SHADOW_RAYS;
                            float epsilon = 0.01;
                            float R = 0.1;
                            actual_ray_direction = lights.at(j).position - point_of_intersection ;
                            actual_ray_direction.normalize();
                            SbVec3f point = point_of_intersection + (epsilon * actual_ray_direction);

                            calculate_coordinate_system(&tempu, &tempv, &tempn, actual_ray_direction);

                            for(int ir =0; ir< number_of_shadow_rays; ir++){

                                    float du, dv;
                                    //float t;
                                    du = get_random_number();
                                    dv = get_random_number();
                                    du = R * (du - 0.5);
                                    dv = R * (dv - 0.5);
                                    offset_ray_direction = actual_ray_direction + (du * tempu) + (dv * tempv);
                                    offset_ray_direction.normalize();

                                    //offset_ray_direction = actual_ray_direction - (R/2 * u) - (R/2 * v) + (du * R * u) + (dv *R * v);
                                    SbVec3f poi;
                                    poi = point + (epsilon * offset_ray_direction);
                                    //offset_ray_direction = actual_ray_direction;
                                    if(!shadow_ray_intersection(&poi, &offset_ray_direction, j)){
                                        //normal_at_intersection = temp.calculate_normal(&poi, &offset_ray_direction, t_value);
                                        //normal_at_intersection.normalize();
                                        SbVec3f V = -1 * (*ray_direction); //view vector
                                        V.normalize();
                                        SbVec3f L = offset_ray_direction;
                                        L.normalize();
                                        SbVec3f R;
                                        R = (2 * normal_at_intersection.dot(L) * normal_at_intersection) - L;
                                        R.normalize();

                                        float NdotL = normal_at_intersection.dot(L);
                                        float cos_theta = V.dot(R);
                                        //if(temp.transparency > 0) std::cout<<"trnas";
                                        for(int i = 0; i <3; i++){
                                            {
                                                if(NdotL > 0)
                                                    color[i] += (( NdotL * temp.material->diffuseColor[0][i] * lights.at(j).intensity * lights.at(j).color[i]  * (1 - temp.transparency ))/ number_of_shadow_rays);
                                                if(cos_theta > 0)
                                                    color[i] += (( pow(cos_theta, 50) * temp.material->specularColor[0][i]* lights.at(j).intensity * lights.at(j).color[i]) / number_of_shadow_rays);
                                            }
                                        }

                                    }

                    }

                    }

                        }
                }
                SbVec3f refColor(0.0,0.0,0.0);
                SbVec3f refracColor(0.0,0.0,0.0);
                // if the current depth of recustion is less than the maximum depth,
                //reflect the ray and add the color returned dude to the result of reflection
                //std::cout<<"here";
                if(refraction_on && recursionDepth < 2){
                    if(temp.isTransparent){
                        SbVec3f T;
                        if(refract(ray_direction, &normal_at_intersection, &T)){
                            T.normalize();
                            SbVec3f poi;
                            poi = point_of_intersection + (epsilon * T);
                            shade(&poi, &T, &refracColor, recursionDepth+1);
                            color = color + (temp.transparency * refracColor);
                        }

                    }
                }
                if(reflection_on && recursionDepth < 2){

                    if(temp.isShiny){//} && !temp.isTransparent){
                        // compute replection of the ray, R1
                        SbVec3f R1;
                        R1 = reflect(&normal_at_intersection, ray_direction);
                        SbVec3f poi;
                        poi = point_of_intersection + (epsilon * R1);
                        shade(&poi, &R1, &refColor, recursionDepth+1);
                        color = color + ((1 - temp.transparency) * temp.shininess * refColor);

                    }
                }

                should_color = true;
            }

        }
    }
    *retColor = color;
    return should_color;
}
Ejemplo n.º 27
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;
}
Ejemplo n.º 28
0
	Spectrum sample(BSDFQueryRecord &bRec, Float &pdf, const Point2 &sample) const {
		bool sampleReflection   = (bRec.typeMask & EDeltaReflection)
				&& (bRec.component == -1 || bRec.component == 0);
		bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
				&& (bRec.component == -1 || bRec.component == 1);
		
		if (!sampleTransmission && !sampleReflection)
			return Spectrum(0.0f);

		Float cosThetaI = Frame::cosTheta(bRec.wi),
			  etaI = m_extIOR,
			  etaT = m_intIOR;

		bool entering = cosThetaI > 0.0f;

		/* Determine the respective indices of refraction */
		if (!entering)
			std::swap(etaI, etaT);

		/* Using Snell's law, calculate the squared sine of the
		   angle between the normal and the transmitted ray */
		Float eta = etaI / etaT,
			  sinThetaTSqr = eta*eta * Frame::sinTheta2(bRec.wi);

		Float Fr, cosThetaT = 0;
		if (sinThetaTSqr >= 1.0f) {
			/* Total internal reflection */
			Fr = 1.0f;
		} else {
			cosThetaT = std::sqrt(1.0f - sinThetaTSqr);

			/* Compute the Fresnel refletance */
			Fr = fresnelDielectric(std::abs(cosThetaI),
				cosThetaT, etaI, etaT);

			if (entering)
				cosThetaT = -cosThetaT;
		}

		/* Calculate the refracted/reflected vectors+coefficients */
		if (sampleTransmission && sampleReflection) {
			/* Importance sample according to the reflectance/transmittance */
			if (sample.x <= Fr) {
				bRec.sampledComponent = 0;
				bRec.sampledType = EDeltaReflection;
				bRec.wo = reflect(bRec.wi);

				pdf = Fr * std::abs(Frame::cosTheta(bRec.wo));
				return m_specularReflectance->getValue(bRec.its) * Fr;
			} else {
				bRec.sampledComponent = 1;
				bRec.sampledType = EDeltaTransmission;

				/* Given cos(N, transmittedRay), compute the 
				   transmitted direction */
				bRec.wo = refract(bRec.wi, eta, cosThetaT);
					
				pdf = (1-Fr) * std::abs(Frame::cosTheta(bRec.wo));

				/* When transporting radiance, account for the solid angle
				   change at boundaries with different indices of refraction. */
				return m_specularTransmittance->getValue(bRec.its) 
					* (1-Fr) * (bRec.quantity == ERadiance ? (eta*eta) : (Float) 1);
			}
		} else if (sampleReflection) {
			bRec.sampledComponent = 0;
			bRec.sampledType = EDeltaReflection;
			bRec.wo = reflect(bRec.wi);
			pdf = std::abs(Frame::cosTheta(bRec.wo));
			return m_specularReflectance->getValue(bRec.its) * Fr;
		} else {
			bRec.sampledComponent = 1;
			bRec.sampledType = EDeltaTransmission;

			if (Fr == 1.0f) /* Total internal reflection */
				return Spectrum(0.0f);

			bRec.wo = refract(bRec.wi, eta, cosThetaT);
			pdf = std::abs(Frame::cosTheta(bRec.wo));

			/* When transporting radiance, account for the solid angle
			   change at boundaries with different indices of refraction. */
			return m_specularTransmittance->getValue(bRec.its) 
				* ((1-Fr) * (bRec.quantity == ERadiance ? (eta*eta) : (Float) 1));
		}
	}
Ejemplo n.º 29
0
static Color3 raycolor(const Scene* scene, RayInfo ray, int n)
{
	Geometry* const* geometry = scene->get_geometries();
	const PointLight* light = scene->get_lights();
	IntersectionInfo intersection;
	intersection.t0 = EP;
	intersection.t1 = 1000000;
	int index;
	for(int i=0; i<scene->num_geometries();i++)
	{
		Matrix4 inversematrix;
		make_inverse_transformation_matrix(&inversematrix, geometry[i]->position, geometry[i]->orientation, geometry[i]->scale );
		RayInfo rayinformation;
		rayinformation.origin = inversematrix.transform_point(ray.origin);
		rayinformation.direction = inversematrix.transform_vector(ray.direction);	
		bool check = geometry[i]->check_geometry(rayinformation,intersection);
		
		if(check)
		{
			index = i;
		}
	}

	Color3 color = Color3::Black;
	if(intersection.t1 != 1000000)
	{
			Matrix4 transmatrix;
		    make_transformation_matrix(&transmatrix, geometry[index]->position, geometry[index]->orientation, geometry[index]->scale );
		    intersection.worldposition = transmatrix.transform_point(intersection.localposition);
			Matrix3 normalmatrix;
			make_normal_matrix(&normalmatrix, transmatrix );
			intersection.worldnormal = normalize(normalmatrix*intersection.localnormal);
			color = intersection.material.ambient*scene->ambient_light;

			for(int i=0; i<scene->num_lights();i++)
			{   
				RayInfo shadowworldrayinfo;
				shadowworldrayinfo.origin = intersection.worldposition;
				shadowworldrayinfo.direction = normalize(light[i].position - intersection.worldposition);
				bool hit = false;
				IntersectionInfo shadowintersection;
				shadowintersection.t0 = EP;
				shadowintersection.t1 = length(light[i].position - intersection.worldposition);
				real_t d = dot(intersection.worldnormal,shadowworldrayinfo.direction);
				if(d > 0)
				{
					for(int j=0; j<scene->num_geometries();j++)
					{
						Matrix4 shadowinversematrix;
						make_inverse_transformation_matrix(&shadowinversematrix, geometry[j]->position, geometry[j]->orientation, geometry[j]->scale );
						RayInfo shadowlocalrayinfo;
						shadowlocalrayinfo.origin = shadowinversematrix.transform_point(shadowworldrayinfo.origin);
						shadowlocalrayinfo.direction = shadowinversematrix.transform_vector(shadowworldrayinfo.direction);	
						bool check = geometry[j]->check_geometry(shadowlocalrayinfo,shadowintersection);
						if(check == true)
						{
								hit = true;
								break;
						}
					 }
					if(hit == false)
					{
						color = color + intersection.material.diffuse*light[i].color*d;
					}
				}
			}
			RayInfo reflectionworldrayinfo;
			reflectionworldrayinfo.origin = intersection.worldposition;
			Vector3 r = ray.direction - 2*dot(ray.direction,intersection.worldnormal)*intersection.worldnormal;
			reflectionworldrayinfo.direction = normalize(r);
			n++;
			
			if(intersection.material.refractive_index != 0)
			{
				real_t judge = dot(ray.direction,intersection.worldnormal);
				real_t c;
				RayInfo refractionworldrayinfo;
				refractionworldrayinfo.origin = intersection.worldposition;
				real_t refractiveratio = scene->refractive_index/intersection.material.refractive_index;

				if(judge<0)
				{
					
					refract(ray, intersection.worldnormal, refractiveratio,refractionworldrayinfo);
					c = -dot(ray.direction,intersection.worldnormal);
				}
				else
				{
					if(refract(ray, -intersection.worldnormal, 1/refractiveratio,refractionworldrayinfo))
					{
						c = dot(refractionworldrayinfo.direction,intersection.worldnormal);
					}
					else
					{
						if(n<=MAXNUMBER)
						{
							return intersection.material.specular*raycolor(scene,reflectionworldrayinfo,n);
						}
					}
				}
				  real_t R0 = (intersection.material.refractive_index-1)*(intersection.material.refractive_index-1)/(intersection.material.refractive_index+1)/(intersection.material.refractive_index+1);
			      real_t R = R0 + (1-R0)*pow(1-c,5);
				  if(n<=MAXNUMBER)
				  {
					return intersection.material.specular*(R*raycolor(scene,reflectionworldrayinfo,n) + (1-R)*raycolor(scene,refractionworldrayinfo,n));
				  }
			}
			else
			{
				if(n<=MAXNUMBER)
				{
					color = color + intersection.material.specular*raycolor(scene,reflectionworldrayinfo,n);
				}
			}
			return color;
			
	}

	return scene->background_color;

}
Ejemplo n.º 30
0
    void RefractShader::generateDir(const SurfacePoint & sp,
                                const glm::vec3 & out,
                                unsigned numSamples,
                                BSDFSamples & samples) const
    {
        samples.resize (numSamples);

        // assume refraction index 1.0 for outer medium
        glm::float_t n1 = 1.0f;
        glm::float_t n2 = m_index;

        // normal should point to medium n1
        glm::vec3 normal = sp.normal;
        const glm::vec3 incident = -out;

        // Flip normal and count new n if the ray is coming from 
        // inside the surface (ie. from n2 to n1)
        if (sp.cos_theta(out) < 0) {
            normal = -normal;
            std::swap(n1, n2);
        }

        // n = n1 / n2 where ray comes from n1 to n2
        /*const glm::float_t n = n1 / n2;
        const glm::float_t cosI = glm::dot(normal, -incident);*/

        for (unsigned i = 0; i < numSamples; ++i)
        {
            glm::vec3 result, value;
                
            glm::vec3 refracted;
            glm::float_t refl;

            if(refract(n1, n2, normal, incident, refracted, refl))
            {
                // always reflect
                //refl = 1.0f;
                // always transmit
                //refl = 0.0f;

                assert(0 <= refl && refl <= 1);
                // choose between refracted and reflected rays based on fresnel term
                const glm::float_t roulette = Sampling::uniform();
                if(roulette < refl)
                {
                    // reflect
                    result = reflect(normal, incident);
                    value = (1 / refl) * (refl) * m_reflectance / sp.cos_theta(result);
                }
                else
                {
                    const real cos_theta = glm::dot(normal, result);
                    // transmit
                    result = refracted;
                    value = (1 / (1 - refl)) * (1 - refl) * m_transmittance / sp.cos_theta(result);
                }
            }
            else
            {
                result = reflect(normal, incident);
                value = m_reflectance / sp.cos_theta(result);
            }
            
            samples[i] = BSDFSample(result, value, 1);
        }
    }