nuclear engineering
virtual education

Built in Unity. Mostly solo project - responsible for nearly all artwork and programming.


This is a virtual lab for nuclear engineering undergrads. I'm responsible for the design, artwork, and (nearly all) programming; built in Unity with visuals in in Blender, Marmoset Toolbag, Substance Painter, and Affinity Designer.

Purdue University Prof. Stylianos Chatzidakis led this project to increase access to curriculum-necessary lab equipment.

Completed late 2023

3D artwork

Fullscreen >>>

The lab runs on the web, optimized for low-spec devices such as Chromebooks and tablets. There are at most 25,000 triangles rendered across 22 draw events. Size is just under 50mb.

Some subtle details in the models:

All of the equipment controls are modeled and fully functional.

My favorite piece of geometry is probably the high-poly detectors with their knurling; not necessarily a difficult trick, but always satisfying :)

and my favorite material is for the High Voltage Supply.


Built in Unity, I'm responsible for all of this project's scripting (except for the cable physics). Like the 3D artwork, everything is optimized for low-spec devices.

signal processing & equipment simulation

Each nuclear appliance is functional and simulates all of the necessary inputs and outputs. With the help of Prof. Chatzidakis and his team, I modeled each equipment's behavior in C#.

The lab targets 100,000 data samples per second, each processed by the equipment. Being a web-assembly app, I'm limited to a single CPU core and can't use Unity's Burst compiler. Even so, low-spec devices run the simulation at full speed.

The data histogram and oscilloscope line graph displays are shaders. Some equipment will write incoming data to textures that these shaders display as a graph.

cable visuals (obi rope)

For cable physics I use Obi Rope. My Obi settings are tuned for a decent balance between visual quality and performance.

Cable mesh updates are expensive; time increases linearly with vertex count, so I use flat ribbon meshes with cylindrical normals.

Cable colors are random so that users can keep track of what is connected to what.

The cables become semi-transparent via dithering when they may obscure important elements.

UX considerations for 3D

The user shouldn't lose draggable objects behind other objects or off screen, so I don't allow dropping objects behind UI elements, outside of the camera bounds, or while the camera is moving.

Camera 'frames' keep important objects in view regardless of aspect ratio.

Controls must be large enough for easy interaction, so I position frames to keep controls at sane screen-sizes. I also keep related frames and controls close together.