Jump to content
  • Advertisement
Sign in to follow this  
Oluf

Path tracing with point lights

This topic is 1883 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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. 

 

 

 

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites

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?

 

 

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!