I was working on my ray tracer written in C++ following this series of books: Ray Tracing in One Weekend. I started working a little bit on my own trying to implement features that weren't described in the book, like a BVH tree builder using SAH, transforms, triangles and meshes.
NOTE: The BVH implementation is based on two main resources which are this article: Bounding Volume Hierarchies and C-Ray (A ray tracer written in C).
After I implemented all of that I noticed that there was some weirdness while trying to use some materials on meshes. For example, as the title says, the metal material looks completely black:
In the first image you can see how the metal material should look like and in the second one you can see how it looks like on meshes.
I spent a lot of time trying to figure out what the issue was but I couldn't find it and I couldn't find a way of tracking it.
If you want to take a look at the code for more clarity the ray tracer is on GitHub at https://github.com/ITHackerstein/RayTracer.
The branch on which I'm implementing meshes is meshes
.
To replicate my build environment I suggest you follow this build instructions:
$ git clone https://github.com/ITHackerstein/RayTracer
$ cd RayTracer
$ git checkout meshes
$ mkdir build
$ cd build
$ cmake ..
$ make
$ mkdir tests
At this point you're almost ready to go except you need the TOML scene file an the OBJ file I'm using which are these two:
Download them and place them in the build/tests
and after that make sure you are in the build
folder and run it using the following command:
$ ./RayTracer tests/boh.toml
After it finishes running you should have a tests/boh.ppm
file which is the resulting image file stored using PPM format. If you don't have a software that let's you open it there are multiple viewers online.
NOTE: My platform is Linux, I didn't test it on Windows or Mac OS.
EDIT
Does the mesh work with other materials?
So as you can in the first image and especially in the second one we have we have some darker rectangular spots, and also the lighting seems kinda messed up. In the third image you have an idea of how it works on a normal primitive.
I finally figured it out thanks to the tips that @Wyck gave me.
The problem was in the normals, I noticed that the Metal::scatter
method received a normal that was almost zero. So that's why it was returning black.
After some logging, I found out that the Instance::intersects_ray
method was not normalizing the transformed normal vector, and that's what caused the issue. So, in the end, the solution was simpler than I thought it would be.