Exploring WebGL Tech

This content was originally created for a graduate project at the Savannah College of Art and Design. The post was written in July 2019 but backdated to the original date of the project. Enjoy!

Project Summary

The goal of this project is to dive head-first into 3D graphics programming by researching, experimenting and finally crafting a 3D scene using WebGL without the assistance of any existing libraries.

Experiment 1

Scroll mouse to zoom

The demo above uses WebGL to display a rotating cube geometry with a texture map of this image. No graphics libraries have been used, however a common math library called Sylvester.js augmented with glUtils.js helps with some of the matrix operations. I was able to create this thanks to MDN Getting started with WebGL and Joe Groff’s Intro to modern OpenGL.

Shaders are really interesting, and it’s fun to know I’m coding something that will be directly executed by the GPU.

Experiment 2 / Final

Drag to rotate, scroll mouse to zoom

Project Notes

This project was very challenging. The combination of 3D math, matrix math, the opaque GPU API, and lack of debugging tools made it difficult to make progress. However, I learned quite a lot in the process. I went from zero GL experience to understanding the basics of the graphics pipeline and being able to draw geometry with graphic textures.

At this point I’ve created four object classes in JavaScript: Cube, Disc, Cylinder, and Tree. This allows for quickly adding any of those objects to the scene with one line:

new Cylinder(gl, width, height, segments, position, texture, textureScale);

Each one of the classes was easier to create than the last as I understood more of how to create geometry and the math involved in manipulating it.

The scene above consists of two Cylinders (the bricks and the fence), one Disc (the grass), and five placed Trees (plus one special fungi every once in a while 😊)

Issues

One particularly complicated issue was getting the trees to draw in the correct order so that foreground tress do not appear to cut out trees behind them. I partially accomplished this by sorting the trees by distance to the camera. This works great unless two trees are close enough to touch/overlap in which case, depending on the view angle, part of one tree may be closer to the viewer than the other tree even if the position of the tree is further away. This causes a graphical error which blocks out part of one tree.

The fix for this is to make sure trees are never so close that they would touch each other, but I decided to leave this in as a demonstration of something that was challenging to figure out.

Conclusion

I have a much better understanding of graphics programming and the GPU rendering pipeline as a result of this project. I’m certain this knowledge will come in handy for future game and software development projects. I’m pleased with the outcome both in personal growth as well as the final scene above.

Thomas Renck

I make things. Sometimes I un-make things. Most of the time I write code and teach on intentionality in design.