Prism
Raytraced and Raymarched Wonders
by Jason Heflinger
Overview
Prism is my continuously-developed toy renderer project! Using the raytracing and raymarching, it renders geometry and abstract shapes with various lighting and effects to create interesting scenes. It also functions a little bit as a modeler as to help the user have creative freedom to create whatever scenes they wish. As I keep working on it, it will continuously improve and support new features and exciting techniques!
Motivation
Despite my project portfolio being quite... diverse, I'm trying to get into a career in computer graphics! Unfortunately, it's quite hard to break into the field though (at least when compared to other fields like web development). Resources to learn are not as nearly as popular, and even in education it's rarely touched on. And so, this project is what I hope to be my little crowbar that lets me break my way in. It's a culmination of my self-learning with computer graphics, all in a nice packaged showcase application that outputs pretty pictures and videos!


Raytraced "Viking Room"
Technologies
The only external libraries as of now being used are Vulkan and Raylib! I supposed technically I'm using my own utilities library that I wrote, but I'm not sure that counts. Raylib is used for the UI and window handling while Vulkan is used for the actual heavy-duty rendering. This means that there is inter-op happening between OpenGL from Raylib and Vulkan itself! While unconventional. I chose to do it this way for 2 main reasons:
  1. I thought it would be a fun and cool quirk to play around with
  2. Having the UI and viewport be confidently stable with Raylib/OpenGL will help when experimenting dangerously with Vulkan
Other than this, everything is in-house! At the end of the day, this is a learning project, and there is no better way to learn than to reinvent all my wheels.
Features
Prism features plenty of different tools to aid with rendering!

Raytracing

At it's core, prism renders everything via raytracing! There is no rasterizing done, no vertex shaders, no fragment shaders, just compute shaders!

If you don't know how raytracing works, each pixel is passed into a compute shader, used to create a ray with a position and direction, and then traced by intersecting with the defined geometry to determine if it was hit or not. It's that simple! With each "hit" pixel, we can then use the calculated distance to the intersection as well as the direction of the normal to then do some basic lighting and view our geometry.


From NVIDIA

Although eventually I'll probably try adapt to rasterizing triangles and raytracing the triangle pixels instead, I wanted to truly dive into pure raytracing to grasp everything it entails. Right now it's also accelerated with a simple BVH, so even at millions of triangles it's still fairly fast!


60 FPS on the 1 million triangle "buddha"


SDF Rendering / Raymarching

Prism also features raymarching to do SDF rendering! SDF rendering allows us to make some really cool and unorthodox shapes that would be normally impossible to model with traditional geometry, such as blobs, volumetric clouds, and even fractals!


Mandelbulb fractal

If you don't know how raymarching and SDFs work, you essentially do the same with raytracing, except you march the ray across space. Instead of calculating whether it intersected or not, you take the distance to the nearest object surface from a given point. You then "march" the point ahead by this given distance until you reach a distance small enough to consider a "hit". By raymarching, we can describe objects with functions to smoothly render irregular shapes without having to define them with millions of polygons.



For the basic shapes this can be pretty fast, although for more complex shapes a larger cap of marches must be applied and thus the frame time to render shapes like the Julia set can get pretty nasty.


Julia set fractal

Phong Lighting

For lighting, I've implemented basic Phong Lighting. If you want to know more specifically about how this works, I won't bore you with the equations, but you can read more about it on wikipedia. The TLDR of how it works is that we define lights and materials as a combination of ambient, diffuse, and specular constants, which then in turn combine together to make some pretty cool lighting despite being a quick and simple lighting model.


Some neat reflection effects

Although it isn't the most versatile model, it can still make some pretty cool scenes! This alongside some basic shadows by tracing rays towards light and looking for obstructions, and we can get some pretty neat geometry out of giving our models some reflection.

Frameless Rendering

I have a blog post that really details how I did frameless rendering here if you want to get the whole write-up on it, but essentially what I did was make pixels update randomly as to give the rendering a cool motion blur effect and reduce frame times! While it isn't all that much of a help, the effect on movement is still visually pleasing and looks a little but like this:


Frameless Rendering

Volumetric Rendering

Using the power of SDF rendering, I was also able to model some volumes to make a cloud! This is done by modeling light diffusion in a volume by marching through a given SDF shape, which gives it some opaqueness. Then by displacing a sphere a good bit and adding in some softening and shading, a fairly realistic cloud is made!


Small Pink Cloud

What's to Come
Right now it definitely isn't the most performant software, and there's plenty of ways to do better lighting and model different materials! I'm still working on brushing up volumetric rendering, but I plan on working on upgrading my lighting beyond phong lighting and doing some path tracing next!!