示例#1
0
void InstantRadiosity( int N, double rho )
{
  double Start = N;

  for ( int Reflections = 0, End = N; End > 0; End = (int)Start, Reflections++ ) {
    Start *= rho;

    for ( int i = (int)Start; i < End; i++ ) {
      // Select starting point on light source
      Point y( phi( 2, i ), phi( 3, i ) );
      Color L( Le( y ) ); // Le( y ) * supp Le; supp Le?
      double w = N;

      // trace reflections
      for ( int j = 0; j <= Reflections; j++ ) {
        glRenderShadowedScene( N / floor( w ) * L, y );
        glAccum( GL_ACCUM, 1 / N );

        // diffuse scattering
        Vector ω = ωd( phi( 2 * j + 2, i ), phi( 2 * j + 3, ( i ) );

        //trace ray from y into direction ω
        y = h( y, ω );

        // Attenuate and compensate
        L *= fd( y );
        w *= ρ;
      }
    }
  }

  glAccum( GL_RETURN, 1.0 );
}
示例#2
0
TEST_F(EventTest, EventDifference) {
  const double e = 1e-2;
  StreamFactory streamFactory;

  Device device(0);
  device.setActiveDevice();
  ASSERT_TRUE(device.isActive());

  Stream* stream = streamFactory.constructStream(device);

  Event before(*stream);

  //TODO a kernel here that waits a while

  Event after(*stream);

  stream->syncStream();

  float diff = after - before;

  const float realDiff = 1;
  float l = realDiff - e;
  float h = realDiff + e;
  EXPECT_THAT(diff, Ge(l));
  EXPECT_THAT(diff, Le(h));

  delete stream;
}
示例#3
0
TEST_F(LogisticTransformTest, KernelSmallVector) {
  const int numberOfRows = 5;
  double e = 10e-5;

  Container::PinnedHostVector* hostVectorFrom = new Container::PinnedHostVector(numberOfRows);
  for(int i = 0; i < numberOfRows; ++i){
    (*hostVectorFrom)(i) = i / 10;
  }

  Container::DeviceVector* logitDeviceVector = hostToDeviceStream1.transferVector(*hostVectorFrom);
  Container::DeviceVector* probDeviceVector = new Container::DeviceVector(numberOfRows);

  kernelWrapper.logisticTransform(*logitDeviceVector, *probDeviceVector);

  Container::HostVector* resultHostVector = deviceToHostStream1.transferVector(*probDeviceVector);
  stream->syncStream();
  handleCudaStatus(cudaGetLastError(), "Error in LogisticTransform test: ");

  ASSERT_EQ(numberOfRows, resultHostVector->getNumberOfRows());

  for(int i = 0; i < numberOfRows; ++i){
    PRECISION x = i / 10;
    x = exp(x) / (1 + exp(x));
    double l = x - e;
    double h = x + e;

    EXPECT_THAT((*resultHostVector)(i), Ge(l));
    EXPECT_THAT((*resultHostVector)(i), Le(h));
  }

  delete hostVectorFrom;
  delete logitDeviceVector;
  delete probDeviceVector;
  delete resultHostVector;
}
示例#4
0
void   testList(int testSize) {
   printf("\n  ==== Test %2d. Generate two lists each of size %d by random insertions\n", testID++, testSize);
   List<T> La; randomList(La, testSize); PRINT(La);
   List<T> Lb; randomList(Lb, testSize); PRINT(Lb);

   printf("\n  ==== Test %2d. Call list members by rank (with high complexity)\n", testID++);
   for (int i = 0; i < La.size(); i++) print(La[i]->data); printf("\n");
   for (int i = 0; i < Lb.size(); i++) print(Lb[i]->data); printf("\n");

   printf("\n  ==== Test %2d. Concatenation\n", testID++); PRINT(La); PRINT(Lb);
   while (0 < Lb.size()) La.insertAsLast(Lb.remove(Lb.first())); PRINT(La); PRINT(Lb);

   printf("\n  ==== Test %2d. Increase\n", testID++); PRINT(La);
   increase(La); PRINT(La);

   printf("\n  ==== Test %2d. Copy\n", testID++); PRINT(La);
   List<T> Ld(La); PRINT(Ld);

   printf("\n  ==== Test %2d. Trim by random deletions\n", testID++); PRINT(Ld);
   while (testSize/4 < Ld.size()) {
      int N = rand() % Ld.size(); printf("removing L[%d]=", N);
      ListNodePosi(T) p = Ld.first(); while (0 < N--) p = p->succ;
      print(p->data); printf(" ...\n");
      Ld.remove(p); PRINT(Ld);
   }

   printf("\n  ==== Test %2d. Copy\n", testID++); PRINT(La);
   List<T> Le(La); PRINT(Le);

   printf("\n  ==== Test %2d. FIND in\n", testID++); PRINT(Le);
   for (int i = 0; i <= testSize*2; i++) { //逐一测试[0, 2n]中的所有可能
      ListNodePosi(T) p = Le.find((T) i); printf("Looking for "); print((T)i); printf(": ");
      if (p) { printf(" found with"); print(p->data); }
      else printf(" not found");
      printf("\n");
   } //正确的结构应该是大致(n+1次)失败、(n次)成功相间

   printf("\n  ==== Test %2d. Sort\n", testID++); PRINT(La);
   La.sort(); PRINT(La);

   printf("\n  ==== Test %2d. SEARCH in\n", testID++); PRINT(La);
   for (int i = 0; i <= testSize*2; i++) { //逐一测试[0, 2n]中的所有可能
      ListNodePosi(T) p = La.search((T) i); printf("Looking for "); print((T)i); printf(": ");
      printf(" stopped at"); print(p->data);
      if ((T) i == p->data) printf(" and found");
      printf("\n");
   } //正确的结构应该是大致(n+1次)失败、(n次)成功相间

   printf("\n  ==== Test %2d. Remove redundancy in\n", testID++); PRINT(La);
   printf("%d node(s) removed\n", La.uniquify()); PRINT(La);

   printf("\n  ==== Test %2d. Remove redundancy in\n", testID++); PRINT(Le);
   printf("%d node(s) removed\n", Le.deduplicate()); PRINT(Le);

   printf("\n  ==== Test %2d. Sort\n", testID++); PRINT(Le);
   Le.sort(); PRINT(Le);

   return;
}
示例#5
0
	Vector sampleDirection(Point2 sample, Float &pdf, Spectrum &value) const {
#if defined(SAMPLE_UNIFORMLY)
		pdf = 1.0f / (4*M_PI);
		Vector d = squareToSphere(sample);
		value = Le(-d);
		return d;
#endif
	}
示例#6
0
    Color3f Li(const Scene *scene, Sampler *sampler, const Ray3f &ray) const {
        /* Find the surface that is visible in the requested direction */
        Intersection its;

        //check if the ray intersects the scene
        if (!scene->rayIntersect(ray, its)) {
            //check if a distant disk light is set
            const Emitter* distantsDisk = scene->getDistantEmitter();
            if(distantsDisk == nullptr ) return Color3f(0.0f);

            //sample the distant disk light
            return distantsDisk->sampleL(ray.d);
        }

        //get the radiance of hitten object
        Color3f Le(0.0f, 0.0f, 0.0f);
        if (its.mesh->isEmitter()  ) {
            const Emitter* areaLightEM = its.mesh->getEmitter();
            const areaLight* aEM = static_cast<const areaLight *> (areaLightEM);
            Le = aEM->sampleL(-ray.d, its.shFrame.n, its);
        }

        //get the asigned BSDF
        const BSDF* curBSDF = its.mesh->getBSDF();

        Color3f Ld(0.0f, 0.0f, 0.0f);
        Color3f f(0.0f, 0.0f, 0.0f);
        Color3f totalLight(0.0f, 0.0f, 0.0f);

        //transform to the local frame
        //create a BRDF Query
        BSDFQueryRecord query = BSDFQueryRecord(its.toLocal(-ray.d), Vector3f(0.0f), EMeasure::ESolidAngle);

        //sample the BRDF
        Color3f mats =  curBSDF->sample(query, sampler->next2D());

        if(mats.maxCoeff() > 0.0f) {
            //Check for the light source
            Vector3f wo = its.toWorld(query.wo);
            Ray3f shadowRay(its.p, wo);
            Intersection itsShadow;
            if (scene->rayIntersect(shadowRay, itsShadow)) {
                //intersection check if mesh is emitter
                if(itsShadow.mesh->isEmitter()){
                    Ld = itsShadow.mesh->getEmitter()->radiance();
                }
            } else {
                //check for distant disk light
                const Emitter* distantsDisk = scene->getDistantEmitter();
                if(distantsDisk != nullptr ) Ld = distantsDisk->sampleL(wo);
            }

            totalLight += Ld * mats;
        }

        return Le + totalLight;
    }
示例#7
0
TEST_F(RandomTests, NextNumber_TwoArgument) {
    int a = rnd.nextInt(10, 20);
    EXPECT_THAT(a, Ge(10));
    EXPECT_THAT(a, Lt(20));

    long long b = rnd.nextLongLong(1000000000000ll, 2000000000000ll);
    EXPECT_THAT(b, Ge(1000000000000ll));
    EXPECT_THAT(b, Lt(2000000000000ll));

    double c = rnd.nextDouble(100.0, 200.0);
    EXPECT_THAT(c, Ge(100.0));
    EXPECT_THAT(c, Le(200.0));
}
glm::vec3 BidirectionalIntegrator::TraceRay(Ray r, unsigned int depth)
{
    Intersection isx = intersection_engine->GetIntersection(r);
    if(isx.t < 0)
        return glm::vec3(0);
    else if(isx.object_hit->material->is_light_source)
    {
        return isx.object_hit->material->base_color * isx.texture_color;
    }

    glm::vec3 resultColor(0);

    for(Geometry* light : scene->lights)
    {
        std::vector<PathNode> eyePath = generateEyePath(r);
        std::vector<PathNode> lightPath = generateLightPath(light);

        if(!eyePath.empty() && !lightPath.empty())
        {
            PathNode* node = &lightPath[0];
            float lightPdf = light->RayPDF(node->isx,Ray(node->isx.point,node->dirIn_world));
            glm::vec3 Le(0);
            if(lightPdf != 0)
                Le = light->material->base_color * light->material->intensity / lightPdf;

            glm::vec3 directWt(1.0f);
            for(int i=1;i<=eyePath.size();i++)
            {
                node = &eyePath[i-1];

                Ray ray(light->transform.position(), - node->dirIn_world);
                resultColor += directWt * EstimateDirectLight(node->isx, ray, light) / WeightPath(i,0);
                directWt *= node->F * glm::abs(glm::dot(node->dirOut_world,node->isx.normal)) / node->pdf;

                for(int j=1;j<=lightPath.size();j++)
                {
                    resultColor += Le * EvaluatePath(eyePath,i,lightPath,j) / WeightPath(i,j);
                }
            }
        }
        else
        {
            continue;
        }

    }
    return resultColor;
}
void TestTermination(
    Integrator const& integrator) {
  Length const q_initial = 1 * Metre;
  Speed const v_initial = 0 * Metre / Second;
  Instant const t_initial;
  Instant const t_final = t_initial + 163 * Second;
  Time const step = 42 * Second;
  int const steps = static_cast<int>(std::floor((t_final - t_initial) / step));

  int evaluations = 0;

  std::vector<ODE::SystemState> solution;
  ODE harmonic_oscillator;
  harmonic_oscillator.compute_acceleration =
      std::bind(ComputeHarmonicOscillatorAcceleration,
                _1, _2, _3, &evaluations);
  IntegrationProblem<ODE> problem;
  problem.equation = harmonic_oscillator;
  ODE::SystemState const initial_state = {{q_initial}, {v_initial}, t_initial};
  problem.initial_state = &initial_state;
  problem.t_final = t_final;
  problem.append_state = [&solution](ODE::SystemState const& state) {
    solution.push_back(state);
  };

  integrator.Solve(problem, step);

  EXPECT_EQ(steps, solution.size());
  EXPECT_THAT(solution.back().time.value,
              AllOf(Gt(t_final - step), Le(t_final)));
  switch (integrator.composition) {
    case BA:
    case ABA:
      EXPECT_EQ(steps * integrator.evaluations, evaluations);
      break;
    case BAB:
      EXPECT_EQ(steps * integrator.evaluations + 1, evaluations);
      break;
    default:
      LOG(FATAL) << "Invalid composition";
  }
  Length q_error;
  Speed v_error;
  for (int i = 0; i < steps; ++i) {
    Time const t = solution[i].time.value - t_initial;
    EXPECT_THAT(t, AlmostEquals((i + 1) * step, 0));
  }
}
示例#10
0
	void sampleEmissionArea(EmissionRecord &eRec, const Point2 &sample) const {
		if (eRec.type == EmissionRecord::ENormal) {
			Vector d = squareToSphere(sample);
			eRec.sRec.p = m_bsphere.center + d * m_bsphere.radius;
			eRec.sRec.n = Normal(-d);
			eRec.pdfArea = 1.0f / (4 * M_PI * m_bsphere.radius * m_bsphere.radius);
			eRec.value = Spectrum(M_PI);
		} else {
			/* Preview mode, which is more suitable for VPL-based rendering: approximate 
			   the infinitely far-away source with set of diffuse point sources */
			const Float radius = m_bsphere.radius * 1.5f;
			Vector d = squareToSphere(sample);
			eRec.sRec.p = m_bsphere.center + d * radius;
			eRec.sRec.n = Normal(-d);
			eRec.pdfArea = 1.0f / (4 * M_PI * radius * radius);
			eRec.value = Le(d) * M_PI;
		}
	}
示例#11
0
// Solving Δt * Δt == n.
TEST_F(RootFindersTest, SquareRoots) {
  Instant const t_0;
  Instant const t_max = t_0 + 10 * Second;
  Length const n_max = Pow<2>(t_max - t_0) * SIUnit<Acceleration>();
  for (Length n = 1 * Metre; n < n_max; n += 1 * Metre) {
    int evaluations = 0;
    auto const equation = [t_0, n, &evaluations](Instant const& t) {
      ++evaluations;
      return Pow<2>(t - t_0) * SIUnit<Acceleration>() - n;
    };
    EXPECT_THAT(Bisect(equation, t_0, t_max) - t_0,
                AlmostEquals(Sqrt(n / SIUnit<Acceleration>()), 0, 1));
    if (n == 25 * Metre) {
      EXPECT_EQ(3, evaluations);
    } else {
      EXPECT_THAT(evaluations, AllOf(Ge(49), Le(58)));
    }
  }
}
示例#12
0
	Spectrum sampleEmissionDirection(EmissionRecord &eRec, const Point2 &sample) const {
		Float radius = m_bsphere.radius;
		if (eRec.type == EmissionRecord::EPreview) 
			radius *= 1.5f;
		Point p2 = m_bsphere.center + squareToSphere(sample) * radius;
		eRec.d = p2 - eRec.sRec.p;
		Float length = eRec.d.length();

		if (length == 0.0f) {
			eRec.pdfDir = 1.0f;
			return Spectrum(0.0f);
		}

		eRec.d /= length;
		eRec.pdfDir = INV_PI * dot(eRec.sRec.n, eRec.d);
		if (eRec.type == EmissionRecord::ENormal)
			return Le(-eRec.d) * INV_PI;
		else
			return Spectrum(INV_PI);
	}
示例#13
0
Spectrum AreaLight::Sample_L( const Point3f& p , Vector3f* wi , LightSample& _lightSample , float* pdf , VisibilityTester* pVisibility ) const
{
	// 采样光源对应的图元
	int index = ( int )( _lightSample.value[0] * ( m_pPrimitive->GetShapeCount() - 1 ) );

	Vector3f LightSourceSampleNormal;
	Point3f LightSourceSamplePoint = m_pPrimitive->GetShape( index )->Sample( p , _lightSample , LightSourceSampleNormal );

	*wi = Normalize( LightSourceSamplePoint - p );

	// Compute Primitive PDF value
	*pdf = m_pPrimitive->PDF( p , *wi );

	pVisibility->SetSegment( p , 1e-3f , LightSourceSamplePoint , 1e-3f );

	// Compute Li
	Spectrum Li = Le( LightSourceSamplePoint , LightSourceSampleNormal , -*wi );

	return Li;
}
示例#14
0
Spectrum InfiniteAreaLightIS::Sample_L(const Scene *scene,
		float u1, float u2, float u3, float u4,
		Ray *ray, float *pdf) const {
	// Choose two points _p1_ and _p2_ on scene bounding sphere
	Point worldCenter;
	float worldRadius;
	scene->WorldBound().BoundingSphere(&worldCenter,
		&worldRadius);
	worldRadius *= 1.01f;
	Point p1 = worldCenter + worldRadius *
		UniformSampleSphere(u1, u2);
	Point p2 = worldCenter + worldRadius *
		UniformSampleSphere(u3, u4);
	// Construct ray between _p1_ and _p2_
	ray->o = p1;
	ray->d = Normalize(p2-p1);
	// Compute _InfiniteAreaLightIS_ ray weight
	Vector to_center = Normalize(worldCenter - p1);
	float costheta = AbsDot(to_center,ray->d);
	*pdf =
		costheta / ((4.f * M_PI * worldRadius * worldRadius));
	return Le(RayDifferential(ray->o, -ray->d));
}
示例#15
0
	/**
	 * This is the tricky bit - we want to sample a ray that
	 * has uniform density over the set of all rays passing
	 * through the scene.
	 * For more detail, see "Using low-discrepancy sequences and 
	 * the Crofton formula to compute surface areas of geometric models"
	 * by Li, X. and Wang, W. and Martin, R.R. and Bowyer, A. 
	 * (Computer-Aided Design vol 35, #9, pp. 771--782)
	 */
	void sampleEmission(EmissionRecord &eRec, 
		const Point2 &sample1, const Point2 &sample2) const {
		Assert(eRec.type == EmissionRecord::ENormal);
		/* Chord model - generate the ray passing through two uniformly
		   distributed points on a sphere containing the scene */
		Vector d = squareToSphere(sample1);
		eRec.sRec.p = m_bsphere.center + d * m_bsphere.radius;
		eRec.sRec.n = Normal(-d);
		Point p2 = m_bsphere.center + squareToSphere(sample2) * m_bsphere.radius;
		eRec.d = p2 - eRec.sRec.p;
		Float length = eRec.d.length();

		if (length == 0) {
			eRec.value = Spectrum(0.0f);
			eRec.pdfArea = eRec.pdfDir = 1.0f;
			return;
		}

		eRec.d /= length;
		eRec.pdfArea = 1.0f / (4 * M_PI * m_bsphere.radius * m_bsphere.radius);
		eRec.pdfDir = INV_PI * dot(eRec.sRec.n, eRec.d);
		eRec.value = Le(-eRec.d);
	}
void TestTermination(Integrator const& integrator) {
  Length const q_initial = 1 * Metre;
  Speed const v_initial = 0 * Metre / Second;
  Instant const t_initial;
  Instant const t_final = t_initial + 1630 * Second;
  Time const step = 42 * Second;
  int const steps = static_cast<int>(std::floor((t_final - t_initial) / step));

  int evaluations = 0;

  std::vector<ODE::SystemState> solution;
  ODE harmonic_oscillator;
  harmonic_oscillator.compute_acceleration =
      std::bind(ComputeHarmonicOscillatorAcceleration,
                _1, _2, _3, &evaluations);
  IntegrationProblem<ODE> problem;
  problem.equation = harmonic_oscillator;
  ODE::SystemState const initial_state = {{q_initial}, {v_initial}, t_initial};
  problem.initial_state = &initial_state;
  auto append_state = [&solution](ODE::SystemState const& state) {
    solution.push_back(state);
  };

  auto const instance =
      integrator.NewInstance(problem, std::move(append_state), step);
  integrator.Solve(t_final, *instance);

  EXPECT_EQ(steps, solution.size());
  EXPECT_THAT(solution.back().time.value,
              AllOf(Gt(t_final - step), Le(t_final)));
  Length q_error;
  Speed v_error;
  for (int i = 0; i < steps; ++i) {
    Time const t = solution[i].time.value - t_initial;
    EXPECT_THAT(t, AlmostEquals((i + 1) * step, 0));
  }
}
TEST_F(EmbeddedExplicitRungeKuttaNyströmIntegratorTest,
       MaxSteps) {
  AdaptiveStepSizeIntegrator<ODE> const& integrator =
      DormandElMikkawyPrince1986RKN434FM<Length>();
  Length const x_initial = 1 * Metre;
  Speed const v_initial = 0 * Metre / Second;
  Speed const v_amplitude = 1 * Metre / Second;
  Time const period = 2 * π * Second;
  AngularFrequency const ω = 1 * Radian / Second;
  Instant const t_initial;
  Instant const t_final = t_initial + 10 * period;
  Length const length_tolerance = 1 * Milli(Metre);
  Speed const speed_tolerance = 1 * Milli(Metre) / Second;
  // The number of steps if no step limit is set.
  std::int64_t const steps_forward = 132;

  int evaluations = 0;
  auto const step_size_callback = [](bool tolerable) {};

  std::vector<ODE::SystemState> solution;
  ODE harmonic_oscillator;
  harmonic_oscillator.compute_acceleration =
      std::bind(ComputeHarmonicOscillatorAcceleration,
                _1, _2, _3, &evaluations);
  IntegrationProblem<ODE> problem;
  problem.equation = harmonic_oscillator;
  ODE::SystemState const initial_state = {{x_initial}, {v_initial}, t_initial};
  problem.initial_state = &initial_state;
  problem.t_final = t_final;
  problem.append_state = [&solution](ODE::SystemState const& state) {
    solution.push_back(state);
  };
  AdaptiveStepSize<ODE> adaptive_step_size;
  adaptive_step_size.first_time_step = t_final - t_initial;
  adaptive_step_size.safety_factor = 0.9;
  adaptive_step_size.tolerance_to_error_ratio =
      std::bind(HarmonicOscillatorToleranceRatio,
                _1, _2, length_tolerance, speed_tolerance, step_size_callback);
  adaptive_step_size.max_steps = 100;

  auto const outcome = integrator.Solve(problem, adaptive_step_size);
  EXPECT_EQ(termination_condition::ReachedMaximalStepCount, outcome.error());
  EXPECT_THAT(AbsoluteError(
                  x_initial * Cos(ω * (solution.back().time.value - t_initial)),
                      solution.back().positions[0].value),
              AllOf(Ge(8e-4 * Metre), Le(9e-4 * Metre)));
  EXPECT_THAT(AbsoluteError(
                  -v_amplitude *
                      Sin(ω * (solution.back().time.value - t_initial)),
                  solution.back().velocities[0].value),
              AllOf(Ge(1e-3 * Metre / Second), Le(2e-3 * Metre / Second)));
  EXPECT_THAT(solution.back().time.value, Lt(t_final));
  EXPECT_EQ(100, solution.size());

  // Check that a |max_steps| greater than or equal to the unconstrained number
  // of steps has no effect.
  for (std::int64_t const max_steps :
       {steps_forward, steps_forward + 1234}) {
    solution.clear();
    adaptive_step_size.max_steps = steps_forward;
    auto const outcome = integrator.Solve(problem, adaptive_step_size);
    EXPECT_EQ(termination_condition::Done, outcome.error());
    EXPECT_THAT(AbsoluteError(x_initial, solution.back().positions[0].value),
                AllOf(Ge(3e-4 * Metre), Le(4e-4 * Metre)));
    EXPECT_THAT(AbsoluteError(v_initial, solution.back().velocities[0].value),
                AllOf(Ge(2e-3 * Metre / Second), Le(3e-3 * Metre / Second)));
    EXPECT_EQ(t_final, solution.back().time.value);
    EXPECT_EQ(steps_forward, solution.size());
  }
}
示例#18
0
 Color HDRILight::eval(const DifferentialGeometry& dg, const Vec3f& wi) const {
   return Le(-wi);
 }
示例#19
0
	Spectrum f(const EmissionRecord &eRec) const {
		if (eRec.type == EmissionRecord::ENormal)
			return Le(-eRec.d) * INV_PI;
		else
			return Spectrum(INV_PI);
	}
示例#20
0
void PhotonShootingTask::Run() {
    // Declare local variables for _PhotonShootingTask_
    MemoryArena arena;
    RNG rng(31 * taskNum);
    vector<Photon> localDirectPhotons, localIndirectPhotons, localCausticPhotons;
    vector<RadiancePhoton> localRadiancePhotons;
    uint32_t totalPaths = 0;
    bool causticDone = (integrator->nCausticPhotonsWanted == 0);
    bool indirectDone = (integrator->nIndirectPhotonsWanted == 0);
    PermutedHalton halton(6, rng);
    vector<Spectrum> localRpReflectances, localRpTransmittances;
    while (true) {
        // Follow photon paths for a block of samples
        const uint32_t blockSize = 4096;
        for (uint32_t i = 0; i < blockSize; ++i) {
            float u[6];
            halton.Sample(++totalPaths, u);
            // Choose light to shoot photon from
            float lightPdf;
            int lightNum = lightDistribution->SampleDiscrete(u[0], &lightPdf);
            const Light *light = scene.lights[lightNum];

            // Generate _photonRay_ from light source and initialize _alpha_
            LightSample ls(u[1], u[2], u[3]);
            LightInfo2 li = light->Sample_L(scene, ls, u[4], u[5], time);
            Spectrum Le(li.L);
            RayDifferential photonRay(li.ray);
            Normal Nl(li.N);
            if (li.pdf == 0.f || Le.IsBlack()) continue;
            Spectrum alpha = (AbsDot(Nl, photonRay.d) * Le) / (li.pdf * lightPdf);
            if (!alpha.IsBlack()) {
                // Follow photon path through scene and record intersections
                PBRT_PHOTON_MAP_STARTED_RAY_PATH(&photonRay, &alpha);
                bool specularPath = true;
                int nIntersections = 0;
                auto optPhotonIsect = scene.Intersect(photonRay);
                while (optPhotonIsect) {
                    ++nIntersections;
                    // Handle photon/surface intersection
                    alpha *= renderer->Transmittance(scene, photonRay, NULL, rng, arena);
                    BSDF *photonBSDF = optPhotonIsect->GetBSDF(photonRay, arena);
                    BxDFType specularType = BxDFType(BSDF_REFLECTION |
                                            BSDF_TRANSMISSION | BSDF_SPECULAR);
                    bool hasNonSpecular = (photonBSDF->NumComponents() >
                                           photonBSDF->NumComponents(specularType));
                    Vector wo = -photonRay.d;
                    if (hasNonSpecular) {
                        // Deposit photon at surface
                        Photon photon(optPhotonIsect->dg.p, alpha, wo);
                        bool depositedPhoton = false;
                        if (specularPath && nIntersections > 1) {
                            if (!causticDone) {
                                PBRT_PHOTON_MAP_DEPOSITED_CAUSTIC_PHOTON(&optPhotonIsect->dg, &alpha, &wo);
                                depositedPhoton = true;
                                localCausticPhotons.push_back(photon);
                            }
                        }
                        else {
                            // Deposit either direct or indirect photon
                            // stop depositing direct photons once indirectDone is true; don't
                            // want to waste memory storing too many if we're going a long time
                            // trying to get enough caustic photons desposited.
                            if (nIntersections == 1 && !indirectDone && integrator->finalGather) {
                                PBRT_PHOTON_MAP_DEPOSITED_DIRECT_PHOTON(&optPhotonIsect->dg, &alpha, &wo);
                                depositedPhoton = true;
                                localDirectPhotons.push_back(photon);
                            }
                            else if (nIntersections > 1 && !indirectDone) {
                                PBRT_PHOTON_MAP_DEPOSITED_INDIRECT_PHOTON(&optPhotonIsect->dg, &alpha, &wo);
                                depositedPhoton = true;
                                localIndirectPhotons.push_back(photon);
                            }
                        }

                        // Possibly create radiance photon at photon intersection point
                        if (depositedPhoton && integrator->finalGather &&
                                rng.RandomFloat() < .125f) {
                            Normal n = optPhotonIsect->dg.nn;
                            n = Faceforward(n, -photonRay.d);
                            localRadiancePhotons.push_back(RadiancePhoton(optPhotonIsect->dg.p, n));
                            Spectrum rho_r = photonBSDF->rho(rng, BSDF_ALL_REFLECTION);
                            localRpReflectances.push_back(rho_r);
                            Spectrum rho_t = photonBSDF->rho(rng, BSDF_ALL_TRANSMISSION);
                            localRpTransmittances.push_back(rho_t);
                        }
                    }
                    if (nIntersections >= integrator->maxPhotonDepth) break;

                    // Sample new photon ray direction
                    Vector wi;
                    float pdf;
                    BxDFType flags;
                    Spectrum fr = photonBSDF->Sample_f(wo, &wi, BSDFSample(rng),
                                                       &pdf, BSDF_ALL, &flags);
                    if (fr.IsBlack() || pdf == 0.f) break;
                    Spectrum anew = alpha * fr *
                        AbsDot(wi, photonBSDF->dgShading.nn) / pdf;

                    // Possibly terminate photon path with Russian roulette
                    float continueProb = min(1.f, anew.y() / alpha.y());
                    if (rng.RandomFloat() > continueProb)
                        break;
                    alpha = anew / continueProb;
                    specularPath &= ((flags & BSDF_SPECULAR) != 0);
                    
                    if (indirectDone && !specularPath) break;
                    photonRay = RayDifferential(optPhotonIsect->dg.p, wi, photonRay,
                                                optPhotonIsect->rayEpsilon);
                    optPhotonIsect = scene.Intersect(photonRay);
                }
                PBRT_PHOTON_MAP_FINISHED_RAY_PATH(&photonRay, &alpha);
            }
            arena.FreeAll();
        }

        // Merge local photon data with data in _PhotonIntegrator_
        { MutexLock lock(mutex);

        // Give up if we're not storing enough photons
        if (abortTasks)
            return;
        if (nshot > 500000 &&
            (unsuccessful(integrator->nCausticPhotonsWanted,
                                      causticPhotons.size(), blockSize) ||
             unsuccessful(integrator->nIndirectPhotonsWanted,
                                      indirectPhotons.size(), blockSize))) {
            Error("Unable to store enough photons.  Giving up.\n");
            causticPhotons.erase(causticPhotons.begin(), causticPhotons.end());
            indirectPhotons.erase(indirectPhotons.begin(), indirectPhotons.end());
            radiancePhotons.erase(radiancePhotons.begin(), radiancePhotons.end());
            abortTasks = true;
            return;
        }
        progress.Update(localIndirectPhotons.size() + localCausticPhotons.size());
        nshot += blockSize;

        // Merge indirect photons into shared array
        if (!indirectDone) {
            integrator->nIndirectPaths += blockSize;
            for (uint32_t i = 0; i < localIndirectPhotons.size(); ++i)
                indirectPhotons.push_back(localIndirectPhotons[i]);
            localIndirectPhotons.erase(localIndirectPhotons.begin(),
                                       localIndirectPhotons.end());
            if (indirectPhotons.size() >= integrator->nIndirectPhotonsWanted)
                indirectDone = true;
            nDirectPaths += blockSize;
            for (uint32_t i = 0; i < localDirectPhotons.size(); ++i)
                directPhotons.push_back(localDirectPhotons[i]);
            localDirectPhotons.erase(localDirectPhotons.begin(),
                                     localDirectPhotons.end());
        }

        // Merge direct, caustic, and radiance photons into shared array
        if (!causticDone) {
            integrator->nCausticPaths += blockSize;
            for (uint32_t i = 0; i < localCausticPhotons.size(); ++i)
                causticPhotons.push_back(localCausticPhotons[i]);
            localCausticPhotons.erase(localCausticPhotons.begin(), localCausticPhotons.end());
            if (causticPhotons.size() >= integrator->nCausticPhotonsWanted)
                causticDone = true;
        }
        
        for (uint32_t i = 0; i < localRadiancePhotons.size(); ++i)
            radiancePhotons.push_back(localRadiancePhotons[i]);
        localRadiancePhotons.erase(localRadiancePhotons.begin(), localRadiancePhotons.end());
        for (uint32_t i = 0; i < localRpReflectances.size(); ++i)
            rpReflectances.push_back(localRpReflectances[i]);
        localRpReflectances.erase(localRpReflectances.begin(), localRpReflectances.end());
        for (uint32_t i = 0; i < localRpTransmittances.size(); ++i)
            rpTransmittances.push_back(localRpTransmittances[i]);
        localRpTransmittances.erase(localRpTransmittances.begin(), localRpTransmittances.end());
        }

        // Exit task if enough photons have been found
        if (indirectDone && causticDone)
            break;
    }
}
示例#21
0
void Parser::executeAction(int production) try {
    if (d_token__ != _UNDETERMINED_)
        pushToken__(d_token__); // save an already available token

    // $insert defaultactionreturn
    // save default non-nested block $$
    if (int size = s_productionInfo[production].d_size)
        d_val__ = d_vsp__[1 - size];

    switch (production) {
        // $insert actioncases

        case 1:
#line 43 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = d_vsp__[0].data<Tag__::basic>();
            res = d_val__.get<Tag__::basic>();
        } break;

        case 2:
#line 51 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = add(d_vsp__[-2].data<Tag__::basic>(),
                                              d_vsp__[0].data<Tag__::basic>());
        } break;

        case 3:
#line 54 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = sub(d_vsp__[-2].data<Tag__::basic>(),
                                              d_vsp__[0].data<Tag__::basic>());
        } break;

        case 4:
#line 57 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = mul(d_vsp__[-2].data<Tag__::basic>(),
                                              d_vsp__[0].data<Tag__::basic>());
        } break;

        case 5:
#line 60 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = div(d_vsp__[-2].data<Tag__::basic>(),
                                              d_vsp__[0].data<Tag__::basic>());
        } break;

        case 6:
#line 63 "parser.yy"
        {
            auto tup = parse_implicit_mul(d_vsp__[-2].data<Tag__::string>());
            if (neq(*std::get<1>(tup), *one)) {
                d_val__.get<Tag__::basic>() = mul(
                    std::get<0>(tup),
                    pow(std::get<1>(tup), d_vsp__[0].data<Tag__::basic>()));
            } else {
                d_val__.get<Tag__::basic>()
                    = pow(std::get<0>(tup), d_vsp__[0].data<Tag__::basic>());
            }
        } break;

        case 7:
#line 73 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = pow(d_vsp__[-2].data<Tag__::basic>(),
                                              d_vsp__[0].data<Tag__::basic>());
        } break;

        case 8:
#line 76 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = rcp_static_cast<const Basic>(
                Lt(d_vsp__[-2].data<Tag__::basic>(),
                   d_vsp__[0].data<Tag__::basic>()));
        } break;

        case 9:
#line 79 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = rcp_static_cast<const Basic>(
                Gt(d_vsp__[-2].data<Tag__::basic>(),
                   d_vsp__[0].data<Tag__::basic>()));
        } break;

        case 10:
#line 82 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = rcp_static_cast<const Basic>(
                Le(d_vsp__[-2].data<Tag__::basic>(),
                   d_vsp__[0].data<Tag__::basic>()));
        } break;

        case 11:
#line 85 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = rcp_static_cast<const Basic>(
                Ge(d_vsp__[-2].data<Tag__::basic>(),
                   d_vsp__[0].data<Tag__::basic>()));
        } break;

        case 12:
#line 88 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = rcp_static_cast<const Basic>(
                Eq(d_vsp__[-2].data<Tag__::basic>(),
                   d_vsp__[0].data<Tag__::basic>()));
        } break;

        case 13:
#line 91 "parser.yy"
        {
            set_boolean s;
            s.insert(rcp_static_cast<const Boolean>(
                d_vsp__[-2].data<Tag__::basic>()));
            s.insert(rcp_static_cast<const Boolean>(
                d_vsp__[0].data<Tag__::basic>()));
            d_val__.get<Tag__::basic>()
                = rcp_static_cast<const Basic>(logical_or(s));
        } break;

        case 14:
#line 99 "parser.yy"
        {
            set_boolean s;
            s.insert(rcp_static_cast<const Boolean>(
                d_vsp__[-2].data<Tag__::basic>()));
            s.insert(rcp_static_cast<const Boolean>(
                d_vsp__[0].data<Tag__::basic>()));
            d_val__.get<Tag__::basic>()
                = rcp_static_cast<const Basic>(logical_and(s));
        } break;

        case 15:
#line 107 "parser.yy"
        {
            vec_boolean s;
            s.push_back(rcp_static_cast<const Boolean>(
                d_vsp__[-2].data<Tag__::basic>()));
            s.push_back(rcp_static_cast<const Boolean>(
                d_vsp__[0].data<Tag__::basic>()));
            d_val__.get<Tag__::basic>()
                = rcp_static_cast<const Basic>(logical_xor(s));
        } break;

        case 16:
#line 115 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = d_vsp__[-1].data<Tag__::basic>();
        } break;

        case 17:
#line 118 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = neg(d_vsp__[0].data<Tag__::basic>());
        } break;

        case 18:
#line 121 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = rcp_static_cast<const Basic>(
                logical_not(rcp_static_cast<const Boolean>(
                    d_vsp__[0].data<Tag__::basic>())));
        } break;

        case 19:
#line 124 "parser.yy"
        {
            d_val__.get<Tag__::basic>()
                = rcp_static_cast<const Basic>(d_vsp__[0].data<Tag__::basic>());
        } break;

        case 20:
#line 129 "parser.yy"
        {
            d_val__.get<Tag__::basic>()
                = parse_identifier(d_vsp__[0].data<Tag__::string>());
        } break;

        case 21:
#line 134 "parser.yy"
        {
            auto tup = parse_implicit_mul(d_vsp__[0].data<Tag__::string>());
            d_val__.get<Tag__::basic>()
                = mul(std::get<0>(tup), std::get<1>(tup));
        } break;

        case 22:
#line 140 "parser.yy"
        {
            d_val__.get<Tag__::basic>()
                = parse_numeric(d_vsp__[0].data<Tag__::string>());
        } break;

        case 23:
#line 145 "parser.yy"
        {
            d_val__.get<Tag__::basic>() = d_vsp__[0].data<Tag__::basic>();
        } break;

        case 24:
#line 152 "parser.yy"
        {
            d_val__.get<Tag__::basic>()
                = functionify(d_vsp__[-3].data<Tag__::string>(),
                              d_vsp__[-1].data<Tag__::basic_vec>());
        } break;

        case 25:
#line 160 "parser.yy"
        {
            d_val__.get<Tag__::basic_vec>()
                = d_vsp__[-2].data<Tag__::basic_vec>();
            d_val__.get<Tag__::basic_vec>().push_back(
                d_vsp__[0].data<Tag__::basic>());
        } break;

        case 26:
#line 166 "parser.yy"
        {
            d_val__.get<Tag__::basic_vec>()
                = vec_basic(1, d_vsp__[0].data<Tag__::basic>());
        } break;
    }
} catch (std::exception const &exc) {
    exceptionHandler__(exc);
}
示例#22
0
	Spectrum Le(const LuminaireSamplingRecord &lRec) const {
		return Le(-lRec.d);
	}
示例#23
0
	inline Spectrum Le(const Ray &ray) const {
		return Le(normalize(ray.d));
	}