Пример #1
0
inline bool Triangle::intersect(Ray& ray, Intersection& intersection) {

    vec3 pvec = cross(ray.direction, edge2);
    float det = dot(edge1, pvec);

    if(det <= 0.0)
        return false;

    vec3 tvec = ray.origin - vert0;

    float u = dot(tvec, pvec);

    if(u < 0.0f || u > det)
        return false;

    vec3 qvec = cross(tvec, edge1);

    float v = dot(ray.direction, qvec);

    if(v < 0.0f || u + v > det)
        return false;

    float t = dot(edge2, qvec);

    float inv_det = 1.0f / det;
    t *= inv_det;
    //u *= inv_det;
    //v *= inv_det;

    if(t >= intersection.getT())
        return false;

    intersection.set(t, ray.getPosition(t), cross(edge1, edge2), edge1, this);
    return true;
}
		Color AtmospherePathTracingIntegrator::transmittance( SceneCPtr scene, const Ray &r, bool debug )const
		{
			Atmosphere::LUTParameters &parms = scene->m_atmosphere->m_parameters;
			const Real heightOffset = (Real)parms.R_e+0.1f;

			// move to correct height
			Ray ray = r;
			ray.o += Vector( 0.0f, heightOffset, 0.0f );
			

			// find intersection with outer atmosphere
			Real t0,t1;
			if (!math::intersectionRaySphere<Real>( ray, (Real)parms.R_a, t0, t1))
				return math::Vec3f(1.0f);

			if( t1 > ray.tmax )
				t1 = ray.tmax;

			unsigned numSamples = parms.viewRaySamples*m_numStepsMultiplier;
			Real segmentLength = t1 / numSamples;

			//Real segmentLength = 200.0f;
			//unsigned numSamples = int(t1 / segmentLength);


			//Real tCurrent = 0.0;
			//math::Vec3f sumR(0.0f), sumM(0.0f);


			Real densityR = Real(0.0);
			Real densityM = Real(0.0);

			for (unsigned i = 0; i < numSamples; ++i)
			{
				Vector samplePosition = ray.getPosition(i*segmentLength);
				Real height = samplePosition.getLength() - (Real)parms.R_e;
				Real currentDensityR = exp(-height / parms.h_r)*segmentLength;
				Real currentDensityM = exp(-height / parms.h_m)*segmentLength;
				densityR += (Real)currentDensityR;
				densityM += (Real)currentDensityM;
			}

			Vector opticalDepth = (Vector)parms.beta_r*densityR + (Vector)parms.beta_m*Real(1.1)*densityM;
			return Vector( exp(-opticalDepth.x), exp(-opticalDepth.y), exp(-opticalDepth.z) );
		}
Пример #3
0
// inter_point : Poistion where ray intersected with geometry.
VolumeTracer::Interval VolumeTracer::getInterval(Ray ray, IVolume* volume, vec3 inter_point) {

  OBB::IntervalData intersect = volume->getInterval(ray);

  if(!intersect.intersected)
    return Interval();

  vec3 min = intersect.min;
  vec3 max = intersect.max;

  if(intersect.inside)  // If we're inside the box, we have no min, put ray position to min.
    min = ray.getPosition();

  float dist = glm::distance(min, max);

  // If inter_point is within the volume, move it to max
  if(glm::distance(min, inter_point) < dist)
    max = inter_point;

  return Interval(true, min, max);
}
Пример #4
0
IAccDataStruct::IntersectionData Heightmap::triangleIntersection(Ray ray, Triangle* triangle1, Triangle* triangle2) {
  vec3 o = ray.getPosition();
  vec3 d = ray.getDirection();

  Triangle* closest_tri = NULL;
  //float closest_dist = -1;
  vec3 closest_pos;

  float closest_t = numeric_limits<float>::infinity( );

  for(int i = 0; i < 2; i++) {

    Triangle* cur_triangle;

    switch (i) {
      case 0:
        cur_triangle = triangle1;
        break;
      case 1:
        cur_triangle = triangle2;
        break;
      default:
        cur_triangle = triangle1;
        break;
    }

    const vector<vec3*> vertices = cur_triangle->getVertices();
    vec3 v0 = *(vertices[0]);
    vec3 v1 = *(vertices[1]);
    vec3 v2 = *(vertices[2]);

    vec3 e1 = v1 - v0;
    vec3 e2 = v2 - v0;
    vec3 s = o - v0;

    vec3 dxe2 = cross(d, e2);
    vec3 sxe1 = cross(s, e1);
    vec3 res = ( 1.0f /  dot(dxe2, e1) ) *
        vec3( dot(sxe1, e2), dot(dxe2, s), dot(sxe1, d) );

    float t = res.x;
    float u = res.y;
    float v = res.z;

    float dist = glm::distance(o, closest_pos);

    if(u >= 0 && v >= 0 && u + v <= 1) {  // Intersection!
      if(t > 0 && t < closest_t) {
        closest_tri = cur_triangle;
        closest_pos = o + t * d;
        //closest_dist = dist;
        closest_t = t;
      }
    }
  }

  if(closest_t == numeric_limits<float>::infinity( )) {
    return IAccDataStruct::IntersectionData::miss();
  }

  vec3 v1v0 = *(closest_tri->getVertices()[1]) - *(closest_tri->getVertices()[0]);
  vec3 v2v1 = *(closest_tri->getVertices()[2]) - *(closest_tri->getVertices()[1]);
  vec3 v2v0 = *(closest_tri->getVertices()[2]) - *(closest_tri->getVertices()[0]);
  vec3 pv0 = closest_pos - *(closest_tri->getVertices()[0]);
  vec3 pv1 = closest_pos - *(closest_tri->getVertices()[1]);

  float a = length(cross(v1v0, v2v0));
  float a0 = length(cross(v2v1, pv1))/a;
  float a1 = length(cross(v2v0, pv0))/a;
  float a2 = length(cross(v1v0, pv0))/a;

  vec3 inter_normal = a0 * *(closest_tri->getNormals()[0]) +
      a1 * *(closest_tri->getNormals()[1]) +
      a2 * *(closest_tri->getNormals()[2]);

  vec3 v1 = v1v0;
  vec3 v2 = v2v1;

  if(v1.length() > v2.length()) {
    v1 = v2v1;
    v1 = v1v0;
  }
  if(v2.length() > v2v0.length()) {
    v2 = v2v0;
  }

  return IAccDataStruct::IntersectionData(NULL, 0, closest_pos, glm::normalize(inter_normal), vec2(0,0));
}
		Color AtmospherePathTracingIntegrator::Li( SceneCPtr scene, RendererCPtr renderer, const Ray &r, Color &transmittance, bool debug) const
		{
			Debug dd;
			Atmosphere::LUTParameters &parms = scene->m_atmosphere->m_parameters;
			const Real heightOffset = (Real)parms.R_e+0.1f;

			// move to correct height
			Ray ray = r;
			ray.o += Vector( 0.0f, heightOffset, 0.0f );

			// find intersection with outer atmosphere
			Real t0,t1;
			if (!math::intersectionRaySphere<Real>( ray, (Real)parms.R_a, t0, t1))
				return math::Vec3f(1.0f);

			if( t1 > ray.tmax )
				t1 = ray.tmax;
			if( t0 < ray.tmin )
				t0 = ray.tmin;

			///*
			Real maxDist = t1-t0;

			//Real stepSize = maxDist/(parms.viewRaySamples);
			Real stepSize = 1.0f;
			//Real stepSize = m_stepSize;
			Vector step = ray.d*stepSize;

			Real tend;
			Real volSamplePDF;
			Vector x;


			///*
			// uniform sampling ---------------
			tend = t0 + math::g_randomNumber.randomFloat()*maxDist;
			volSamplePDF = 1.0f/maxDist;
					
			// raymarch to tend and compute transmittance
			Real t = t0;// + math::g_randomNumber.randomFloat()*stepSize;
			x = ray.getPosition( t );
			Real densityR = 0.0f;
			Real densityM = 0.0f;
			while( t<tend )
			{
				Real height = x.getLength() - (Real)parms.R_e;
				Real currentDensityR = exp(-height / parms.h_r)*stepSize;
				Real currentDensityM = exp(-height / parms.h_m)*stepSize;
				densityR += currentDensityR;
				densityM += currentDensityM;

				t += stepSize;
				x += step;
			};

			Vector opticalDepth = (Vector)parms.beta_r*densityR + (Vector)parms.beta_m*Real(1.1)*densityM;
			Vector transmittanceView = Vector( exp(-opticalDepth.x), exp(-opticalDepth.y), exp(-opticalDepth.z) );
			//*/

			/*
			// woodcock tracking
			Real maxDensity = 6.0f;
			Real densityEnd = -log( math::g_randomNumber.randomFloat() ) / maxDensity;

			// raymarch to tend and compute transmittance
			Real densityR = 0.0f;
			Real densityM = 0.0f;
			tend = t0;
			x = ray.getPosition(tend);
			while( (densityR+densityM<maxDensity)&&(tend<t1) )
			{
				Real height = x.getLength() - (Real)parms.R_e;
				Real currentDensityR = exp(-height / parms.h_r)*stepSize;
				Real currentDensityM = exp(-height / parms.h_m)*stepSize;

				densityR += currentDensityR;
				densityM += currentDensityM;
				tend += stepSize;
				x += step;
			};

			Vector opticalDepth = (Vector)parms.beta_r*densityR + (Vector)parms.beta_m*Real(1.1)*densityM;
			Vector transmittanceView = Vector( exp(-opticalDepth.x), exp(-opticalDepth.y), exp(-opticalDepth.z) );
			volSamplePDF = exp(-(densityR+densityM))*maxDensity;
			*/
			/*
			// woodcock tracking2
			Real maxDensity = 2.0f;
			Real densityEnd = -log( math::g_randomNumber.randomFloat() ) / maxDensity;

			// raymarch to tend and compute transmittance
			Real densityR = 0.0f;
			Real densityM = 0.0f;
			tend = t0;
			while(tend < t1)
			{
				tend += -log( math::g_randomNumber.randomFloat() ) / maxDensity;
				x = ray.getPosition(tend);

				Real height = x.getLength() - (Real)parms.R_e;
				Real currentDensityR = exp(-height / parms.h_r);
				Real currentDensityM = exp(-height / parms.h_m);
				densityR += currentDensityR;
				densityM += currentDensityM;

				if( math::g_randomNumber.randomFloat() < (currentDensityR+currentDensityM)/maxDensity )
					break;
			};


			Vector opticalDepth = (Vector)parms.beta_r*densityR + (Vector)parms.beta_m*Real(1.1)*densityM;
			Vector transmittanceView = Vector( exp(-opticalDepth.x), exp(-opticalDepth.y), exp(-opticalDepth.z) );
			volSamplePDF = exp(-(densityR+densityM))*maxDensity;
			*/




			// ---
			Real nu = math::dot( ray.d, (Vector)scene->m_atmosphere->m_sunDirection );
			Real phaseR = (Real)(3.0f / (16.0f * Real(MATH_PIf))) * (1.0f + nu * nu);
			Real g = (Real)parms.mie_phase_g;
			Real phaseM = (3 / (8 * Real(MATH_PI))) * (((1 - g * g) * (1 + nu * nu))/((2 + g * g) * pow(1 + g * g - 2 * g * nu, Real(1.5))));



			Color Ls(0.0f);

			// single scattering
			{
				LightCPtr light = scene->m_lights[0];

				Vector          lx = x - Vector( 0.0f, heightOffset, 0.0f );
				Vector          wi;
				Real           pdf;
				Ray            vis; // visibility ray
				Color Li = light->sample_L( lx, wi, pdf, vis );

				Color transmittanceLight = renderer->transmittance( scene, vis );

				Real height = x.getLength() - (Real)parms.R_e;
				Real currentDensityR = exp(-height / parms.h_r)*stepSize;
				Real currentDensityM = exp(-height / parms.h_m)*stepSize;


				Color tt = transmittanceView*transmittanceLight;

				Color sum_r = tt*phaseR*currentDensityR*parms.beta_r;
				Color sum_m = tt*phaseM*currentDensityM*parms.beta_m*Real(1.1f);

				Ls += Li*(sum_r + sum_m)/pdf;

				///*
				if( debug )
				{
					Debug dd;
					dd.tend = tend;
					dd.transmittance = transmittanceLight;
					dd.Li = Ls;
					debugData.push_back(dd);
				}
				//*/
			}



			transmittance = this->transmittance(scene, r);


			return Ls/volSamplePDF;
		}
Пример #6
0
Ray Transform::transform( const Ray &i_ray, const glm::mat4 &i_transform ) {
    
    glm::vec3 position = Transform::transform( i_ray.getPosition(), i_transform );
    glm::vec3 direction = Transform::transform( i_ray.getDirection(), i_transform, false );
    return Ray( position, direction );
}