Raytracer Version 4: We have materials!

Another update to the Javascript real-time ray tracer.

For the previous version please check here:

The latest implementation now includes materials. These materials include a diffuse texture, diffuse colour, normal map, roughness value, roughness texture, and reflection amount.

The has changed the process to the following:

  1. For each bounce of light:
    1. First Draw Pass
      • Calculate the current eye position and ray vector.
      • If this not the first bounce pass, calculate the reflection amount.
    2. Second Draw Pass
      • Calculate the ray hits,
    3. Third Pass:
      1. For each material:
        1. Check if we hit an object. If we hit nothing, draw the sky gradient.
        2. Draw the ambient light value.
        3. Draw the Diffuse texture and colour to the diffuse layer.
        4. Calculate the normals using the model normal mixed with the normal map.
        5. Calculate the current surface roughness.
        6. Calculate the specular texture, store the roughness in the alpha channel.
    4. Third Pass:
      • Draw the ambient values
      • For each light calculate the specular and diffuse colours based on the light.
    5. Swap the draw buffers.
  2. Draw the result to the screen by merging the current and the previous frames.

The final result is starting to look pretty good. The textures for this tutorial we’re obtained from texture.com. If you’re not familiar with this sight, I highly recommend it for realistic textures.

Almost there, next I’ll be working on the dynamic models and refraction.

Give it a shot:

Open in new tab.

Keyboard Controls:
W, A, S, D - Movement
Left Arrow, Right Arrow - Rotate left and right.
1 - Show merged frame
2 - Show un-merged frame
3 - Show the last ambient light frame.
4 - Show the last point hit frame.
5 - Show the last ray frame.
6 - Show the last normals frame.
7 - Show the last eye location offest.
8 - Show the last diffuse texture frame.
9 - Show the last specular texture frame.

Note: This example requires a browser that supports WebGL2.

As always, please feel free to try out the code for yourself: