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
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
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.