The Benin Bronze Experience

The Benin Bronze Experience is a VR exploration into what it was like to be a bronze caster in the ancient Kingdom of Benin. In this project, I have worked with 33 Strong mainly in the capacity of a technical artist using my skill and knowledge in Unreal Engine 5, creating complex game elements such as a combining a moving liquid shader mathmatical algorithms and VFX to allow the bronze to be melted and poured. We worked in collaboration with the Sainsbury Centre to ensure historical accuracy to their artefacts and accessibility for exhibiting our work.

Check out The Benin Bronze Experience: Click Me!

Check out 33 Strong: Click Me!

Check out the Sainsbury Centre: Click Me!

This project was a very fun and challenge game to work on. What we have created is unique and the solutions bespoke, I believe some of the elements in this work world firsts, bringing many complex elements together. 33 Strong and the team at the Sainsbury Centre were amazing to work with, look out for future updates!


The Crucible

Shaders and Effects

The visuals of the crucible can be broken down into a few main elements: Pouring Bronze, Smoke Effects, the Glowing Crucible, and the Liquid Bronze.

The pouring bronze and smoke effects are both made through Unreal Engine's Niagara system, an advanced particle system created for UE 5. It enabled the ability to control flows of data into and out of the particle system, while remaining well optimised if used correctly.

For the pouring bronze specifically, it was the combination of a sprite renderer and a ribbon renderer, allowing globs of molten bronze to pour but keeping a connection of bronze between them to give them a realistic feeling. Custom input data, such as the rate of the pour being based on the angle, makes the bronze pour feel more realistic, as well as having a velocity derived from the pour direction. This, combined with accurate drag, gravity, and collision with the ground, allows for a fluid and heavy feeling, resulting in our desired outcome.

When it comes to the smoke effects they were a combination of two sprite renders, one using a heat warping effect and the other using smoke sprites with a flipbook texture, together these have collision and inverted gravity to stop them going to walls and to rise at a consistent rate, the spawn rate is determined by a user parameter changes in the code base of the amount of bronze in the crucible.

The glowing crucible has a custom material, determining a lit PBR shader's look. It has two states: one being emissive and orange, based on some video references of bronze pouring, and the other is stone. A dynamic material parameter allows a linear interpolation between the two states, so it can change gradually via code.

Liquid Bronze was the hardest of all of these to create, having a shader that moves the liquid based on rotation, and also being able to lerp the amount based on melting bronze was a tall order, but with enough graft, I worked perfectly in the end. The basic principle for how it works is instead of working out where the liquid is, you work out where the liquid isn’t, using the opacity of the material, essentially cutting out the bit you don't want.

To find out the bit you don't want, I did a calculation to subtract the world position from the local object position to get the difference, and then added the bounds of the object. By multiplying the bounds by a normalized value, you can reduce and increase the liquid amount easily. By controlling this normalized value, we have created a close to realistic approach where the liquid amount decreases as the pour amount increases, all based on physical interaction.



Programming and Math

The crucible programmatically has one element that stands out. The function to calculate the lowest edge when pouring is a simple concept, but in practice, it worked out to be more complex than initially thought.

To find the lowest edge of the crucible, first, we need to define where the edge of the crucible is, and to do that, we need to draw multiple points around the top of the crucible. We drew 8 points around the top; these points would update their Z coordinate in the world accordingly, and from then it is simply a question of checking all the points and figuring out which is the lowest in a loop.

Due to the nature of how the code works, this edge point value stored is able to be used by a sphere trace collision, detecting what the molten bronze collides with. Robust code often does the opposite of tech debt, making life easier in the future.

The other significant programmatic element of the crucible is the maths in order to make the pour feel regarding the angle required for molten bronze to pour out. If we were pouring in two dimensions, this job couldn't have been easier. We take whichever relevant rotational axis and have a condition based on requiring an exact degree, and call it a day. However, VR programming proved to be more complex yet again.

To solve this, I did research, planned, and used trial and error, and eventually came to a solution. First, convert my rotation into a quaternion, to then translate it into an Euler representation in a 3D vector. This is now our rotation, but represented in a more useful format. I then get the up vector of the original rotator and subtract each 3D vector from each other. This gets the difference between our current rotation and the up vector. To get a usable angle, we then take the X and Y values from this as its own vector and get the vector length. This will give you specifically the angle of tilt regardless of the direction held in-game.


The Tongs

The tongs in the Benin Bronze Experience could perhaps be the first working tongs created in VR and are done through a combination of procedural (inverse kinematic) animations and bespoke programming.

Control Rig

Procedural animation can be done in many different ways, but the requirements for this specific use case are unique. Because of the VR aspect of the game, the player's hands can rotate and move through space, and so we had to adjust for this.

Ultimately, traditional baked animations would not suffice; using aim constraints to animate each tong limb while keeping its fixed centre at a calculated point is the solution to the large amount of animation. But this will leave the limbs able to rotate independently, so it is important to lock the tongs' rotation on other irrelevant axes. To do this, you only allow rotation around the up vector of the tongs' root bone.

Because of a discrepancy between the animation and player interaction there is still one issue. The control that commands the aim of the animation can move around freely, not fixed onto the tongs, which can cause glitches. So an extra control is added, a fixed control that will lock onto each handle spot, the freely moving control still exists to animate the main bones for the animation, but these fixed controls can act as reference points of the animation to reset to or for other utility required.

VR Player Programming

In terms of the player programming for VR tongs, the first question is, how do you program a two-handed object? And how can the hands act independently but be connected by a hinge?

These were the questions we were asking ourselves when approaching this problem, but the solution I released was all too obvious. The solution was to treat both tong handles as independent objects in the grab code, so the player can hold both separately. And once both are held, we can calculate the position of the hinge of the tongs can be set according to both handle positions.

This approach worked in tandem with the procedural animations to create the start of our animated tongs. By this point, we had tongs you can grab and move through space with the animations working, but the tong limbs would rotate into each other if pushed too far, and invert if the other direction. To fix this, we needed some kind of clamp, but with our system working dynamically, we had no fixed metric to work from. What we needed was a way to calculate the exact angle the tongs were at.

To approximate an angle from the data available and to work in different scenarios was not easy, but the solution we ended up with was a complicated piece of maths using the distance between the tong handles. As the distance linearly increased with the angle of the tongs, we can use this to clamp our animation.

To make our tongs function with the crucible in the game, we used some overlap collision spheres at the end of the tongs, along with measuring how closed they are to attach the crucible to them.