logo80lv
Articlesclick_arrow
Talentsclick_arrow
Events
Workshops
Aboutclick_arrow
profile_login
Log in
0
Save
Copy Link
Share

Breakdown: How to Create a Cinematic Visualization of a Stained Glass

Aleksandr Kamenshchikov shared the workflow behind the Unreal Stained Glass - Cinematic project, talking about what inspired it, what he wanted to achieve with the animation, and explaining how he modeled and textured the material.

Introduction

Hi, my name is Aleksandr Kamenshchikov. I'm a 3D Artist with experience across game art, real-time VFX, and gameplay prototyping. My first steps in 3D graphics began on walls, painting 3D-style graffiti in the early 2000s. So when I finally had access to 3D software, I became fully immersed in it.

Looking back now, I believe that was the foundation. Nevertheless, my professional journey started in graphic design in 2008. From time to time, I worked on tasks involving 3D, and gradually that interest became stronger. In 2011, I moved into the mobile games industry, where I worked across different genres, including city builders and social casino games.

Many of those projects initially relied on sprite-based visuals but later evolved into full 3D environments as production scaled. During that period,  I became deeply involved in Unity and worked with it extensively over the years. At different stages, my responsibilities included designing game scenes, creating and implementing various types of game assets directly in the engine, setting up UI, solving UX-related challenges, and developing gameplay prototypes.

I had been keeping an eye on Unreal Engine for a while, but I started using it actively after the release of version 5. Today, I focus on my personal projects, and I'd like to show you the process of creating the stained glass material for my cinematic Unreal Stained Glass inspired by Unreal Engine.

Conception

The main idea was to create a metaphorical visualization of the processes happening under the hood of the engine. The first spark came when I saw a UE5 logo stylised around the Nanite feature. It was a version of the logo where the filled area around the "U" was represented as coloured triangles, exactly how meshes look in the viewport Nanite visualisation mode.

This reminded me of stained glass, and the image felt strong enough to keep for later. So I simply wrote the idea down. I returned to it about a year later, when I finally had some free time.

While another project was loading, I caught a vivid image in my mind: strange shapes floating in space, assembling into a solid structure that forms the logo, followed by flames erupting around it as a symbol of a powerful force and the motivating energy behind new creations.

I hope I'm not the only one who has moments like this. Anyway, after a few quick pen strokes, the concept became clearer, and it was a good time to start gathering references.

The Foundation: Unreal Rose Window

The key feature I wanted to create for the stained glass material was a flame animation. The first step, therefore, was designing the Unreal Rose Window as the foundation for the animation. The idea was that the Unreal Rose Window would be formed by separate elements. Each of them would symbolise major Unreal Engine systems and tools.

Once combined into a unified whole, they would begin to create something almost magical. Since Unreal Engine is based on the C++ programming language, I decided to give each element a symbolic name, stylised as an ancient programming command engraved along the window's contours.

This imagined code sequentially activates the engine systems:

&& fRadiance::Ignite();

&& fAudioAmbience::Oscillate();

&& fInfinityGeometry::Virtualize();

&& fMaterials::Refine();

&& fEclipseManifest::CastShadows();

&& fChaosWeaver::Fracture();

&& fFlows::Simulate();

&& fProceduralForge::CreateWorld();

&& fRealmPartition::Optimize();

&& fEntityOrigin::Generate();

&& fMultiUserSpace::Unite();

Let's take a quick look at the simple steps in creating the 3D model of the Unreal Rose Window. First, I created the base geometry of the window in 3ds Max and separated its elements using Live Boolean in ZBrush. Then I applied Dynamesh, Smooth, and Decimate to the model. After, I made Retopology and UVs in 3ds Max.

For the material, I created the Base Color, Roughness, and Scattering maps in Substance 3D Designer. After that, I switched to Substance 3D Painter, where I baked the Mesh maps and set up the remaining textures. I also used procedural materials from the Substance 3D library: Stone Slate and Rock Face. They were blended with multiple noise layers at varying intensities to establish the base for the Normal map.

The engraving masks were created in Adobe Illustrator and then applied to the 3D model using various projection techniques in Substance 3D Painter.

To create the cracks, I designed the procedural brush in Substance 3D Designer and painted it onto each object using the Paint Along Path tool.

Unreal Rose Window asset overview:

Unreal Stained Glass Material Creation Process

Procreate Dreams: Flame animation

Since the 3D model foundation was already prepared, I could focus entirely on creating the Unreal Stained Glass material. As mentioned earlier, the flame animation was the key feature. For this animation, I didn't aim for ultra-smooth motion. Instead, I wanted a clearly visible flipbook animation. Therefore, the first step was to decide on the FPS and the number of frames in the loop.

In traditional 2D animation, working in the 8-12 FPS range is quite common. I chose to build a 9-frame loop and matched the playback to 9 FPS. This compact frame count allows for quick drawing while still giving the animation a good sense of variation.

As an additional benefit, 9 frames fit perfectly into a 3×3 atlas, which can be useful for optimisation. However, this wasn't the primary goal, as the project required large textures. After setting up the scene in Procreate Dreams, I drew the animation frame by frame, organising the stages into separate layers.

Substance 3D Designer: Base Setup

In Substance 3D Designer, the first thing I created was a parameter called Animation Timeline using the Multiswitch Grayscale node. This parameter allowed me to quickly preview different frames and helped set up exporting the full texture sequences in a single click. Next, I imported the flame frames, the rose window silhouette, and the logo, and then I prepared a minimal set of base masks to move forward smoothly.

Substance 3D Designer: Height Map

To build the main outline of the leading (the metal bars), I converted the flame mask and the rose window mask into splines using the Mask to Paths and Path to Spline nodes. Then I defined the line thickness and the cross-section profile with Spline Sample Thickness and Scatter on Spline Grayscale, and finally merged the result using the Blend node.

Next, I decided to create my own graphic for the thinner leading pattern inside the main outline, for both the flame and background areas. For the flame, I created a small stylised piece of flame using a chain of Spline (Poly Quadratic) nodes. I set the thickness and cross-section profile in the same way as for the main outline, then introduced subtle distortions with the Warp node. The tile was generated using Splatter Color.

The chain of Spline nodes was also used for the background pattern. This process turned out to be quite relaxing. After combining the main outline with the flame and background patterns, the final leading structure was completed and then used as part of the Height map and mask creation.

To make the glass surface easier to control, I prepared a solid glass mask from the leading structure using Histogram Scan and Invert Grayscale. Then I generated a Flood Fill mask, which provided local control over individual glass pieces.

For the glass base surface, I wanted the flame and background to have their own surface details in addition to plain noise. To achieve this, I built a simple pattern using Spline nodes and Tile Generator Grayscale. Then I controlled the placement and rotation of the texture per glass piece with Flood Fill Mapper Grayscale.

I also applied additional surface distortions to the glass. To create a slight overall bulge in a glass piece, I used Flood Fill Mapper Grayscale combined with the Shape node set to Hemisphere. For a subtle bend at the glass edges, I used the Bevel node. To slightly tilt the small pieces relative to each other, I used Flood Fill to Gradient. Finally, for a subtle layer of imperfections, I combined the Grunge Leaky Paint node with Flood Fill Mapper Grayscale.

After combining the surface layers of the leading and the glass, the height map was completed. The Normal map and ambient occlusion were easily generated from the Height map using the corresponding nodes. With the mask collection already in place, creating textures for Base Color, Roughness, and other channels became a smooth and efficient process.

Substance 3D Designer: Material reveal (Initial Mask)

Another important feature of the material was the stained glass reveal animation. To control it with a single parameter, I created an additional mask called the Initial Mask. To set the reveal direction of the leading, I generated gradients using the Bevel node for each type of lead, including the main outline, as well as the flame and background areas.

For the glass reveal gradients, I blended Voronoi and Triangle Grid Grayscale with a slightly tilted variation layer that had been created earlier for the glass pieces in the Height map.

The stained glass reveal animation was divided into five phases, starting from the top layer:

  1. Leading reveal: Main Outline
  2. Leading reveal: Flame Area
  3. Glass reveal: Flame Area
  4. Leading reveal: Background Area
  5. Glass reveal: Background Area

After several tests, I determined a gradient range that ensured a smooth transition throughout the stained glass reveal. The gradients of each phase were then remapped using the Gradient Map node to maintain clean value separation and layered with additional stencil masks.

Then, I was testing the Initial Mask with the Histogram Scan node:

The texture export was set up as a batch per frame across the entire sequence, driven by the Animation Timeline parameter created at the very beginning.

The stained glass material graph in Substance 3D Designer:

The final material in Substance 3D Painter:

Unreal Engine: Import textures

For the Unreal Engine material, in addition to the texture sequences, I prepared two custom textures: Section Mask and Flame Mask. As well as one texture from the engine library: Noise Mask. The Section Mask was used for the stained glass reveal animation, while the Flame Mask and Noise Mask were used to create the flickering effect behind the glass.

Next, I created Texture 2DArray assets from the sequences for each texture and added them to the Material Editor using TextureSampleParameter2DArray nodes. Then, I organised the inputs using Named Reroute Declaration nodes to maintain a clear workflow.

Unreal Engine: Flipbook Parameter

To control the sequence, the TextureSampleParameter2DArray node has to receive an index through the UVs input. This does not work with the standard TextureCoordinate alone, as the index must be provided as the third component of the UVs.

To achieve this, I built a simple Material Function that appends the index to TextureCoordinate using AppendVector. I also added a sequence cycling feature. The Fmod node allows the sequence to loop when the slider is moved continuously in one direction (every 9 frames in this case). The Floor node is used to round the value down so the frame index remains an integer.

To make the setup more robust, reverse looping was implemented by introducing one extra Fmod node, ensuring that the sequence continues correctly even when the slider goes into negative values. Next, I created a float parameter called Flipbook Frame to control the frame index within the Material Function.

At the same stage, I connected a Material Parameter Collection asset as a global controller of material parameters using an Lerp node. MPC made it much easier to animate the material in Sequencer during cinematic creation. Testing the flipbook parameter in the material instance:

Unreal Engine: Reveal Parameters

The stained glass has six areas, which need to appear with a slight time offset. To achieve this, I created six independently controlled parameters and built a Material Function capable of isolating a target ID from a grayscale texture.

The SelectID Material Function was applied to the Section Mask. Each area was then multiplied by its own float parameter, and the result was blended with the Initial Mask from the texture.

The Initial Mask parameters were also exposed through the Material Parameter Collection.

Testing the Initial Mask parameters in the material instance:

Unreal Engine: Light Flickering Parameters

The next step was to simulate a subtle, shaky candlelight glow, as if it were coming from inside a building. To achieve this, I created two modular Material Functions with a wide set of settings: UVShaker and FlickeringPulse.

Next, I combined UVShaker and FlickeringPulse modular functions into the main FlameFlickering Material Function to control both the flicker intensity and the UV jitter. Inside the main function, there are two primary layers: Flame and Pattern. In the Flame layer, a single texture is duplicated to apply two different UV jitter settings, and the results are then multiplied together.

In the Pattern layer, a single texture is also used with its own UV jitter configuration. After that, the Flame and Pattern layers are multiplied together with the pulsing tone from FlickeringPulse. Each layer supports both Texture2D and Texture2DArray. A set of input parameters was also prepared to ensure full control at the material level.

Using the FlameFlickering Material Function, I implemented shadow jitter and light flicker effects in the emissive channel, along with a simple fake caustics effect in the subsurface channel.

I also exposed light flickering parameters through the Material Parameter Collection.

Test of light flickering parameters in the material instance:

Finalising the material, I applied minor artistic refinements to a few material channels. Base Color and Specular were subtly enhanced using the AO texture, and the Normal map was strengthened with the FlattenNormal node. Unreal Stained Glass material graph in UE:

Conclusion

Working on the Unreal Stained Glass material was a truly fun experience for me. It was exciting to see how an animation of a simple flat image could evolve into a complex material with many details. At the same time, I wanted to preserve the feeling that it still looked like real stained glass, even though it behaved in an unreal way.

Another important goal was to present the flame positively, as an empowering energy that drives the desire to create forward, rather than as a force of destruction. I enjoyed exploring the tools and gaining precise control over the flame animation and the way it appears. I also enjoyed achieving a glow that feels as if it's coming from the depths of the engine.

Since the material is based on a black and white mask, it supports only two colour areas of the stained glass. However, each area can be customised with its own leading pattern. This was enough for the cinematic, but in the future, it would be interesting to extend it to support full colour animation.

Artistically, one of the toughest challenges across the whole project was designing the Unreal Rose Window structure and making it feel harmonious with the original symbol. This was a personal project, and I worked at my own pace, sometimes with long breaks. Creating the stained glass material from scratch took around fourteen days.

This included drawing the sequence in Procreate Dreams, setting up the textures in Substance 3D Designer, and creating the functional material in Unreal Engine 5. The full cinematic project took around six months to complete, covering design, modelling and material creation, lighting setup, animation of everything, including Niagara, as well as the soundtrack.

If you ask me for advice, I would say: capture your ideas, take short breaks during your work, and keep your pipeline organised. Ideas can eventually grow into a more complete concept for future artwork. Breaks give you a fresh perspective and help you evaluate the result more objectively. An organised pipeline makes workflow much easier, especially in complex projects.

I truly appreciate the opportunity to share this journey, and I hope my project inspires you to explore and experiment with your own ideas. Feel free to connect with me on ArtStation, Instagram, and LinkedIn.

Aleksandr Kamenshchikov, Game and VFX Artist

Interview conducted by Gloria Levine

Ready to grow your game’s revenue?
Talk to us

Comments

0

arrow
Type your comment here
Leave Comment
Ready to grow your game’s revenue?
Talk to us

We need your consent

We use cookies on this website to make your browsing experience better. By using the site you agree to our use of cookies.Learn more