Introduction
Hey! I'm Antony Naumovic, a Technical Artist from the UK.
I love pushing myself to learn different areas of art and rendering, and I hope that you might learn something new or find my projects interesting.
The Challenge
I was searching for a new project to add to my portfolio, and I wanted it to be slightly out of my comfort zone. I’d always wanted to have a go at a more stylised piece to learn more about the differences between that and a more realism-focused pipeline that I’ve become accustomed to.
While searching, my mate Chris Pereira sent me this concept by Clement Tesolin and challenged me to recreate it in 3D with a few constraints:
- No textures for the eye shader
- Create depth without Parallax Occlusion Mapping
- The eye shader has to be controllable with an external look position
At first, I thought it was going to be relatively simple, then I actually started planning the shader and realised I had a lot of work ahead of me.
Understanding the Concept
Before even opening Blender, I spent a bit of time researching what Mecha’thun actually is. Turns out they’re a Hearthstone skin of the Old God C’Thun from World of Warcraft, and they are the god of madness and chaos.
I gathered references from different iterations of C’Thun and environmental images that I thought felt unsettling or ancient. I always try to encapsulate the feelings that a concept creates, and out of it, build an idea of how I want my version to feel.
I try to think about who or what the character is whilst I work.
How old are they?
What’s going on in their mind?
Are they even conscious?
I find this approach genuinely helps me to establish them as a character and not just as a piece of work. It changes how I approach shapes, damages, animation, lighting, and everything really.
Building Mecha’thun
I always start with a rough blockout first. No detail, just a few polygons to establish proportions and general silhouette.
I tapered a cylinder into the approximate shape of the body and used this to align the camera so I could model from the reference. From there, I slowly refined shapes whilst making sure the silhouette was how I imagined.
One thing I’ve learned from adapting 2D concepts into 3D is that they cheat all the time. This sounds harsh, but honestly, we’d all do the same. It ends up looking good, but doesn’t make proper sense once you add in a third dimension.
I spent a lot of time orbiting the model and checking it in Unreal while working. I find having a matching camera in Unreal helps massively, as I can get a better idea of what the final product will be.
The tentacles were one of the first big hurdles.
Initially, I thought I’d need to make each shell segment individually and spend a long time editing the meshes. So instead, I built a Geometry Nodes setup that used curves to create the shells. This allowed me to create organic shapes that are easily editable.
Making the tentacles along splines saved me a lot of headache. It meant I could reshape the tentacles quickly and experiment freely without having to rebuild everything whenever I needed to change a curve slightly.
After the larger forms were done, I sculpted in secondary damage and hammered metal details.
I wanted the surface to feel worn and ancient, like it had existed for centuries and been through countless struggles.
Texturing
After importing the meshes into Marmoset, I baked all the maps there.
I know it adds another step to the workflow, but Marmoset can be a lifesaver when needing to skew paint or adjust cages.
Then, I moved everything into Substance Painter.
I started with the base materials for the body first, adding a stylised iron and galvanised finish. One thing I noticed in the concept was how much the colours shifted depending on the lighting. Shadows pushed into the blue range, whilst highlights leaned towards green. There also isn’t really a clean white light source, so all the colours sort of blend into one another.
I ended up desaturating the concept in Photoshop to see the values directly. This is really helpful as hues can have majorly different perceived values, even if their numerical lightness is the same.
I added several different value layers, matching the different luminosities that I found in the concept. I used this to recreate the hand-painted feeling of the metal across the body and tentacles.
Finding the right colours to map the values to on the tentacles was a bit of a struggle. The concept has such a large range of hues to choose from, but eventually, I found some that I was happy with.
For the roughness and metallic, I wanted the surface to feel painterly, so I set each of the value layers to a different roughness. On top of this, I also added stylisation filters to add some brush strokes and help unify the layers beneath.
The Eye Shader
The eye shader was easily the hardest part of the entire project. What I thought would take a few weeks slowly grew into a six-month project.
The first version of the shader was honestly questionable. It technically worked, but it was bloated and completely non-modular. I approached each feature separately instead of building one homogenous system. While helping to see if they were feasible, they ended up becoming unmanageable when adding new features.
Small changes would break other parts of the shader, and debugging became painful. At one point, I had to take a break and work on other parts of the project to clear my mind. Eventually, I stopped trying to patch it and rebuilt a lot of it from scratch.
The entire shader is built using SDFs (Signed Distance Fields) and custom mathematical noises rather than textures – SDFs are pretty much just shapes made out of maths, rather than through a texture. I created a library of these SDF shapes for the iris, pupil, and different internal details.
Meanwhile, for the depth, I used virtual plane coordinates with offsets for each layer. Then I used SDF masks to cut away the insides to reveal the layers underneath. Imagine several planes cutting through the eye at different depths and projecting details onto them.
The eye tracking ended up being pretty satisfying to solve. I used vector maths to rotate the virtual planes toward a world position supplied by a material parameter. Then, I used the distance between the eye and the target to drive the pupil’s dilation and constriction.
One thing I’m weirdly proud of is that the whole shader makes its own UVs. It works on pretty much any mesh, although it does end up looking a little bit cursed on objects that aren’t very spherical.
I also had to implement maths functions that were new to me, like adding in Rodrigues’ rotation formula to allow the iris to rotate without messing up the other rotations.
The scanlines were another part that I thought would be simple, but absolutely weren’t.
I got them working initially, but they were based on UVs, so they ended up not rotating with the iris and looked off. I had to create custom UVs for them, using the object’s bounds and the eye’s rotation, kind of similar to how planar projection works.
I also experimented with the new MVWO (Motion Vector World Offset Per Pixel) node, which allows you to add custom motion vectors in-material. I used this to make it look like the scanlines were physically moving and not flat.
The rage effect was probably one of the most fun parts though.
I used World Position Offset with layered sine noises to create the glitching effect and surface instability. Then I tied everything to a Material Parameter Collection, so every instance could react globally to the same value.
Once the system was finally stable, animating everything actually became surprisingly easy. Most of the movement comes from the look positions and the rage parameter building up.
Rigging & Animation
I wanted Mecha’thun to feel alive inside Unreal, rather than just posing it statically.
I created bone chains along all of the splines in Blender and used Dual Spline IK with chain dynamics in Control Rig to get the movement working. I then set up controls so I could easily animate everything.
The actual animation process became much more personality-driven than I expected. I started imagining each tentacle having its own behaviour and acting differently. Some moved more aggressively, some were curious, some defensive. Truth be told, I’m not an animator, but I think without that idea, it would have felt too stiff.
The eyes were all controlled through blueprints that randomised where they looked and how quickly they moved between the targets.
Then, during the cinematic, they slowly locked onto the camera one by one. I really liked the idea that Mecha’thun wasn’t immediately threatened by your presence, but slowly became more and more aware of you.
Environment & Lighting
The environment needed to support the eye, not compete with it.
I blocked out the background using the same concept camera and started shaping the architecture as it was in the reference.
For the runes, I did my best to recreate the shapes in Illustrator and converted the SVGs into geometry in Blender.
Most of the environment’s materials were made in Substance Designer. I created stone, brick, and a bronze trim material, then used baked vertex colour AO to add extra depth to the meshes as they relied on these tileables.
The fog ended up being one of the most important parts of the scene too.
Without it, the environment lost a huge amount of atmosphere and sense of scale. I used volumetric fog alongside ray-traced lighting, which required enabling:
r.VolumetricFog.InjectRaytracedLights=1
Otherwise, the volumetric fog doesn’t react to shadows correctly.
I also created custom volumetric shapes using a Geometry Nodes setup that slices meshes into a volume texture. That let me push denser fog toward the mouth and create a more directional atmosphere throughout the scene.
Lighting took a huge amount of iteration, as it always does.
The concept has this really intense glowing haze where the lighting and fog blend, and matching this in 3D took a lot of tuning.
I used strong backlights and rim lights to separate Mecha’thun from the environment, whilst maintaining the silhouette. I also recreated some of the specular highlights from the concept manually in Photoshop and used them as rect lights.
Also, there was a tiny bit of cheating with the arch rim light – no matter what I was doing, it ended up feeling unbalanced, so I ended up using vertex colour to paint in the highlight.
Even though it may sound a bit silly, faking lights is very common in stylised work.
Effects & Cinematic
Niagara handled all of the lightning and energy effects throughout the scene.
I built several variants of the lightning system for different purposes. Some travelled along the tentacles, some sparked into the air, some crawled across the floor, and some across the eye. I used Niagara light renderers in them as well to add dynamic lighting from the lightning.
For the outer radial focus effect, I used the MVWO node again, but this time on the environment. This made Unreal’s motion blur system think every vertex was getting pulled towards the eye, giving the stretched radial effect that didn’t need to be masked and no post-process material needed.
Camera Matching
The camera distortion turned into another strangely difficult problem.
At first, I created a post-process material for the barrel distortion. It worked, but had a major downside: the pixels in the centre were being massively stretched out.
I ended up solving it in a strange way.
I rendered out a distortion grid using the post-process material on the camera, then took the image into Blender’s Movie Clip Editor. From there, I approximated the lens distortion values, messing with the K1, K2, and K3 until the grid didn’t look distorted anymore. I then used those values to create a Lens File back in Unreal.
This, combined with setting the lens to use Scene View Extension, allowed Unreal to render the final image without faking the distortion.
It took quite a bit longer than expected, but the image quality difference was definitely worth it.
The Hearthstone Card
Near the end of the project, I had this thought in the back of my mind: “What would this look like as a real Hearthstone card?”
So, I ended up making one.
This part started as a bit of fun and somehow turned into one of my favourite parts of the project.
I found images of the layers of the original Hearthstone card, then converted them into height maps. I cut out each of the layers into meshes and displaced them using these maps.
Inside Unreal, I used Render Targets and mirrored camera movement to make it feel like the card version of Mecha’thun was holographic. It was pretty much the same system as a portal.
At first, the effect felt pretty flat and more like a window, so I added fake specular highlights that reacted as the card rotated. This small adjustment helped sell the illusion quite a bit more than I expected.
My mate Kris joked that since the card was animated, it should really have been a golden card instead. Though by the time he said that, it was already done, and there was no chance I was remaking everything.
Audio
For the final voice, I spliced different C’Thun voice lines together in Adobe Audition.
I created a blueprint that converted the audio intensity to a 0-1 value that drove parts of the visual effects system.
This was a great idea from another mate, Mikael, and it really helped tie Mecha’thun into the environment. I also liked the idea that Mecha’thun’s voice almost forces your attention towards it.
After rendering everything out, I added smaller ambient audio like mechanical movement, electrical crackling, glitches, and environmental sounds to help the cinematic feel more grounded.
Conclusion
This ended up being one of the most difficult projects I’ve worked on, but definitely one of the most rewarding as well. I’ve learned so much over the six months, especially about building more flexible systems.
There were a lot of moments I thought that parts were just going to not work out. But honestly, that’s one of the joys of tech art. You spend ages trying to find the solution to one problem, then suddenly one small change fixes it, and there’s joy in the world again.
I’m really happy with how Mecha’thun turned out in the end, and I’m glad I pushed myself into making something that wasn’t in my comfort zone.
A huge thanks to all of my friends who gave me feedback throughout the project, and especially to Chris for giving me this challenge in the first place.
Hopefully some of this was useful, or at least interesting to read through.