Fog

Six-Way Lighting - Fog

My Inspiration

My main goal was to create good-looking fog with enough artistic control so it could be tweaked to fit different environments. I knew that full real-time volumetric fog can be expensive and slow because the lighting has to be calculated every frame.


While looking for alternatives, I came across six-way lighting and got really excited about it. The idea of packing light information into textures and using those textures to fake lighting on sprites/planes seemed like a more efficient way to get depth and volume without relying on a full volumetric fog system.


After researching the technique and how it works, I decided to build this portfolio project around six-way lighting and explore what kind of fog I could create with it.

EmberGen

I created the fog in EmberGen by simulating smoke and shaping it until I got the look I wanted. EmberGen updates the simulation in real time, which made it easy to try different settings and see the results instantly. This let me experiment with the shape and movement of the fog without waiting for long rendering times.


EmberGen also lets you export flipbooks using six-way lighting. When exporting, you get two flipbooks with three directional lighting information in baked into each channel of the flipbook. These textures becomes Top, Left, Right (TLR) and Bottom, Back, Front (BBF).

Shader Material

To create realistic lighting for the fog, the shader reads the directional light vector to determine where the light is coming from. The X, Y, and Z components of this vector indicate whether the light comes from the left or right, top or bottom, and front or back. Step functions check if each component is positive or negative, creating six directional masks.


These masks correspond to lighting directions stored in the TLR and BBF textures, where each color channel represents a specific direction. Instead of simply switching between textures, the masks are multiplied by the strength of the light vector components to create directional weights.


These weights are used to blend the texture channels together, allowing the fog lighting to transition smoothly as the sun/moon moves. This approximates volumetric light scattering, giving the fog depth and shape without the cost of full volumetric lighting.

Iteration

After my classmates Emilia and Oliver started using the fog in their scenes, I received valuable feedback about features and artist usability. Based on this, I continued improving the system and added parameters like edge softness, animation speed variation, and start frame offsets to give more control and help break up repetition.


I also adjusted the smoke simulation so the fog movement felt smoother and optimized the flipbook so the full texture space was used. I added depth fade and camera fade to help the fog blend more naturally into the environment.

Image source: Unity Technologies, Realistic smoke with 6-way lighting in VFX Graph, Unity Blog.

What is Six-Way Lighting?

Six-way lighting is a technique used to give flat 2D fog a sense of depth and volume without relying on expensive real-time volumetric lighting. Fog in games is often rendered using flat textures or sprites, but making them respond convincingly to light can be difficult.


Normal maps can simulate surface direction and allow lighting calculations, but they are not well suited for soft, dynamic effects like fog. Another approach is to use baked color maps, where lighting information is stored directly in the texture. However, this lighting is static and cannot respond to changes in the scene, such as moving light sources.


Six-way lighting solves this problem by storing lighting information from six different directions in two separate textures. The shader then uses these textures based on the direction of the light, allowing the fog to appear more three-dimensional and react dynamically to where the lighting is coming from while still maintaining good performance.

Flipbooks

After I was satisfied with the simulation, I exported two flipbook textures using six-way lighting. In the shader, these channels are compared with the direction of the light so the sprite can react to the lighting direction in the scene in real time.


This allows the fog to change its appearance depending on the direction of the light while still keeping the effect efficient. The video to the left shows how each frame in the flipbook is packed.

Fog in Unreal

I created both fog cards and a Niagara system to layer on top of Unreal’s volumetric fog. The goal was not to replace the built-in volumetric fog, but to gain more control over how the fog sits in the scene. My fog cards are mainly used to shape the background and add depth and movement across larger areas, while the Niagara system is used closer to the player when the fog needs to feel more present or show stronger movement.


The two materials I created are very similar, but they handle animation differently. In Niagara, the flipbook animation is controlled in the emitter, while for the fog cards the flipbook animation is handled directly in the shader.

Below is a video showcasing the two different environment before and after implementing my fog

The scenes used in this project were created by my classmates. The first scene was made by Emilia and the second scene was made by Oliver.

Technical Challanges

  • Making flat textures look volumetric without expensive calculations.
  • Balancing visual quality with performance for real-time rendering.
  • Ensuring the fog integrates well with lighting and the environment

  • Optimizing the shader by removing branching and simplifying calculations

Takeaways

This project taught me how to store and reconstruct lighting information in textures to create convincing real-time volumetric effects. Using six-way lighting showed how depth and volume can be faked on flat sprites while keeping performance high.

I also gained experience building an efficient VFX pipeline across tools. Simulating fog in EmberGen and setting up the shader and systems in Unreal demonstrated how different tools can work together to produce a polished, real-time effect.


Finally, I learned the importance of artist usability. Feedback from classmates led me to add parameters like edge softness, animation variation, and start frame offsets, making the system flexible, easy to control, and able to produce natural movement without repetitive patterns

If I Had More Time...

...I would explore adding flowmaps to the fog. This would give all the fog a more subtle, organic movement with some randomness, making it feel even more alive and dynamic. I would also implement a switch node in the material so the fog cards and Niagara system could share the same material with two instances, instead of using two separate materials, which would simplify maintenance and improve workflow.

I am part of The Game Assembly’s internship program. As per the agreement between the Games Industry and The Game Assembly, neither student nor company may be in contact with one another regarding internships before April 15th. Any internship offers can be made on April 27th, at the earliest.