I’ve allocated quite a lot of spare time to writing on the project over the last week and have made progress on the renderer.

Indexed meshes rendered with simple lighting with Metal

A rough timeline of what I’ve done and in what order is:

  • Draw a triangle with hardcoded vertices.
  • Pass a sine value over time as a shader uniform. Use this to rotate the vertices in the shader and later to add to the rgb components to vary the brightness over time.
  • Pass a model matrix as a shader uniform to convert from object to world space.
  • Create rotation matrix in app and pass to shader to rotate triangle vertices.
  • Create parameterised view and perspective matrices to transform world coordinates to clip space coordinates.
  • Added meshes comprised of an arbitrary number of vertices references by index when rendering.
  • Implemented a basic memory management system based on block allocating a single large buffer and providing offsets to meshes.
  • Created an indexed cube model.
  • Introduced scene objects representing entities with uniforms that can be drawn using the mesh data they reference.
  • Created a textured mesh shader and a cube mesh with texture coordinates, along with bitmap texture data hand written in the app.
  • Created a coherent generated texture and modified cube to use fewer indexed vertices so that the texture coordinates aren’t shared between faces.
  • Added an icosahedron mesh that can be subdivided.
  • Refactored the scene object and mesh rendering code and data to remove hard coded aspects of it.
  • Implemented loading of png files as texture images, including handling whether they have an alpha channel or not.
  • Parameterised texture mesh to load different samples textures and added these to the example scene.
  • Simple Phong shading with a fixed point light source.

Adding lighting proved tricky as I wanted to do some matrix transformation for normals in the shader, but some of the functions available in GL Shading Language (mat4 inverse and mat4 to mat3), are not present in Metal Shading Language. Implementing this was a challenge and there is still work to be done to make this really usable. Before going much further with lighting I want to understand a bit more about rendering engine models for lighting and shadows.

This entry is part of a series on writing a Metal Renderer in Swift Playgrounds.