Beispiel #1
0
void Film::AddSplat(const Point2f &p, const Spectrum &v) {
    if (v.HasNaNs()) {
        Warning("Film ignoring splatted spectrum with NaN values");
        return;
    }
    ProfilePhase pp(Prof::SplatFilm);
    if (!InsideExclusive((Point2i)p, croppedPixelBounds)) return;
    Float xyz[3];
    v.ToXYZ(xyz);
    Pixel &pixel = GetPixel((Point2i)p);
    for (int i = 0; i < 3; ++i) pixel.splatXYZ[i].Add(xyz[i]);
}
inline Spectrum EstimateDirectIllumination (
	const Scene * thisScene,
	const Intersection * intersectionInfo,
	const Ray & ray
)
{
	Spectrum intensity;

	Objects * obj = intersectionInfo->object;
	BRDFModels * brdf = obj->brdf_model;

	Vector newRayDirection;
	Vector normalDirection;

	normalDirection = intersectionInfo->normal;

	Attenuation attenuationFactor;
	bool delta_brdf_hitEmissive = false;
	bool occludedByObjects = true;

	Spectrum lightIntensity;

	if ( obj->brdf_model->surfaceFlag == surface_delta )
	{
		// get reflection direction
		// generate new ray
		// intersect with scene to see if the ray hit a light source
		normalDirection = intersectionInfo->normal;

		attenuationFactor = brdf->SampleBRDF(
			ray.direction,
			newRayDirection,
			normalDirection
		);

		Ray newRay( intersectionInfo->intersectionPoint, newRayDirection );

		Intersection newIntersectionInfo;

		if ( !thisScene->IntersectionWithScene( newRay, newIntersectionInfo ) )
			return Spectrum();

		if ( newIntersectionInfo.object->emitter == true )
		{
			delta_brdf_hitEmissive = true;
			lightIntensity = newIntersectionInfo.object->emission;

			attenuationFactor.Scaled_by_Spectrum_Value( obj->material_type->color );

			intensity = Attenuate_Light_Spectrum(
				attenuationFactor,
				lightIntensity
			);
		}
	}
	else
	{
		Spectrum lightSourceSamplingContribution;
		Spectrum brdfSamplingContribution;

		// light source sampling evaluation
		Objects * light;
		light = thisScene->AquireOneOfEmissiveObjects();


		double light_pdf = 0; // to be added
		double brdf_pdf = 0;
		double light_weight = 0;
		double brdf_weight = 0;

		Pnt3D pointOnLight;
		int i = 0;
		while ( i < 2 && occludedByObjects == true )
		{
			pointOnLight = light->samplePointOnObject();
			occludedByObjects = thisScene->Occluded(
				intersectionInfo->intersectionPoint,
				pointOnLight,
				light
			);

			i++;
		}

		if ( occludedByObjects == false )
		{
			newRayDirection = pointOnLight - intersectionInfo->intersectionPoint;

			brdf->BRDF(
				ray.direction,
				newRayDirection,
				attenuationFactor
			);

			attenuationFactor.Scaled_by_Spectrum_Value( obj->material_type->color );

			// light pdf 
			light_pdf = light->PDF_in_solid_angle ( pointOnLight, intersectionInfo->intersectionPoint, newRayDirection );

			//	brdf_pdf = obj->brdf_model->PDF ( ray.direction , newRayDirection );

			// geomery term????
			// according to PBRT page 765, geometric term cancel out ???

			Vector normal_on_light;
			light->getNormalDirection( pointOnLight, normal_on_light );
			double geometryTerm = GeometricTerm( ray, normalDirection, pointOnLight, normal_on_light );

			lightIntensity = light->emission;
			lightSourceSamplingContribution =
				Attenuate_Light_Spectrum(
					attenuationFactor,
					lightIntensity
				) * geometryTerm / light_pdf;
		}

		// evaluate BRDF sampling
		if ( light->isDeltaEmitter == false )
		{
			attenuationFactor = brdf->SampleBRDF(
				ray.direction,
				newRayDirection,
				normalDirection
			);

			Ray newRay( intersectionInfo->intersectionPoint, newRayDirection );

			Intersection newIntersectionInfo;

			if ( thisScene->IntersectionWithScene( newRay, newIntersectionInfo ) )
				if ( newIntersectionInfo.object->emitter == true )
				{
					{
						brdf_pdf = obj->brdf_model->PDF( ray.direction, newIntersectionInfo.normal, newRayDirection );
						//	weight = BalanceHeuristic ( 1 , brdf_pdf , 1 , light_pdf );
						attenuationFactor.Scaled_by_Spectrum_Value( obj->material_type->color );

						double cos_i = AbsDot( ray.direction, normalDirection );

						brdfSamplingContribution += Attenuate_Light_Spectrum(
							attenuationFactor,
							newIntersectionInfo.object->emission
						) * cos_i / brdf_pdf;
					}
				}
		}

		light_weight = light_pdf / ( brdf_pdf + light_pdf );
		brdf_weight = brdf_pdf / ( brdf_pdf + light_pdf );

		intensity += lightSourceSamplingContribution * light_weight;
		intensity += brdfSamplingContribution * brdf_weight;

		if ( intensity.HasNaNs() )
		//	printf ( "has nan" );
			return Spectrum();

		return intensity;
	}
}