Path tracing with point lights

Started by
2 comments, last by Bacterius 10 years, 10 months ago

Hi.

I am currently try to get path tracing to work, and I think I got the basic understanding of what is going on correct.

However I would like to get it to work with point lights as well - seeing as how the rays i trace would most likely never hit a point light what is the correct approch for doing this?

I have more or less followed the same approach as prestented here: http://www.iquilezles.org/www/articles/simplepathtracing/simplepathtracing.htm

So my code looks sorta like this:


(if ray hits scene:)

std::vector<PointLight*>::iterator it;
				Vector3 dirLightRes = Vector3(0.0f);
				for(it = m_lights.begin(); it != lights()->end() ; it++){							
					
					PointLight *light = *it;
		
					Vector3 lightOri = light->position();
					Vector3 lightDir = (lightOri-hitInfo.P).normalized();
					HitInfo shadowInfo;
					Ray shadowRay;
					shadowRay = Ray(hitInfo.P+(epsilon*lightDir),lightDir);
					if(trace(shadowInfo,shadowRay)){
		
					}
					else{
					
				       float ndl = std::max(0.0f, dot(shadowRay.d,hitInfo.N));
					dirLightRes +=  ndl* light->color(); 				}

					
					
				}
				
				//indirect light:
				Vector3 diffuseResult;

				Ray r = Ray(hitInfo.P,getRandomNormalInHemisphere(hitInfo.N));
				r.o += r.d*epsilon;
				if (traceScene(r, diffuseResult, depth)){

					shadeResult = (hitInfo.material->getDiffuseColor ()) + (diffuseResult*dirLightRes) ;
				}

Is this the correct approch ? Not all my test scenes produce the result i would expect (one of them fails to show shadows the way i expected it too) but I am not sure if this is a problem with my path tracing, number of samples or because it is simple tea pot scene and I got a lot of misses on my traces as there isnt much geomety there.

I would have assumed that each reccursive call would need to decrease the amount of colour contributed as well, is this correct? I haven't been able to find any places where this is discussed but it seems logical... ?

Any input is very much appriciated.

Its all a matter of will power
Advertisement

Hello,

I haven't read the approach from I. Quilez, but as I have some knowledge in path tracing I will give you few points. In stadard path tracing you're performing something like this:


TracePath(Ray* r)
{
     IntersectResult result;
     result = Raytrace(r);

     if(!result.hit)
     {
          return float4(0.0f);
     }

     Ray next = GenerateRay(r);

     return result.shape->emissivity + dot(result.normal, r->direction) * result.shape->color * TracePath(&next) * PDF;
}

Where you generate your ray with some probability distribution function - PDF.

Now you want to perform an explicit light sampling step, but still having the solution unbiased. Basically you sample each path step the light, although if you suddenly hit the light now (in next path step), it must not contribute with emissivity (as you already counted that in explicit light sample step).

Another thing is, you don't want to sample all lights at once. You want to sample just one of them (otherwise it would be hard to scale the method for large scenes). Basically you do something like this:


TracePath(Ray* r, float E = 1.0f)
{
     IntersectResult result;
     result = Raytrace(r);

     if(!result.hit)
     {
          return float4(0.0f);
     }

     Light* light = PickLight();
     Ray explicit = GenerateRayToLight(r, light);
     IntersectResult shadow = Raytrace(explicit);

     Ray next = GenerateRay(r);

     return result.shape->emissivity + dot(result.normal, r->direction) * result.shape->color * (TracePath(&next, shadow.shape->emissivity ? 0.0f : 1.0f) * PDF + dot(result.normal, explicit.direction) * shadow.shape->emissivity);
}

This performs just *dumb* Lambert's law for explicit light sample, but works well enough.

Now to your question:

1.) I would have assumed that each reccursive call would need to decrease the amount of colour contributed as well, is this correct?

It actually has to - see the code I posted, you multiply next path step by color at current hit position.

As for your code, I haven't through the whole code, but I don't think it's correct - you're missing some factors in there. Also note that precision issues might hurt a bit. Check whether you're pushing your ray origins enough far from the surface by epsilon!

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

Thanks a lot for your reply and for the example code!

When you say "emissivity" in the code snippet, do you mean this as a diffuse colour of the trace hit, or the colour of the light being sampled?

Its all a matter of will power

The most important thing to remember is that when you sample a point light (or any explicit point in the world) you need to divide by the distance squared to properly evaluate the solid angle term. When you do a random walk you don't have to because that's already implicitly handled by the geometry intersection process.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

This topic is closed to new replies.

Advertisement