Example #1
0
    /// Evaluate the BRDF for the given pair of directions
    Color3f eval(const BSDFQueryRecord &bRec) const {

        /* This is a smooth BRDF -- return zero if the measure
           is wrong, or when queried for illumination on the backside */
        if (bRec.measure != ESolidAngle
            || Frame::cosTheta(bRec.wi) <= 0
            || Frame::cosTheta(bRec.wo) <= 0)
            return Color3f(0.0f);

        Vector3f wh = (bRec.wi + bRec.wo).normalized();

        float cosThetai = Frame::cosTheta(bRec.wi);
        float cosThetao = Frame::cosTheta(bRec.wo);


        //compute the Beckman term
        float D =  Microfacet::D(m_alpha, wh) / Frame::cosTheta(wh);
        //float D = Warp::squareToBeckmannPdf(wh, m_alpha) / Frame::cosTheta(wh);


        //compute the Fresnel term
        float F = fresnel(wh.dot(bRec.wi), m_extIOR, m_intIOR);

        //compute the geometry term
        float G = Microfacet::G(m_alpha, bRec.wi, bRec.wo, wh);
        //float G = G1(bRec.wi, wh) * G1(bRec.wo, wh);

        return (m_kd * INV_PI) + (m_ks * ((D * F * G)/(4.0f * cosThetai * cosThetao)));
    }
Example #2
0
MyRGBColor
FresnelReflector::sample_f(const ShadeRec& sr,  Vector3D& wr, const Vector3D& wo) const{
	float ndotwo = sr.normal * wo;
	wr = -wo + 2.0 * sr.normal * ndotwo; 
	
	return (fresnel(sr) * white / fabs(sr.normal * wr));
}
Example #3
0
	Spectrum fDelta(const BSDFQueryRecord &bRec) const {
		bool sampleReflection   = (bRec.typeMask & EDeltaReflection)
				&& (bRec.component == -1 || bRec.component == 0);
		bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
				&& (bRec.component == -1 || bRec.component == 1);
		bool reflection = bRec.wo.z * bRec.wi.z > 0;
		Float fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
		
		if (sampleReflection && !sampleTransmission && !reflection) 
			return Spectrum(0.0f);
		else if (!sampleReflection && sampleTransmission && reflection)
			return Spectrum(0.0f);

		if (reflection) {
			return m_specularReflectance->getValue(bRec.its) * fr;
		} else {
			Float etaI = m_extIOR, etaT = m_intIOR;
			bool entering = Frame::cosTheta(bRec.wi) > 0.0f;
			if (!entering)
				std::swap(etaI, etaT);

			Float factor = (bRec.quantity == ERadiance) 
				? (etaI*etaI) / (etaT*etaT) : 1.0f;

			return m_specularTransmittance->getValue(bRec.its)  * factor * (1 - fr);
		}

	}
double Clothoid::calcD(double alpha) {
    double x, z;

    fresnel(sqrt(2 * alpha / PI), x, z);

    double d = cos(alpha) * (x)+ (sin(alpha) * z);
    return d;
}
void Clothoid::getXY(double s, double a, double b, double c, double& x, double& y) {
    double storeX, storeY;

    if (a > 0) {
        double limit_ = (b + 2 * a * s) / (sqrt(2 * fabs(a) * PI));
        fresnel(limit_, storeX, storeY);

        x = sqrt(PI / 2 / fabs(a))*((cos(b * b / 4 / a - c))*(storeX)+(sin(b * b / 4 / a - c))*(storeY));
        y = sqrt(PI / 2 / fabs(a))*((cos(b * b / 4 / a - c))*(storeY)-(sin(b * b / 4 / a - c))*(storeX));

        double x1, y1;
        limit_ = (b) / (sqrt(2 * fabs(a) * PI));
        fresnel(limit_, storeX, storeY);
        x1 = sqrt(PI / 2 / fabs(a))*((cos(b * b / 4 / a - c))*(storeX)+(sin(b * b / 4 / a - c))*(storeY));
        y1 = sqrt(PI / 2 / fabs(a))*((cos(b * b / 4 / a - c))*(storeY)-(sin(b * b / 4 / a - c))*(storeX));

        x -= x1;
        y -= y1;

    } else {

        a = -a;
        double limit_ = (2 * a * s - b) / (sqrt(2 * fabs(a) * PI));
        fresnel(limit_, storeX, storeY);


        x = sqrt(PI / 2 / fabs(a))*((cos(b * b / 4 / a + c))*(storeX)+(sin(b * b / 4 / a + c))*(storeY));
        y = sqrt(PI / 2 / fabs(a))*(-(cos(b * b / 4 / a + c))*(storeY)+(sin(b * b / 4 / a + c))*(storeX));

        double x1, y1;

        limit_ = (-b) / (sqrt(2 * a * PI));

        fresnel(limit_, storeX, storeY);

        x1 = sqrt(PI / 2 / fabs(a))*((cos(b * b / 4 / a + c))*(storeX)+(sin(b * b / 4 / a + c))*(storeY));
        y1 = sqrt(PI / 2 / fabs(a))*(-(cos(b * b / 4 / a + c))*(storeY)+(sin(b * b / 4 / a + c))*(storeX));
        x -= x1;
        y -= y1;
    }


}
Example #6
0
Color trace(Ray& ray, int i){
    if(!i) return Color(0,0,0);
    Obj* o;
    Vector x;
    Vector n;
    if(firstIntersect(ray, x, n, &o)<0) return La;
    Color c=directLight(ray.dir,x,n,o->mat);
    if(!o->mat.reflective&&!o->mat.refractive){
        double px=(x.x/4+0.5)*phms;
        double py=(x.y/4+0.5)*phms;
        double u=px-(int)px;
        double v=py-(int)py;
        Color f=ph2((int)px, (int)py)*(1-u)*(1-v)+
            ph2((int)px+1, (int)py)*(u)*(1-v)+
            ph2((int)px, (int)py+1)*(1-u)*(v)+
            ph2((int)px+1, (int)py+1)*(u)*(v);
            c=c+f*(5000./phLim);
    }
    if(o->mat.reflective) {
        Vector refd=reflectDir(ray.dir,n)+x;
        Ray ref(x,refd);
        if(o->mat.refractive){
            bool valid=true;
            Vector refrd=refractDir(ray.dir,n,o->mat.n.r,valid);
            if(valid){
                c=c+fresnel(ray.dir,n,o->mat,false)*trace(ref,i-1);
            } else {
                c=c+trace(ref,i-1);
            }
        } else {
            c=c+fresnel(ray.dir,n,o->mat,false)*trace(ref,i-1);
        }
    }
    if(o->mat.refractive){
        bool valid=true;
        Vector refrd=refractDir(ray.dir,n,o->mat.n.r,valid)+x;
        if(valid){
            Ray refr(x,refrd);
            c=c+fresnel(ray.dir,n,o->mat,true)*trace(refr,i-1);
        }
    }
    return c;
}
Spectrum DipoleSubsurfaceIntegrator::Li(const Scene *scene, const Renderer *renderer,
        const RayDifferential &ray, const Intersection &isect,
        const Sample *sample, RNG &rng, MemoryArena &arena) const {
    Spectrum L(0.);
    Vector wo = -ray.d;
    // Compute emitted light if ray hit an area light source
    L += isect.Le(wo);

    // Evaluate BSDF at hit point
    BSDF *bsdf = isect.GetBSDF(ray, arena);
    const Point &p = bsdf->dgShading.p;
    const Normal &n = bsdf->dgShading.nn;

    Spectrum rho_dr = Spectrum(1.0f);

    // Evaluate BSSRDF and possibly compute subsurface scattering
    BSSRDF *bssrdf = isect.GetBSSRDF(ray, arena);
    if (bssrdf && octree) {	
        Spectrum sigma_a  = bssrdf->sigma_a();
        Spectrum sigmap_s = bssrdf->sigma_prime_s();
        Spectrum sigmap_t = sigmap_s + sigma_a;
        if (!sigmap_t.IsBlack()) {
            // Use hierarchical integration to evaluate reflection from dipole model
            PBRT_SUBSURFACE_STARTED_OCTREE_LOOKUP(const_cast<Point *>(&p));
            DiffusionReflectance Rd(sigma_a, sigmap_s, bssrdf->eta());
            Spectrum Mo = octree->Mo(octreeBounds, p, Rd, maxError);
            FresnelDielectric fresnel(1.f, bssrdf->eta());
            Spectrum Ft = Spectrum(1.f) - fresnel.Evaluate(AbsDot(wo, n));
            float Fdt = 1.f - Fdr(bssrdf->eta());

	    // modulate SSS contribution by rho_dr
            //L += (INV_PI * Ft) * (Fdt * Mo);
	    rho_dr = wet->integrate_BRDF(bsdf, ray.d, 10, BxDFType(BSDF_REFLECTION | BSDF_GLOSSY));
	    L += (INV_PI * Ft) * (Fdt * Mo) * (Spectrum(1.0f) - rho_dr);
	    //L += (INV_PI * Ft) * (Fdt * Mo) * (Spectrum(0.0f));
	    
            PBRT_SUBSURFACE_FINISHED_OCTREE_LOOKUP();
        }
    }

    L += UniformSampleAllLights(scene, renderer, arena, p, n,
        wo, isect.rayEpsilon, ray.time, bsdf, sample, rng, lightSampleOffsets,
        bsdfSampleOffsets);

    if (ray.depth < maxSpecularDepth) {
        // Trace rays for specular reflection and refraction.

      //TODO: this has no effect?
        L += SpecularReflect(ray, bsdf, rng, isect, renderer, scene,
			     sample, arena);
        L += SpecularTransmit(ray, bsdf, rng, isect,
			      renderer, scene, sample, arena);
    }
    return L;
}
Example #8
0
Color Fresnel::sample(const IntersectionInfo& info)
{
	float eta = ior;
	float NdotI = dot(info.normal, info.rayDir);
	if (NdotI > 0)
		eta = 1.0f / eta;
	else
		NdotI = -NdotI;
	float fr = fresnel(NdotI, eta);
	return Color(fr, fr, fr);
}
Example #9
0
// for global lighting
MyRGBColor
FresnelReflector::sample_f(const ShadeRec& sr,  Vector3D& wr, const Vector3D& wo, float& pdf) const {
	float ndotwo = sr.normal * wo;
	wr = -wo + 2.0 * sr.normal * ndotwo;
	//pdf = sr.normal * wr;
	pdf = fabs(sr.normal * wr);	// maybe this instead?
	
	// assuming this is correct based on the other sample_f
	return(fresnel(sr) * white);
	//return (kr * cr);
}
Example #10
0
Vec trace(const Ray& r, const int index, const int num_samps) {
	// ray-sphere intersection
	double t;
	if (!intersect(r, t)) return Vec();

	// compute the intersection data
	const Vec x = r.o + r.d * t, n = (x - sph.p).normalized(), w = -r.d;

	// compute Fresnel transmittance at point of emergence
	const double T21 = 1.0 - fresnel(w.dot(n), eta);

	// integration of the BSSRDF over the surface
	unsigned int xi = next_rand(index);
	Vec result;
	for (int i = 0; i < num_samps; i++) {
		// generate a sample
		Vec sp, sn, sw;
		sample(i, Vec(hal(2, index), hal(3, index), 0.0), sp, sn);
		sw = Vec(1, 1, -0.5).normalized();

		// directional light source
		const double radiance = 8.0*PI;
		const double cos_wi_n = sn.dot(sw);
		if (cos_wi_n > 0.0) {
			// Russian roulette (note that accept_prob can be any value in (0, 1))
			const double accept_prob = exp(-(sp - x).len() * min_sigma_tr);
			if ((xi / rand_range) < accept_prob) {
				const double T12 = 1.0 - fresnel(cos_wi_n, eta);
				const double Li_cos = T12 * radiance * cos_wi_n / (samplePDF * accept_prob);

				for (int j = 0; j < 3; j++) result[j] += bssrdf(sp, sn, sw, x, n, w, j) * Li_cos;

				// reciprocal evaulation with the reciprocity hack
				//for (int j = 0; j < 3; j++) result[j] += 0.5 * (bssrdf(sp, sn, sw, x, n, w, j) + bssrdf(x, n, w, sp, sn, sw, j)) * Li_cos;
			}
			xi = next_rand(xi);
		}
	}
	return T21 * result / (double)num_samps;
}
Example #11
0
void shoot(const Color& pow, Ray& ray, int i){
    if(i>8) return;
    Obj* o;
    Vector x;
    Vector n;
    if(firstIntersect(ray, x, n, &o)<0) return;
    if(i&&!o->mat.reflective&&!o->mat.refractive){
        if(n*ray.dir<0){
            addPhoton(x, pow*(n*ray.dir*-1));
        }
        return;
    }
    if(o->mat.reflective) {
        Vector refd=reflectDir(ray.dir,n)+x;;
        Ray ref(x,refd);
        if(o->mat.refractive){
            bool valid=true;
            Vector refrd=refractDir(ray.dir,n,o->mat.n.r,valid);
            if(valid){
                shoot(pow*fresnel(ray.dir,n,o->mat,false), ref, i+1);
            } else {
                shoot(pow, ref, i+1);
            }
        } else {
            shoot(pow*fresnel(ray.dir,n,o->mat,false), ref, i+1);
        }
    }
    if(o->mat.refractive){
        bool valid=true;
        Vector refrd=refractDir(ray.dir,n,o->mat.n.r,valid)+x;
        if(valid){
            Ray refr(x,refrd);
            shoot(pow*fresnel(ray.dir,n,o->mat,true), refr, i+1);
        }
    }
}
Example #12
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));
}
Example #13
0
	Spectrum Lo(const Scene *scene, Sampler *sampler,
			const Intersection &its, const Vector &d, int depth) const {
		if (!m_ready || m_ssFactor.isZero())
			return Spectrum(0.0f);
		IsotropicDipoleQuery query(m_zr, m_zv, m_sigmaTr, m_Fdt, its.p);
	
		const Normal &n = its.shFrame.n;
		m_octree->execute(query);

		if (m_eta == 1.0f) {
			return query.getResult() * m_ssFactor * INV_PI;
		} else {
			Float Ft = 1.0f - fresnel(absDot(n, d));
			return query.getResult() * m_ssFactor * INV_PI * (Ft / m_Fdr);
		}
	}
Example #14
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);
}
Example #15
0
    Color3f sample(BSDFQueryRecord &bRec, const Point2f &sample) const {

        bRec.measure = EDiscrete;

        //check if your are inside or not
        //compute the angle between the normal and the incoming direction
        float theta1 = Frame::cosTheta(bRec.wi);

        float fresnelTerm = fresnel(theta1, m_extIOR, m_intIOR);

        //check if entering or leaving
        bRec.entering = (theta1 > 0);


        float et = m_extIOR;
        float ei = m_intIOR;
        Vector3f n = Vector3f(0.0, 0.0, 1.0);
        if(!bRec.entering) {
             std::swap(ei, et);
             n(2) = -1.0;
        }


        // check you should a reflection or refraction
        if(sample(0) < fresnelTerm) {
            //mirror like reflection
            bRec.wo = Vector3f(
                -bRec.wi.x(),
                -bRec.wi.y(),
                 bRec.wi.z()
            );
            bRec.eta = 1.0f;
        } else {
            float snellsTerm = et / ei;

            float wdotn = bRec.wi.dot(n);

            Vector3f fstPart = (bRec.wi - (wdotn) * n);
            float srqtTerm = std::sqrt(1.0f - snellsTerm * snellsTerm * (1.0f - wdotn * wdotn));

            bRec.wo = - snellsTerm * fstPart - n * srqtTerm;
            bRec.eta = bRec.entering?  m_intIOR / m_extIOR : m_extIOR / m_intIOR;
        }

        return Color3f(1.0f);
    }
Example #16
0
	Float pdfDelta(const BSDFQueryRecord &bRec) const {
		bool sampleReflection   = (bRec.typeMask & EDeltaReflection)
				&& (bRec.component == -1 || bRec.component == 0);
		bool sampleTransmission = (bRec.typeMask & EDeltaTransmission)
				&& (bRec.component == -1 || bRec.component == 1);
		bool reflection = bRec.wo.z * bRec.wi.z > 0;

		Float result = 0.0f;
		if (sampleTransmission && sampleReflection) {
			Float fr = fresnel(Frame::cosTheta(bRec.wi), m_extIOR, m_intIOR);
			result = reflection ? fr : (1-fr);
		} else if (sampleReflection) {
			result = reflection ? 1.0f : 0.0f;
		} else if (sampleTransmission) {
			result = reflection ? 0.0f : 1.0f;
		}
		return result * std::abs(Frame::cosTheta(bRec.wo));
	}
/**
 * Simple program that starts our raytracer
 */
int main(int argc, char *argv[]) {
	try {
		RayTracer* rt;
		Timer t;
		rt = new RayTracer(800, 600);
		
		std::shared_ptr<SceneObjectEffect> color(new ColorEffect(glm::vec3(0.0, 1.0, 0.0)));
		std::shared_ptr<SceneObjectEffect> phong(new PhongEffect(glm::vec3(0.0, 0.0, 10.0)));
		std::shared_ptr<SceneObjectEffect> steel(new SteelEffect());
		std::shared_ptr<SceneObjectEffect> fresnel(new FresnelEffect());
		
		std::shared_ptr<SceneObject> s1(new Sphere(glm::vec3(-3.0f, 0.0f, 6.0f), 2.0f, steel));
		rt->addSceneObject(s1);
		std::shared_ptr<SceneObject> s2(new Sphere(glm::vec3(3.0f, 0.0f, 3.0f), 2.0f, fresnel));
		rt->addSceneObject(s2);
		std::shared_ptr<SceneObject> s3(new Sphere(glm::vec3(0.0f, 3.0f, 9.0f), 2.0f, steel));
		rt->addSceneObject(s3);


		std::string path = "cubemaps/SaintLazarusChurch3/";
		std::shared_ptr<SceneObject> cubeMap(new CubeMap(path + "posx.jpg", path + "negx.jpg",
			path + "posy.jpg", path + "negy.jpg",
			path + "posz.jpg", path + "negz.jpg"));
		rt->addSceneObject(cubeMap);


		std::shared_ptr<SceneObject> triangle(new Triangle(glm::vec3(0.0f, 2.0f, -1.0f), 
			glm::vec3(-2.0f, -2.0f, -1.0f), glm::vec3(2.0f, -2.0f, 0.0f),  steel));
		rt->addSceneObject(triangle);
				
		t.restart();
		rt->render();
		double elapsed = t.elapsed();
		std::cout << "Computed in " << elapsed << " seconds" <<  std::endl;
		rt->save("test", "bmp"); //We want to write out bmp's to get proper bit-maps (jpeg encoding is lossy)

		delete rt;
	} catch (std::exception &e) {
		std::string err = e.what();
		std::cout << err.c_str() << std::endl;
		return -1;
	}
	return 0;
}
Example #18
0
const BSDF *MetalMaterial::GetBSDF(const DifferentialGeometry &i_dg, size_t i_triangle_index, MemoryPool &i_pool) const
  {
  BSDF *p_bsdf = new ( i_pool.Alloc(sizeof(BSDF)) ) BSDF(i_dg);

  SpectrumCoef_d r, a;
  if (mp_refractive_index && mp_absorption)
    {
    r = mp_refractive_index->Evaluate(i_dg, i_triangle_index);
    a = mp_absorption->Evaluate(i_dg, i_triangle_index);
    }
  else
    {
    ASSERT(mp_reflectance);
    SpectrumCoef_d reflectance = mp_reflectance->Evaluate(i_dg, i_triangle_index);
    reflectance.Clamp(0.0, 1.0);

    ApproximateFresnelParameters(reflectance, r, a);
    }
  FresnelConductor fresnel(r, a);

  BxDF *p_bxdf;
  if (mp_roughness)
    {
    typedef Microfacet<FresnelConductor,BlinnDistribution> BlinnMicrofacetMetal;
    double roughness = MathRoutines::Clamp(mp_roughness->Evaluate(i_dg, i_triangle_index), 0.001, 1.0);
    BlinnDistribution blinn(1.0/roughness);

    p_bxdf = new ( i_pool.Alloc(sizeof(BlinnMicrofacetMetal)) ) BlinnMicrofacetMetal(SpectrumCoef_d(1.0), fresnel, blinn);
    }
  else
    {
    ASSERT(mp_u_roughness && mp_v_roughness);

    typedef Microfacet<FresnelConductor,AnisotropicDistribution> AnisotropicMicrofacetMetal;
    double u_roughness = MathRoutines::Clamp(mp_u_roughness->Evaluate(i_dg, i_triangle_index), 0.001, 1.0);
    double v_roughness = MathRoutines::Clamp(mp_v_roughness->Evaluate(i_dg, i_triangle_index), 0.001, 1.0);
    AnisotropicDistribution anisotropic(1.0/u_roughness, 1.0/v_roughness);

    p_bxdf = new ( i_pool.Alloc(sizeof(AnisotropicMicrofacetMetal)) ) AnisotropicMicrofacetMetal(SpectrumCoef_d(1.0), fresnel, anisotropic);
    }

  p_bsdf->AddBxDF(p_bxdf);
  return p_bsdf;
  }
Example #19
0
bool refractRay(const Vec3& origin, const Vec3&incident_dir, const Vec3& normal, const float rei[],
	Vec3& refract_dir, float& ref_weight)
{
	float eta = rei[0] / rei[1];
	float c1 = normal.dot(incident_dir), c2 = 1 - eta*eta*(1 - c1*c1);
	if (c2<0)
	{
		ref_weight = 1.0f;
		return false;
	}

	Vec3 v_nor = normal;
	if (c1<0.0f)
		c1 = -c1;
	else
		v_nor *= -1;
	refract_dir = eta*incident_dir + (eta*c1 - sqrt(c2))*v_nor;
	fresnel(c1, fabs(refract_dir.dot(normal)), rei, ref_weight);
	return true;
}
RGBColor
FresnelTransmitter::sample_f(const ShadeRec& sr, const Vector3D& wo, Vector3D& wt) const {
	
	Normal n(sr.normal);
	float cos_thetai = n * wo;

	float eta = eta_in / eta_out;//ior;	
		
	if (cos_thetai < 0.0) {			// transmitted ray is outside     
		cos_thetai = -cos_thetai;
		n = -n;  					// reverse direction of normal
		eta = 1.0 / eta; 			// invert ior 
	}

	float temp = 1.0 - (1.0 - cos_thetai * cos_thetai) / (eta * eta);
	float cos_theta2 = sqrt(temp);
	wt = -wo / eta - (cos_theta2 - cos_thetai / eta) * n;   
	
	return (fresnel(sr) / (eta * eta) * white / fabs(sr.normal * wt));

}
Example #21
0
static unsigned int ray_color(const point3 e, double t,
                              const point3 d,
                              idx_stack *stk,
                              const rectangular_node rectangulars,
                              const sphere_node spheres,
                              const light_node lights,
                              color object_color, int bounces_left)
{
    rectangular_node hit_rec = NULL, light_hit_rec = NULL;
    sphere_node hit_sphere = NULL, light_hit_sphere = NULL;
    double diffuse, specular;
    point3 l, _l, r, rr;
    object_fill fill;

    color reflection_part;
    color refraction_part;
    /* might be a reflection ray, so check how many times we've bounced */
    if (bounces_left == 0) {
        SET_COLOR(object_color, 0.0, 0.0, 0.0);
        return 0;
    }

    /* check for intersection with a sphere or a rectangular */
    intersection ip= ray_hit_object(e, d, t, MAX_DISTANCE, rectangulars,
                                    &hit_rec, spheres, &hit_sphere);
    if (!hit_rec && !hit_sphere)
        return 0;

    /* pick the fill of the object that was hit */
    fill = hit_rec ?
           hit_rec->element.rectangular_fill :
           hit_sphere->element.sphere_fill;

    void *hit_obj = hit_rec ? (void *) hit_rec : (void *) hit_sphere;

    /* assume it is a shadow */
    SET_COLOR(object_color, 0.0, 0.0, 0.0);

    for (light_node light = lights; light; light = light->next) {
        /* calculate the intersection vector pointing at the light */
        subtract_vector(ip.point, light->element.position, l);
        multiply_vector(l, -1, _l);
        normalize(_l);
        /* check for intersection with an object. use ignore_me
         * because we don't care about this normal
        */
        ray_hit_object(ip.point, _l, MIN_DISTANCE, length(l),
                       rectangulars, &light_hit_rec,
                       spheres, &light_hit_sphere);
        /* the light was not block by itself(lit object) */
        if (light_hit_rec || light_hit_sphere)
            continue;

        compute_specular_diffuse(&diffuse, &specular, d, l,
                                 ip.normal, fill.phong_power);

        localColor(object_color, light->element.light_color,
                   diffuse, specular, &fill);
    }

    reflection(r, d, ip.normal);
    double idx = idx_stack_top(stk).idx, idx_pass = fill.index_of_refraction;
    if (idx_stack_top(stk).obj == hit_obj) {
        idx_stack_pop(stk);
        idx_pass = idx_stack_top(stk).idx;
    } else {
        idx_stack_element e = { .obj = hit_obj,
                                .idx = fill.index_of_refraction
                              };
        idx_stack_push(stk, e);
    }

    refraction(rr, d, ip.normal, idx, idx_pass);
    double R = (fill.T > 0.1) ?
               fresnel(d, rr, ip.normal, idx, idx_pass) :
               1.0;

    /* totalColor = localColor +
                    mix((1-fill.Kd) * fill.R * reflection, T * refraction, R)
     */
    if (fill.R > 0) {
        /* if we hit something, add the color */
        int old_top = stk->top;
        if (ray_color(ip.point, MIN_DISTANCE, r, stk, rectangulars, spheres,
                      lights, reflection_part,
                      bounces_left - 1)) {
            multiply_vector(reflection_part, R * (1.0 - fill.Kd) * fill.R,
                            reflection_part);
            add_vector(object_color, reflection_part,
                       object_color);
        }
        stk->top = old_top;
    }
    /* calculate refraction ray */
    if ((length(rr) > 0.0) && (fill.T > 0.0) &&
            (fill.index_of_refraction > 0.0)) {
        normalize(rr);
        if (ray_color(ip.point, MIN_DISTANCE, rr, stk,rectangulars, spheres,
                      lights, refraction_part,
                      bounces_left - 1)) {
            multiply_vector(refraction_part, (1 - R) * fill.T,
                            refraction_part);
            add_vector(object_color, refraction_part,
                       object_color);
        }
    }

    protect_color_overflow(object_color);
    return 1;
}

/* @param background_color this is not ambient light */
void raytracing(void* args)
{
    arg *data = (arg*) args;
    point3 u, v, w, d;
    color object_color = { 0.0, 0.0, 0.0 };

    const viewpoint *view = (*data).View;
    color back = { 0.0 , 0.1 , 0.1 };
    uint8_t *pixels = data->pixels;
    int start_j,end_j;

    /*	Separate to count the pixels  */
    if(pthread_equal(pthread_self(),THREAD[0])) {
        start_j = 0;
        end_j = 128;
    } else if(pthread_equal(pthread_self(),THREAD[1])) {
        start_j = 128;
        end_j = 256;
    } else if(pthread_equal(pthread_self(),THREAD[2])) {
        start_j = 256;
        end_j = 384;
    } else if(pthread_equal(pthread_self(),THREAD[3])) {
        start_j = 384;
        end_j = 512;
    }

    /* calculate u, v, w */
    calculateBasisVectors(u, v, w, view);

    idx_stack stk;

    int factor = sqrt(SAMPLES);

    #pragma omp parallel for num_threads(64)	\
    private(stk), private(d),	\
    private(object_color)
    for (int j = start_j ; j < end_j; j++) {
        for (int i = 0 ; i < (*data).row; i++) {
            double r = 0, g = 0, b = 0;
            /* MSAA */
            for (int s = 0; s < SAMPLES; s++) {
                idx_stack_init(&stk);
                rayConstruction(d, u, v, w,
                                i * factor + s / factor,
                                j * factor + s % factor,
                                view,
                                (*data).row * factor, (*data).col * factor);
                if (ray_color(view->vrp, 0.0, d, &stk,(*data).rectangulars,
                              (*data).spheres, (*data).lights, object_color,
                              MAX_REFLECTION_BOUNCES)) {
                    r += object_color[0];
                    g += object_color[1];
                    b += object_color[2];
                } else {
                    r += back[0];
                    g += back[1];
                    b += back[2];
                }
                pixels[((i + (j * (*data).row)) * 3) + 0] = r * 255 / SAMPLES;
                pixels[((i + (j * (*data).row)) * 3) + 1] = g * 255 / SAMPLES;
                pixels[((i + (j * (*data).row)) * 3) + 2] = b * 255 / SAMPLES;
            }
        }
    }
}
Example #22
0
void fg(real_t x, real_t *f, real_t *g)
{
	void fresnel(real_t, real_t *, real_t *);
	real_t absx,c,s,c1,s1,a,xinv,x3inv,c4,p,q;

	absx=fabs(x);
	if (absx <= 1.6) {
		fresnel(x,&c,&s);
		a=x*x*1.57079632679490;
		c1=cos(a);
		s1=sin(a);
		a = (x < 0.0) ? -0.5 : 0.5;
		p=a-c;
		q=a-s;
		*f = q*c1-p*s1;
		*g = p*c1+q*s1;
	} else if (absx <= 1.9) {
		xinv=1.0/x;
		a=xinv*xinv;
		x3inv=a*xinv;
		c4=a*a;
		p=(((1.35304235540388e1*c4+6.98534261601021e1)*c4+
				4.80340655577925e1)*c4+8.03588122803942e0)*c4+
				3.18309268504906e-1;
		q=(((6.55630640083916e1*c4+2.49561993805172e2)*c4+
				1.57611005580123e2)*c4+2.55491618435795e1)*c4+1.0;
		*f = xinv*p/q;
		p=((((2.05421432498501e1*c4+1.96232037971663e2)*c4+
				1.99182818678903e2)*c4+5.31122813480989e1)*c4+
				4.44533827550512e0)*c4+1.01320618810275e-1;
		q=((((1.01379483396003e3*c4+3.48112147856545e3)*c4+
				2.54473133181822e3)*c4+5.83590575716429e2)*c4+
				4.53925019673689e1)*c4+1.0;
		*g = x3inv*p/q;
	} else if (absx <= 2.4) {
		xinv=1.0/x;
		a=xinv*xinv;
		x3inv=a*xinv;
		c4=a*a;
		p=((((7.17703249365140e2*c4+3.09145161574430e3)*c4+
				1.93007640786716e3)*c4+3.39837134926984e2)*c4+
				1.95883941021969e1)*c4+3.18309881822017e-1;
		q=((((3.36121699180551e3*c4+1.09334248988809e4)*c4+
				6.33747155851144e3)*c4+1.08535067500650e3)*c4+
				6.18427138172887e1)*c4+1.0;
		*f = xinv*p/q;
		p=((((3.13330163068756e2*c4+1.59268006085354e3)*c4+
				9.08311749529594e2)*c4+1.40959617911316e2)*c4+
				7.11205001789783e0)*c4+1.01321161761805e-1;
		q=((((1.15149832376261e4*c4+2.41315567213370e4)*c4+
				1.06729678030581e4)*c4+1.49051922797329e3)*c4+
				7.17128596939302e1)*c4+1.0;
		*g = x3inv*p/q;
	} else {
		xinv=1.0/x;
		a=xinv*xinv;
		x3inv=a*xinv;
		c4=a*a;
		p=((((2.61294753225142e4*c4+6.13547113614700e4)*c4+
				1.34922028171857e4)*c4+8.16343401784375e2)*c4+
				1.64797712841246e1)*c4+9.67546032967090e-2;
		q=((((1.37012364817226e6*c4+1.00105478900791e6)*c4+
				1.65946462621853e5)*c4+9.01827596231524e3)*c4+
				1.73871690673649e2)*c4+1.0;
		*f = (c4*(-p)/q+0.318309886183791)*xinv;
		p=(((((1.72590224654837e6*c4+6.66907061668636e6)*c4+
				1.77758950838030e6)*c4+1.35678867813756e5)*c4+
				3.87754141746378e3)*c4+4.31710157823358e1)*c4+
				1.53989733819769e-1;
		q=(((((1.40622441123580e8*c4+9.38695862531635e7)*c4+
				1.62095600500232e7)*c4+1.02878693056688e6)*c4+
				2.69183180396243e4)*c4+2.86733194975899e2)*c4+1.0;
		*g = (c4*(-p)/q+0.101321183642338)*x3inv;
	}
}
Example #23
0
cv::Mat HologramDecoder::decode_hologram( cv::Mat hologram, float z, float lambda, float dx, float dy ) {
    return fresnel( hologram, dx, dy, lambda * z, lambda );
}
Example #24
0
static unsigned int ray_color(const point3 e, double t,
                              const point3 d,
                              idx_stack *stk,
                              const rectangular_node rectangulars,
                              const sphere_node spheres,
                              const light_node lights,
                              color object_color, int bounces_left)
{
    rectangular_node hit_rec = NULL, light_hit_rec = NULL;
    sphere_node hit_sphere = NULL, light_hit_sphere = NULL;
    double diffuse, specular;
    point3 l, _l, r, rr;
    object_fill fill;

    color reflection_part;
    color refraction_part;
    /* might be a reflection ray, so check how many times we've bounced */
    if (bounces_left == 0) {
        SET_COLOR(object_color, 0.0, 0.0, 0.0);
        return 0;
    }

    /* check for intersection with a sphere or a rectangular */
    intersection ip= ray_hit_object(e, d, t, MAX_DISTANCE, rectangulars,
                                    &hit_rec, spheres, &hit_sphere);
    if (!hit_rec && !hit_sphere)
        return 0;

    /* pick the fill of the object that was hit */
    fill = hit_rec ?
           hit_rec->element.rectangular_fill :
           hit_sphere->element.sphere_fill;

    void *hit_obj = hit_rec ? (void *) hit_rec : (void *) hit_sphere;

    /* assume it is a shadow */
    SET_COLOR(object_color, 0.0, 0.0, 0.0);

    for (light_node light = lights; light; light = light->next) {
        /* calculate the intersection vector pointing at the light */
        subtract_vector(ip.point, light->element.position, l);
        multiply_vector(l, -1, _l);
        normalize(_l);
        /* check for intersection with an object. use ignore_me
         * because we don't care about this normal
        */
        ray_hit_object(ip.point, _l, MIN_DISTANCE, length(l),
                       rectangulars, &light_hit_rec,
                       spheres, &light_hit_sphere);
        /* the light was not block by itself(lit object) */
        if (light_hit_rec || light_hit_sphere)
            continue;

        compute_specular_diffuse(&diffuse, &specular, d, l,
                                 ip.normal, fill.phong_power);

        localColor(object_color, light->element.light_color,
                   diffuse, specular, &fill);
    }

    reflection(r, d, ip.normal);
    double idx = idx_stack_top(stk).idx, idx_pass = fill.index_of_refraction;
    if (idx_stack_top(stk).obj == hit_obj) {
        idx_stack_pop(stk);
        idx_pass = idx_stack_top(stk).idx;
    } else {
        idx_stack_element e = { .obj = hit_obj,
                                .idx = fill.index_of_refraction
                              };
        idx_stack_push(stk, e);
    }

    refraction(rr, d, ip.normal, idx, idx_pass);
    double R = (fill.T > 0.1) ?
               fresnel(d, rr, ip.normal, idx, idx_pass) :
               1.0;

    /* totalColor = localColor +
                    mix((1-fill.Kd) * fill.R * reflection, T * refraction, R)
     */
    if (fill.R > 0) {
        /* if we hit something, add the color */
        int old_top = stk->top;
        if (ray_color(ip.point, MIN_DISTANCE, r, stk, rectangulars, spheres,
                      lights, reflection_part,
                      bounces_left - 1)) {
            multiply_vector(reflection_part, R * (1.0 - fill.Kd) * fill.R,
                            reflection_part);
            add_vector(object_color, reflection_part,
                       object_color);
        }
        stk->top = old_top;
    }
    /* calculate refraction ray */
    if ((length(rr) > 0.0) && (fill.T > 0.0) &&
            (fill.index_of_refraction > 0.0)) {
        normalize(rr);
        if (ray_color(ip.point, MIN_DISTANCE, rr, stk,rectangulars, spheres,
                      lights, refraction_part,
                      bounces_left - 1)) {
            multiply_vector(refraction_part, (1 - R) * fill.T,
                            refraction_part);
            add_vector(object_color, refraction_part,
                       object_color);
        }
    }

    protect_color_overflow(object_color);
    return 1;
}

static void *parallel (void* range1)
{
    Thread_range *range = (Thread_range *)range1;

    point3 d;
    idx_stack stk;
    color object_color = { 0.0, 0.0, 0.0 };

    for (int j = range->height1; j < range->height2; j++) {
        for (int i = 0; i < range->ptr->width; i++) {
            double r = 0, g = 0, b = 0;
            /* MSAA */
            for (int s = 0; s < SAMPLES; s++) {
                idx_stack_init(&stk);
                rayConstruction(d, range->ptr->u,
				range->ptr->v, range->ptr->w,
                                i * range->ptr->factor + s / range->ptr->factor,
                                j * range->ptr->factor + s % range->ptr->factor,
                                range->ptr->view,
                                range->ptr->width * range->ptr->factor, 
				range->ptr->height * range->ptr->factor);
                if (ray_color(range->ptr->view->vrp, 0.0, d,
			      &(stk), range->ptr->rectangulars,
			      range->ptr->spheres,
                              range->ptr->lights, object_color,
                              MAX_REFLECTION_BOUNCES)) {
                    r += object_color[0];
                    g += object_color[1];
                    b += object_color[2];
                } else {
                    r += range->ptr->background_color[0];
                    g += range->ptr->background_color[1];
                    b += range->ptr->background_color[2];
                }
                range->ptr->pixels[((i + (j * range->ptr->width)) * 3) + 0] = r * 255 / SAMPLES;
                range->ptr->pixels[((i + (j * range->ptr->width)) * 3) + 1] = g * 255 / SAMPLES;
                range->ptr->pixels[((i + (j * range->ptr->width)) * 3) + 2] = b * 255 / SAMPLES;
            }
        }
    }
	return NULL;
}