示例#1
0
//trace the ray and find out the color at its intersection point with the scene
Vector4 Renderer::traceColor(Ray ray, Scene* scene, unsigned int recDepth) {

	Vector4 color(0,0,0);
	ray.min_t = ray.min_t + ray.epsilon_t;
	IntersectionData* iData = scene->intersect(ray);
	
	if (iData && (recDepth < m_recursionDepth)) { // sucessful intersection test


	  //=== EXERCISE 2.2.3 ===
		Vector3 N = (iData->normal).normalize();

		Vector3 R = ((N.operator*(2)).operator*(N.dot(-ray.direction))+ray.direction).normalize(); // calculate R

		Ray newRay(iData->position, R);
		newRay.min_t = newRay.min_t + ray.epsilon_t;

		color = traceColor(newRay, scene, recDepth+1).operator*(iData->reflectionPercentage) + ( m_shader->shade(iData, scene).operator*(1 - iData->reflectionPercentage)) ; // recursion
		
    }
	else {
		color = m_shader->shade(iData, scene);
		//color = scene->getBackground(); // background color
	}


	// clean
	if (iData!=NULL){
		delete(iData);
	}

	return color.clamp01();
}
Spectrum<constant::spectrumSamples> PathBRDF::randomBRDFSampling(bool& randomBRDFsampled,
                                                                 Spectrum<constant::spectrumSamples>& L,
                                                                 const Vector3D& wo,
                                                                 const MaterialBRDF& material,
                                                                 const Intersection& intersection,
                                                                 const TracerSpectrum& pathTracer,
                                                                 const int bounce,
                                                                 const BRDFType type) const {
    
    Vector3D wi(INFINITY, INFINITY, INFINITY);
    
    //Sample brdf of the give type.
    Spectrum<constant::spectrumSamples> f = material.samplef(&wi, wo, intersection, type);
    
    if(wi.x != INFINITY && wi.y != INFINITY && wi.z != INFINITY) {
        
        //BRDF has been sampled.
        randomBRDFsampled = true;
        
        //Normalize wi.
        wi.normalize();
        
        //Get pdf of wi sampled from brdf.
        float pdf = material.pdf(wi, wo, intersection, type);
        
        Spectrum<constant::spectrumSamples> weight(0.0f);
        
        //Check pdf to avoid 0/0 division (and NaN generation).
        //A spectrum composed of NaN values could bend all samples
        //during sum in Tracer classes.
        if(pdf > 0.0f) {
            
            weight = (f * fabsf(wi.dot(intersection.normal))) / pdf;
        } else {
            
            //Weight is 0, so all bounces will be useless.
            return L;
        }
        
        //Setup new ray to be traced.
        Ray newRay(MathUtils::addEpsilon(intersection.point, intersection.normal), wi);
        
        //Rendering equation with recursive path tracing calculation.
        L = L + weight * pathTracer.trace(newRay, bounce - 1);
    }
    
    return L;
}
示例#3
0
int main()
{

  Film film(401, 401);

  ngl::Vec3 pos(0, 0, 0);
  ngl::Vec3 lookAt(0, 0, 100);
  ngl::Vec3  up(0, 1, 0);



  Camera cam(pos, lookAt, up, 90.0, &film);

  Ray newRay(ngl::Vec3(0, 0, 0), ngl::Vec3(0, 0, 1));



  //cam.generateRay(200, 200, &newRay);
  std::cout << newRay.m_origin << newRay.m_direction << newRay.m_invDirection << std::endl;


  IsectData intersection;

  //film.show();

  //std::thread task(&Film::show, &film);

  auto mesh = Meshes::scene1();
  auto green = std::make_shared<Material>();
  green->m_diffuseColour = SDL_Color{0, 255, 0, 255};

  std::shared_ptr<Primative> scenePrim = std::make_shared<GeometricPrim>(mesh, green);

  Renderer new_renderer(&cam, &film, scenePrim);

  new_renderer.renderImage();
  //task.join();

  film.show();
  return EXIT_SUCCESS;
}
示例#4
0
文件: main.cpp 项目: exopole/gitVTK
int main(int argc, char *argv[])
{
	std::cout << "/////////////////////   POINT   //////////////////////////////////" << std::endl;
    Point newPoint(0,1,2);
    std::cout << "x : " << newPoint.x() << std::endl;
    std::cout << "y : " << newPoint.y() << std::endl;
    std::cout << "z : " << newPoint.z() << std::endl;
    newPoint.setY(5);
    Point pointB;
    std::cout << "y : " << pointB.y() << std::endl;

    if (! newPoint.isNotEqual(pointB))
    	std::cout << "equal" << std::endl;
    else
    	std::cout << "nonEqual" << std::endl;

	std::cout << "/////////////////////   VECTOR   //////////////////////////////////" << std::endl;

	Vector newVector, vect;
    newVector.setCoordonne(-8.0, 5.0, 6.0);
    Vector vec2(newPoint, pointB);
    Vector vec3(newVector, vec2);
    std::cout << "x2 : " << vec2.x() << std::endl;
    std::cout << "y2 : " << vec2.y() << std::endl;
    std::cout << "z2 : " << vec2.z() << std::endl;

    if (vect.vecteurNull())
    	std::cout << "vec Null" << std::endl;
    else
    	std::cout << "vec Non NUll" << std::endl;

    if (newVector.vecteurNull())
    	std::cout << "newVector Null" << std::endl;
    else
    	std::cout << "newVector Non NUll" << std::endl;

    std::cout << "dot => " << newVector.dot(vec2) << std::endl; 

    std::cout << "x3 : " << vec3.x() << std::endl;
    std::cout << "y3 : " << vec3.y() << std::endl;
    std::cout << "z3 : " << vec3.z() << std::endl;

	std::cout << "/////////////////////   RAY   //////////////////////////////////" << std::endl;

	Ray newRay(pointB,newPoint);
	std::cout << "origine : " << newRay.P0().x() << ", " << newRay.P0().y() << ", " << newRay.P0().z()<< std::endl;
	std::cout << "direction : " << newRay.P1().x() << ", " << newRay.P1().y() << ", " << newRay.P1().z() << std::endl;

	std::cout << "/////////////////////   Triangle   //////////////////////////////////" << std::endl;

	Point pointC(6,8,5);
    Point V2(0,-1,-10);
    Point V0(5,-50,59);
    Point V1(9,0,-25);
	Triangle newTriangle(V0,V1,V2);
	std::cout << "coordonnee : " << newTriangle.V0().x() << ", " << newTriangle.V1().y() << ", "<< newTriangle.V2().z() << std::endl; 

	std::cout << "/////////////////////   Point/Triangle   //////////////////////////////////" << std::endl;
	Point I;
	std::cout << newRay.P0().x() + 6 * newVector.x() << std::endl;
	std::cout << newRay.P0().y() + 6 * newVector.y() << std::endl;
	std::cout << newRay.P0().z() + 6 * newVector.z() << std::endl;
	I.setCoordonne(newRay.P0().x() + 6 * newVector.x(), newRay.P0().y() + 6 * newVector.y(), newRay.P0().z() + 6 * newVector.z());	
	std::cout << "coucou" << std::endl;

	std::cout << "/////////////////////  test intersect   //////////////////////////////////" << std::endl;

	int test;
	test = intersect3D_RayTriangle(newRay, newTriangle, I);
	std::cout << "I : " << I.x() << ", " << I.y() <<", "<< I.z() << "\n test : " << test << std::endl; 


	std::cout << "/////////////////////   VECTOR/Triangle  //////////////////////////////////" << std::endl;

	Vector newVector2(newTriangle.V0(), newTriangle.V1());

    std::cout << "x : " << newVector2.x() << std::endl;
    std::cout << "y : " << newVector2.y() << std::endl;
    std::cout << "z : " << newVector2.z() << std::endl;

    return 0;
}
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;
	}
}
Spectrum PathTracer::Integration (
	const Scene * thisScene,
	const Ray & ray,
	size_t currentDepth
) const
{
	// Russian Roulette
	// probility to stop this path
	double rr = 0.01;
	double randnum = getUniformRandomNumber( 0.0, 0.99 );
	if ( randnum < rr && currentDepth > 5 )
		return Spectrum();

	if ( currentDepth == maxDepth )
		return Spectrum();

	Intersection intersectionInfo;

	// check intersection between ray and scene
	if ( ! thisScene->IntersectionWithScene( ray, intersectionInfo ) )
		return Spectrum();

	// if there is an intersection
	Spectrum intensity;
	Spectrum emission;

	Objects * obj = intersectionInfo.object;

	if ( obj->emitter )
	{
		emission = obj->emission;
	}

	BRDFModels * brdf = obj->brdf_model;

	// Get surface (macro) normal direction
	Vector geometryNormalDirection ( 0 , 0 , 0 );
	Vector sampledNextDirection ( 0 , 0 , 0 );

	geometryNormalDirection = intersectionInfo.normal;

	double pdf = 0;

	Attenuation attenuationFactor = 
		brdf->SampleBRDF(
			ray.direction,
			sampledNextDirection,
			geometryNormalDirection,
			pdf
		);

	Ray newRay(
		intersectionInfo.intersectionPoint,
		sampledNextDirection
	);

	Spectrum Li =
		Integration(
			thisScene,
			newRay,
			currentDepth + 1
		);


	if ( !Li.isEmpty() )
	{
		attenuationFactor.Scaled_by_Spectrum_Value( obj->material_type->color );

		double cos_i = AbsDot( sampledNextDirection, geometryNormalDirection );

		intensity +=
			Attenuate_Light_Spectrum( attenuationFactor, Li ) * cos_i / pdf;
	}

	// weight the radiance back after Ruassian Roulette
	intensity = ( currentDepth > 5 ) ? ( intensity / ( 1 - rr ) ) : intensity;

	ASSERT_NAN( intensity );

	return emission + intensity;
}
// with direct illumination
// this one actually does not do the right things on DI with MIS
// left only for reference
Spectrum PathTracer::IntegrationWithDI (
	const Scene * thisScene,
	const Ray & ray,
	size_t currentDepth
) const
{
	// Russian Roulette
	// probility to stop this path
	double rr = 0.01;
	double randnum = getUniformRandomNumber( 0.0, 1.0 );
	if ( randnum < rr && currentDepth > 5 )
		return Spectrum();

	if ( currentDepth == maxDepth )
		return Spectrum();

	Intersection intersectionInfo;

	// check intersection between ray and scene
	if ( !thisScene->IntersectionWithScene( ray, intersectionInfo ) )
		return Spectrum();

	// if there is an intersection
	Spectrum intensity;
	Spectrum lightSourceSamplingContribution;
	Spectrum brdfSamplingContribution;

	double brdf_pdf = 0;
	double light_pdf = 0;

	double brdf_weight = 0;
	double light_weight = 0;

	Objects * obj = intersectionInfo.object;

	if ( obj->emitter )
	{
		intensity += obj->emission;
	}


	BRDFModels * brdf = obj->brdf_model;


	// **************** evaluate direction illumination ******
	if ( !obj->emitter )
		EstimateDirectIllumination(
			thisScene,
			& intersectionInfo,
			ray,
			light_pdf,
			lightSourceSamplingContribution
		);

	// ******************** end of direct illumination **********************

	// BRDF sampling is evaluated twice????

	Vector geometryNormalDirection;

	geometryNormalDirection = intersectionInfo.normal;

	Vector sampledNextDirection( 0, 0, 0 );
	Attenuation attenuationFactor;

	attenuationFactor = brdf->SampleBRDF(
		ray.direction,
		sampledNextDirection,
		geometryNormalDirection,
		brdf_pdf
	);

	Ray newRay(
		intersectionInfo.intersectionPoint,
		sampledNextDirection
	);

	Spectrum Li =
		IntegrationWithDI(
			thisScene,
			newRay,
			currentDepth + 1
		);

	if ( !Li.isEmpty() )
	{
		attenuationFactor.Scaled_by_Spectrum_Value( obj->material_type->color );

		double cos_i = AbsDot( sampledNextDirection, geometryNormalDirection );

		brdfSamplingContribution += Attenuate_Light_Spectrum( attenuationFactor, Li ) * cos_i;
	}


	if ( light_pdf == 0 && brdf_pdf == 0 )
	{
		return intensity;
	}
	// MIS weight
	BalanceHeuristic( 1, light_pdf, 1, brdf_pdf, light_weight, brdf_weight );

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

	intensity = ( currentDepth > 5 ) ? ( intensity / ( 1 - rr ) ) : intensity;


	ASSERT_NAN( intensity );

	return intensity;
}
示例#8
0
Colour Raytracer::Trace(const Ray& ray, RandomGenerator* random, int depth, int depth2, std::list<IMedium*>& mediumList)
{
	if(depth >= this->maxIterations)
		return Vec3(0,0,0);

	// First find intersection with closes geometry.
	IntersectResult result;
	geometry->Intersect(ray, result);

	// First depth2=0, we also include "singular light geometry"
	if(depth2 == 0 && this->singularLightGeometry)
		singularLightGeometry->Intersect(ray, result);

	if(result.distance >= std::numeric_limits<Scalar>::max())
		return Vec3(0,0,0); //< Return "sky" radiance

	// Calculate position of intersection.
	
	Vec3 position = result.distance * ray.direction + ray.origin;
	Vec3 cameraDirection = -ray.direction;

	// Check for interaction with medium (scaterring)
	ColourScalar scateringWeight;
	Vec3 scatteringPos, scatteringDir;
	if(ray.medium->SampleScattering(ray.origin, result.normal, position, random, scateringWeight,
		scatteringPos, scatteringDir))
	{
		Ray newRay(scatteringPos, scatteringDir);
		newRay.medium = ray.medium;
		return scateringWeight.CMultiply(Trace(newRay, random, depth+1, depth2, mediumList));
	}


	// Now calculate mediums.
	bool isInsideMedium = cameraDirection * result.normal < 0;
	IMedium* insideMedium, *outsideMedium;
	if(isInsideMedium)
	{
		// FIXME: sometimes due to numerical errors, we ignore those hits (alternative - set to vacuum).
		if(mediumList.size() == 0)
			return Vec3(0,0,0);
		outsideMedium = mediumList.back();
		insideMedium = ray.medium;
	} else {
		outsideMedium = ray.medium;
		insideMedium = result.material->insideMedium;
	}

	// Compute radiance of point.
	Vec3 L(0,0,0);

	// 1) self radiance
	if(SELF_LIGHTNING_BIT(depth, depth2) && result.material->surfaceLight != 0)
		L = SELF_LIGHTNING_MASK(depth, depth2, result.material->surfaceLight->Radiance(position, cameraDirection, result.normal));
	
	// Early exit for non-reflective materials. This is useful for singular lights.
	if(result.material->bsdf == 0)
		return scateringWeight.CMultiply(L);
	SamplingType samplingType = result.material->bsdf->GetSamplingType(cameraDirection, result.normal);
	

	// 2) radiance from singular sources
	if(DIRECT_LIGHTNING_BIT(depth, depth2) && ((samplingType & Singular) != 0))
	{
		for(std::vector<ISingularLight*>::iterator i = lights.begin(); i != lights.end(); i++)
		{
			ISingularLight* light = *i;
			Vec3 towardsLightDirection;

			// We can use radiance at position for point lights (no translate).
			Vec3 Li = light->Radiance(position, towardsLightDirection, geometry);

			// Early exit for shadowed lights (no BRDF execution) && when backfacing lights.
			if(Li.x == 0 && Li.y == 0 && Li.z == 0)
				continue;
			 
			// Weights with cosine.
			Vec3 t = (result.normal * towardsLightDirection)*Li.CMultiply(result.material->bsdf->BSDF(position, result.normal,
				 cameraDirection, towardsLightDirection, result.materialData, insideMedium, outsideMedium));
			L += DIRECT_LIGHTNING_MASK(depth, depth2, t);
		}
	}
	// 3) caustics map lightning
	if(PHOTONMAP_CAUSTICS_BIT(depth, depth2) && this->causticsMap)
	{
		std::vector<Photon*> photons;
		causticsMap->FindInRange(position, this->causticsPhotonMapGatherRadius, photons);

		// We estimate radiance at the point.
		Vec3 Flux(0,0,0);
		for(std::vector<Photon*>::iterator i = photons.begin(); i != photons.end(); i++)
		{
			Photon* p = *i;

			// Cull backfacings.
			if(p->outDirection * result.normal < 0)
				continue;

			Flux += p->power.CMultiply((result.normal * p->outDirection) * result.material->bsdf->BSDF(position, result.normal, p->outDirection, cameraDirection, result.materialData,
				insideMedium, outsideMedium));
		}

		Vec3 t = Flux / (PI*this->causticsPhotonMapGatherRadius*this->causticsPhotonMapGatherRadius);

		L += PHOTONMAP_CAUSTICS_MASK(depth, depth2, t);
	}

	// Calculate number of samples
	int numberOfSamples = std::min(result.material->bsdf->GetMaxNumberOfSamples(cameraDirection, result.normal), 
		(int)(this->secondaryRays * exp(-secondaryRayDecay*depth2)));

	bool isPerfectReflection = numberOfSamples <= this->gatherIterationThreeshold;	//< This will only allow bigger iteration depth.

	// 4a) indirect photon map rendering (it is either this or hemisphere integration), reflection is still handled with
	// normal raytracing
	if(PHOTONMAP_GLOBAL_BIT(depth, depth2) && !isPerfectReflection && this->globalMap)
	{
		std::vector<Photon*> photons;
		globalMap->FindInRange(position, this->globalPhotonMapGatherRadius, photons);

		// We estimate radiance at the point.
		Vec3 Flux(0,0,0);
		for(std::vector<Photon*>::iterator i = photons.begin(); i != photons.end(); i++)
		{
			Photon* p = *i;

			// Cull backfacings.
			if(p->outDirection * result.normal < 0)
				continue;

			Flux += p->power.CMultiply((result.normal * p->outDirection) * result.material->bsdf->BSDF(position, result.normal, p->outDirection, cameraDirection, result.materialData,
				insideMedium, outsideMedium));
		}

		Vec3 t = Flux / (PI*this->globalPhotonMapGatherRadius*this->globalPhotonMapGatherRadius);

		L += PHOTONMAP_GLOBAL_MASK(depth, depth2, t);

		// We skip through
		return scateringWeight.CMultiply(L);
	}


	// 4b) integrated radiance over hemisphere
	if((samplingType & MultipleSample) == 0 || INDIRECT_LIGHTNING_BIT(depth, depth2) == false)
		return scateringWeight.CMultiply(L);

	
	if(depth2 < this->maxGatherIterations || isPerfectReflection)
	{
		// If perfect reflection, we need only one ray to approximate.
		for(int i = 0; i < numberOfSamples; i++)
		{
			Vec3 newDirection;
			ColourScalar S = result.material->bsdf->Sample(i, numberOfSamples, position, result.normal, 
				cameraDirection, random, result.materialData, insideMedium, outsideMedium, newDirection); 

			// Trace new ray.
			Ray newRay(position, newDirection);
			bool needsPop = false, needsPush = false;
			Scalar translateInwards = -1;
			if(isInsideMedium)
			{
				// In-Out combination
				if(newDirection * result.normal > 0)
				{
					newRay.medium = mediumList.back();
					mediumList.pop_back();
					needsPush = true;
					translateInwards = 1;
				}
				// In-In combination
				else
					newRay.medium = ray.medium;
			}
			else {
				// Out-out combination
				if(newDirection * result.normal > 0)
					newRay.medium = ray.medium;
				else
				{
					newRay.medium = result.material->insideMedium;
					mediumList.push_back(ray.medium);
					needsPop = true;
					translateInwards = 1;
				}
			}

			// Translation of ray position so the whole solid angle can be sampled (also in corners)
			newRay.origin = newRay.origin + (translateInwards * this->hitTranslate) * ray.direction;

			ColourScalar newL = Trace(newRay, random, depth+1, depth2 + (isPerfectReflection ? 0 : 1), mediumList);

			// Undo medium list to prev state
			if(needsPush)
				mediumList.push_back(newRay.medium);
			if(needsPop)
				mediumList.pop_back();

			// NaN check (FIXME: must get rid of it and find the source).
			if(newL.x != newL.x || newL.y != newL.y || newL.z != newL.z)
			{
				continue;
			}

			// Add already weighted result to intensity.
			Vec3 t = S.CMultiply(newL);
			L += INDIRECT_LIGHTNING_MASK(depth,depth2,t);
		}
	}

	return scateringWeight.CMultiply(L);

}