Riko Ophorst
Rendering & Software Engineer
4+ years professional experience (incl. internships) Started working professionally in Sep 2018, including my initial internship at OTOY. Does not include internships from before that date.
C++, C, HLSL, GLSL, MSL, SPIRV
Vulkan, Metal, D3D11/12, CUDA, CMake, RTX, Windows, macOS, Linux
Raytracing & pathtracing
Realtime 3D rendering
R&D in Emerging Technologies
Cross-platform & porting
GPU & CPU optimizations
2 shipped products
4 shipped games
5 game jams
Creative Media & Game Technologies (BSc, July 2019)
At Breda University in the Netherlands
Tremble
  • Multiplayer FPS engine
  • C++ / DirectX 12
  • GPU Skinning / Skeletal animation
  • Advanced rendering architecture
  • Hierarchical view frustum culling
What is Tremble?
Tremble is a 16-week second year project, during which a total of 8 people worked on the engine - I was the team lead during all those weeks. The original idea was to make it a multiplayer FPS engine, and although we do have some multiplayer FPS gameplay, it's not worth showing off. What I do want to show off though, is the rendering of this engine.

I was solely responsible for the rendering of the engine. It was the first time for me doing anything with DirectX 12. The engine supports hierarchical view frustum culling and has support for skeletal animations thanks to the GPU skinning that I implemented.

Other than that, the engine has a pretty advanced rendering architecture, fully abstracting the DirectX 12 API so that it has an interface that is a lot friendlier to use for the average programmer.
Technical specifications
  • Team lead of 8 other programmers
  • C++ / DirectX 12
  • 16 weeks of total development time
  • Responsible for all rendering in the project
  • Hierarchical view frustum culling
  • Skeletal animations using GPU skinning
View the source code on GitHub
Using DirectX 12 to build the rendering
This is the first time that I've worked with DirectX 12, and I soon realized that DirectX 12 has a lot of overhead in the sense that you need to type a huge amount of code to really do anything with it.

To relieve that issue a little bit, I built an advanced wrapper around the DirectX 12 CommandList and CommandQueue objects. It is an absolute godsend. You can now easily start a new command list, start recording commands and send it over to the GPU in less than 5 lines of code! And the CPU-GPU syncing is still completely flexible, you can still decide how the synchronization between CPU and GPU should happen. It is quite a nice and dynamic system. I'm quite fond of it - if you couldn't tell.

You can checkout the implementation here.


Easy to use GPU resources
Managing GPU resources can be a pain in plain DirectX 12. That's why I wrapped the most common types of GPU resources, such as:
  • StructuredBuffers
  • TypedBuffers
  • UploadBuffers
  • ByteAddressBuffers
  • ColorBuffers
  • DepthBuffers
All those types of buffers automatically have descriptors generated and attached to them, so you don't ever need to worry about descriptors again. It's all taken care of.

You can checkout the implementation here.


Hierarchical view frustum culling
In Tremble I wanted to experiment a bit with optimizing the number of drawcalls. One way of doing that, is with a technique called hierarchical view frustum culling.

Hierarchical view frustum culling works by storing the entire scene in an octree based on each mesh's bounding box. You then test the camera view frustum against the octree to see what objects are within view of the camera. If an object is in view, a draw call gets send to the GPU and it gets rendered. If it isn't in view, the object gets ignored.

For a visualization of hierarchical view frustum culling, check out the second video on the top of this page.

You can checkout the implementation of the octree here.
You can checkout the implementation of the culling logic here (in the Renderer::Draw() method).


Skeletal animations thanks to GPU skinning
GPU skinning is the act of transforming the vertices of a mesh on the GPU based on a set of bone transforms. By moving around the bone transforms, the vertices will then also move accordingly to the weights that were assigned to corresponding bone transforms.

For a demo of what this is, check out the very first video on the top of this page.

You can checkout the model loading & animation importing here.
You can checkout the animation playback & bone transform calculations here.
You can checkout the vertex shader used to do the actual GPU skinning here.
textneedstobeherelol