In a special edition, I would like to go over my experience in rendering the scene Veach-Ajar by Benedikt Bitterli. Since it is a scene with many objects, which has instances, transformations, and features a procedural checkerboard texture. While the scene is not officially a part of our assignments, it is a useful testbed for the ray tracer. Thus, I will share some of the problems that I encountered and how I solved them in this rather short post.
First, the final render looks like this, and it takes about a minute with 16 samples:
When I first started out, the initial renders were quite discouraging. Partly because, getting the ray tracer this far in the assignments, I thought there are no bugs related to the prior assignments. However, it turns out to be that this was not the case at all! I felt bitter and surprised that it took so long to figure out those bugs, but the joy of getting a proper render outweighs all hard feelings.
Here, there are many problems to spot at first sight. The pot on the left is missing, the top part of the pot in the middle is also missing. Also, there is an unnatural shadowing in the middle with circular patterns. Also, the checkerboard pattern is wrong.
I first worked on the circular shadow patterns on the wall object. When I debugged the black pixels, I have found out that during the shading, cos(theta) parameters are 0. Thus, the ray tracer tries to send a shadow ray, to a light that is the other side of the wall. To make sure how it looks with proper rendering, I decomposed the composite transformation matrix of the wall model. It has a translation to the +x direction and scaled in the x dimension. I imported the model to Unity3D, setup the lighting (compensated for the left-handedness), and observed how it should look under various settings. Then, I took another render in which I erased the wall from the object list. Then I saw that the teapot in the left and the teapot in the middle renders just fine. The wall has intersections in its local coordinates, then the inverse coordinates do not work well with the shadow rays.
It turns out that, after adding the transformations as a feature, I let transformed objects override the tmin values during intersection tests. They do it in their local space, which is inconsistent with the world space. Same with the shadow ray tests as well. Remember, the shadow ray test happens between the intersection point and the light position. I fed a distance parameter, so I only tell that the object is in shadow if there is an intersection within that distance. That distance also needs to be recalculated with the transformations, just before the shadow ray test. Now, in the correct version, the BVH, the wrapping object class, meshes, and spheres convert the intersection distances so that they respect the world space lengths. They only update the ray hit information and the ray hit distance only if they are below the world-space tmin value, that is the distance of the closest intersection so far.
This scene was quite useful in that regard when I compared it with the older scenes. The relative positions of the objects or the ones with transformations, luckily they did not cause any wrong output in the older ones. Presumably, even the ordering of the objects in the XML files got me lucky (or unlucky). This object has 21 objects, and they have homogeneously distributed around the scene. Some of them had transformations, and some of them not. Therefore, such problems with the transformations appear right away.
The last point was about the checkerboard pattern. I double-checked my implementation with the checkerboard pattern, and it seemed fine. However, the stripes were inconsistent in one axis. I thought this could be related to transformations as well. And it turns out that the same object had a scaling in the x-axis, too. Then, I figured out that the checkerboard pattern works in the object's local space. Therefore, before calculating the pattern, I multiply with the inverse transform to get the intersection point to the local space of the object. Then, when the checkerboard pattern is calculated, it works just fine.
All-in-all, this rather complex scene is not just a test for the ray tracer. It was a test of perseverance and tenacity for the one who is implementing it.
Comments
Post a Comment