I'm implementing my own ray tracer as an iPad app for a school project. At the moment this is the result:
I need to add the last requirement, soft shadows, but I can't find a complete reference anywhere. If I understood well, to implement this feature I have to shoot many ray from an intersection point to mt light source. This one must be an area light. Suppose I use a sphere, my questions are:
- Which point on the sphere I must use to calculate the shadow ray?
- How do I average the result?
You are standing at a point P with local surface normal N, and need to find out the illumination arriving from spherical light source L with center C hanging above the horizon, uniformly and happily radiating energy on visible frequencies. To get soft shadows you will need to send multiple occlusion detector rays (shadowfeelers) towards different points on L, but let's do more than just that.
The picture makes it pretty clear that direct light can only arrive at P from hemisphere HF, so it is the only part of the sphere you have to sample - send shadowfeelers to - in order to accurately assess L's contribution to illumination at P. However, while generating points on a sphere is simple, here we have just a hemisphere that isn't necessarily aligned with any of the world coordinate axes, complicating the math. But the real problem is elsewhere - if we sampled HF uniformly, we would give equal treatment to its parts that face P head on, and to those that are nearly sideways. This is a waste, and it's better to focus our computation on areas that send more energy towards P.
We make a quick observation that all these shadowfeelers are actually aimed towards disc D that shares the center with L (i.e. is great circle of L) and is orthogonal to a line connecting P and C.
This means that rather than generate points on HF, we can generate them on disc D, which is not only simpler to do, but also - assuming uniform point distribution on D - guarantees that shadowfeeler density on HF will be locally proportional to the area's potential contribution, nicely solving the problem we had above.
Another way of looking at this is that you need to generate rays within a cone that has P as an apex and D as a base.
To sum it up:
- Assume some total amount of light E arriving from L to P. You may base it on distance between L and P, angular spread of L over P, or something even more complicated.
- Generate a set of M random, uniform shadow rays from P towards disc D.
- If a ray R intersects anything before hitting L, there is no energy transfer along this path.
- Otherwise:
- multiply E/M by a dot product of normal vector N at P and (normalized) R,
- add the result to the light transferred so far.
- Repeat for all M rays.
TO DO: optimizations (detect if L is fully/partially under local horizon, vary M with angular spread of L over P, use stratification and/or adaptive sampling, cache occluder hits, etc.)
PS. The above makes a ton of assumptions and simplifications, and is not correct photometrically, but should do for an iPad ray tracer.
来源:https://stackoverflow.com/questions/31709332/ray-tracing-soft-shadow