// only light sampling.. // left only for reference inline void EstimateDirectIllumination ( const Scene * thisScene, const Intersection * intersectionInfo, const Ray & ray, double & light_pdf, Spectrum & lightSourceSamplingContribution ) { 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; light_pdf = 0; // to be added if ( brdf->surfaceFlag == surface_delta ) { return; } // Spectrum lightSourceSamplingContribution; // Spectrum brdfSamplingContribution; // light source sampling evaluation Objects * light; light = thisScene->AquireOneOfEmissiveObjects(); 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 = Normalize( pointOnLight - intersectionInfo->intersectionPoint ); brdf->BRDF( ray.direction, newRayDirection, attenuationFactor ); attenuationFactor.Scaled_by_Spectrum_Value( obj->material_type->color ); // light pdf in angular form // should be returned for MIS light_pdf = light->PDF_in_solid_angle ( pointOnLight, intersectionInfo->intersectionPoint, newRayDirection ); // not sure !!! double pointSamplePdf = light->PDF(); Ray nextRay( intersectionInfo->intersectionPoint, newRayDirection ); Vector normal_on_light; light->getNormalDirection( pointOnLight, normal_on_light ); double geometryTerm = GeometricTerm( nextRay, normalDirection, pointOnLight, normal_on_light ); lightIntensity = light->emission; lightSourceSamplingContribution = Attenuate_Light_Spectrum( attenuationFactor, lightIntensity ) * geometryTerm / pointSamplePdf; } else { if ( DebugMode ) { printf( "Direct illimination can not sample a point on light source" ); } } }
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; } }