Search Unity

Spotlight Team best practices: Making believable visuals in Unity

March 9, 2018 in Engine & platform | 13 min. read
Topics covered

Is this article helpful for you?

Thank you for your feedback!

Being part of the Spotlight Team, I am fortunate to be involved in some very interesting projects. The Spotlight Team at Unity works on games together with our customers and a significant part of my role is to help developers achieve the desired look and quality for their projects. I get to hear many stories from all across the industry and can identify common issues that content creators are facing. Several of the projects I have worked on aimed for fairly realistic visuals. Given the project’s art contents, how do we make a scene in Unity that will look believable?

There are a multitude of topics that need to be covered in order to make believable visuals. In this post I’m going to discuss lighting and render settings. Further down the post I’ll also share our Spotlight Tunnel Sample Scene and explain how you can use it to learn and experiment.

Preparing Unity render settings

Understanding how Unity’s rendering features can be used to realistically mimic the real world will help you to achieve your project’s visual goal.

Linear rendering mode
In simple terms, this sets Unity to do lighting and shading calculations using physically accurate math before transforming the final output into the format that works best for monitors.

To specify a gamma or linear workflow,
go to Edit > Project Settings > Player and open Player Settings.
Then go to Other Settings > Rendering and change the Color Space to Linear.

Defining your color space should be one of the earliest decisions in your project, because of the drastic impact on the final shading and lighting results.

Rendering mode.
In the Spotlight Tunnel Sample Scene, we use deferred rendering path. This allows content creators to work with multiple dynamic lights efficiently, combined multiple reflection cubemaps, and have the ability to use the existing Screen Space Reflection features in Unity 2017+.

To set this, go to Graphic Settings > Rendering Path or Camera > Rendering Path

You can find more information about render modes refer in this part of Unity documentation.

High Dynamic Range (HDR) Camera.
When rendering believable lighting, much like in real life, content creators will be dealing with lighting values and emissive surfaces that have a brightness higher than 1 (high dynamic range). These values then need to be remapped to the proper screen range (this is called tonemapping). This setting is crucial to allow the Unity camera to process these high values and not clip them.

To enable this, select the main camera on the scene and ensure that HDR is checked in the inspector tab for the selected camera.

HDR Lightmap encoding. (optional)
The Spotlight Tunnel sample scene didn’t use baked lighting, however, if you’re planning to work with High intensity (HDR) baked lighting, we recommend that you set the lightmap encoding to HDR lightmap to make sure the baked light result is consistent.
The option can be found under Edit > Project > Player settings > Other settings > Lightmap encoding (Unity 2017.3+ only).
Detailed information for Lightmap encoding can be found in the manual.

Tonemapper for your Scene (part of Post Processing Stack).
To display HDR lighting properly, a tonemapper needs to be enabled in the project.
Make sure to install Unity Post Processing Stack (version 1) from the Asset Store first.

Create a Post Process Profile Asset in your project and configure it as follows:

  • Enable Color Grading > Tonemapper > ACES
    (Academy Color Encoding Standards)
  • Enable Dithering. Dithering allows the Scene to alleviate banding artifact introduced by 8 Bit/channel output from HDR Scene. Modern engines use this technique to circumvent the limitation of 16M color output. Leave the rest of settings in tonemapper alone for now.
  • Select the “Main Camera” and add component Post Processing Behaviour.
  • Assign the Post Process profile previously created to the profile slot. If you want to use  Post Processing Stack Version 2, please refer to the readme of the package as it is currently in Beta.
  • Enable Image effect for viewport.
    This enables you to see the tonemapper all the time while working with the Scene view.
    Notice the highlight rendition and the dark tunnel value separation improvements in the tonemapped Scene. If you look at the non-tonemapped Scene, you can see how the highlights didn’t converge to a unified color. (the yellowish burning sun in this case).

This setup essentially tries to replicate how a digital camera captures a scene with a fixed exposure (without exposure adaptation / eye adaptation features enabled).

At this point, content creators have achieved a proper foundational scene rendering setup that should give believable results with a wide range of content.

Lighting and setup

Unity caters to lots of different lighting strategies/systems and project scenarios. We recommend that you check out our extensive documentation on lighting modes and setup to understand all the different options.

However, for fast iteration and simplicity, responsive visual feedback is necessary.
For this reason, the Spotlight Tunnel Sample Scene is using real-time lighting with Realtime Global Illumination (GI). This will give us a nice range of specular response, good bounce lighting, and let us change our lights on the fly.

Realtime lighting with Realtime GI + Light Probe

Going back to the lighting itself, a typical Scene, at daytime, with outdoor areas, can be broken down to 3 lighting components:

  1. Hemisphere (Sky contribution).
  2. Direct lights (Sun + Local lights).
  3. Indirect illumination (GI lighting).

At this stage, content creators are assumed to have meshes that are properly textured, and an assembled Scene.

Outdoor lighting and setup

Initial Hemisphere lighting
First component for outdoor lighting is Hemisphere lighting, called Environment Lighting in Unity. This is a fancy word for skylight. Night sky has minimal contribution, while daytime sky has very bright contribution. Hemisphere settings can be found under the Lighting tab (Window > Lighting > Settings > Environment).
For a start, procedural skybox material would be prefered instead of HDRI cubemap. Create a new material in the project, name it SkyMaterial and then set it to Skybox / Procedural.

Assign it to Environment Skybox Material inside Lighting tab > Scene.

At this point the Scene is somewhat lit. There is ambient, but not exactly proper hemisphere lighting. We’ll leave this alone for now.

Directional Light
Typical sunlight or moonlight is a light source close to infinity distance and has parallel light direction and shadow. They’re usually represented by a directional light.

Indirect Illumination / Global Illumination.
Directional light + ambient alone won’t create believable lighting. Proper hemisphere lighting requires occlusion of the skylight lighting. We also need to simulate sunlight bouncing off subjects in the scene. The sky currently renders a single color value to the Scene making it flat. This is where Realtime Global Illumination or Baked Lighting is required to calculate occlusion and indirect bounce lighting. In order to achieve that, follow these steps:

  • Make sure all meshes that need to contribute to the Realtime GI or baking are flagged with Enable Lightmap Static and Reflection Probe Static. These would typically be large static meshes.
  • Next, enable Realtime Global Illumination (Leave at default-medium settings) in the Lighting tab > Scene > Realtime Lighting.
  • Hit Generate Lighting or check Auto Generate.

Whoa, the Scene is now dark after light generation has finished. To make matters worse, some elements of the Scene are out of place - notice the Tram and the door on the background.
The static objects in the Scene currently have proper occlusion for hemisphere and indirect bounce response from the directional light, however, the rest of the objects lack a proper lighting setup.

Light Probes and Reflection Probes.
For dynamic objects or non-lightmap objects to receive Realtime/Baked Global Illumination, there needs to be light probes distributed in the Scene. Make sure to distribute light probe groups in the Scene efficiently near the areas where dynamically lit objects are located or will pass (such as player). Learn more about Light Probe Group in the manual.
Hit Generate Lighting again or wait for the precomputation to finish if Auto Generate is checked.

The Tram and the background door are grounded better, but reflections look out of place. Sky reflection is all over the place and shows up inside the tunnel. This is where reflection probes comes in. Efficiently place reflection probes with proper coverage in the Scene as needed. In the Scene above, one reflection probe for the main room is sufficient and two for each tunnel interior.
128 pixels Cubemap Resolution using box projection usually is a good baseline for typical cases and will keep memory and reflection bake times happy.
Here’s more information about Reflection Probe.

The Scene now looked properly grounded and cohesive, an important part of a believable Scene. But everything is even darker than before and nowhere near believable quality.

HDR Lighting Value
Many content creators don’t realize that, in reality, hemisphere lighting and sunlight are very bright light sources. They’re much brighter than the value 1. This is where HDR lighting comes into play.

For now, turn off the directional light and then set the SkyMaterial Exposure to 16.
This will give you a good idea what proper hemisphere lighting does to a Scene.

Things start to look believable. Think of this state as a cloudy day, where sunlight is completely diffused in the sky, so there’s no directional light.

At this point, you can reintroduce sunlight back into the Scene at a much higher value. Try Intensity 5 for a start. Despite the sun looking nearly white, it’s important that directional light color is chosen properly as the impact of indirect color from the strong sun can dramatically change the look of the Scene.

Now the sun (directional light) looks like a high energy light as expected from real life. The Scene looks quite believable at this point.

Screen Space Ambient Occlusion and Screen Space Reflection
While the Scene lighting looks pretty good at this point, there’s additional details that you can add to Scene to push it further. Baking detailed occlusion usually isn’t possible because of the limited resolution set in the Realtime GI for reasonable performance. This is where Screen Space Ambient Occlusion can help. Enable SSAO in the Post Process Profile under Ambient occlusion. Settings for this example are set to Intensity 0.5, Radius to 1, Medium Sample count w/ Downsampling and Ambient Only checked for a start.

While SSAO takes care of extra ambient lighting occlusion, reflection could use some accuracy improvements in addition to the simple reflection probes.
Screen Space Raytraced Reflections can helps improve this situation. Enable the Screen Space Reflection in the post process profile.

Notice that the left side of the wet track no longer renders bright reflections as SSR gives the Scene more accurate reflections for on screen objects. Both of these post process effects incur performance costs at runtime, so enable them wisely and set the quality settings to fit within your runtime performance constraints.

At this stage the content creators have achieved somewhat believable outdoor and indoor value separation on a fixed exposure. Reflection is visible in the dark indoor areas as strong highlights and not dim muddy values.

However, the Scene foreground elements and background elements aren’t showing up despite having strong perspective elements. A subtle fog in the Scene can create a massive difference in giving the Scene additional dimension.

Notice the foreground railing has better definition compared to the zero fog Scene.
Fog is enabled in Lighting tab > Scene > Other Settings. Fog color #6D6B4EFF, Exponential at 0.025 density is enabled here. In Unity 2017 deferred rendering, you might also need to enable fog in the post process profile if it’s not activated automatically.

Indoor and local lighting

Spotlight / Pointlight
The staples of real time local lighting are spotlights and pointlights. Area lighting can only be used when baking lighting, unless you’re using the HD Scriptable Render Pipeline (SRP), introduced in 2018.1 beta. There are new area lights that can be rendered in realtime in HD SRP mode.

Fundamentally, both of these types of lights emit light from one point in space and are limited by range with the spotlight having an additional limit by angle. More information about lighting is in the relevant section of Unity docs.

The big differences between the two lights has to do with the way they cast shadows and interact with cookies. Shadowing with a point light costs 6 shadow maps compared to a spotlight’s single shadow map. For this reason shadow casting point lights are much more expensive and should be used very sparingly.

NOTE: Baked lights don’t need to worry about this issue.
Another difference is that a cookie texture on a Spotlight is a simple straight forward 2d texture while a pointlight requires a cubemap, usually authored in 3D software.

Color and Intensity of light.
Choosing the proper color and intensity for your lights needs to follow some loose guidelines to give plausible results.

When selecting intensity for indoor lights, try to make sure no indoor lights have a greater intensity than the sun’s. This can create an unbalanced look depending on the Scene.

Given this Sample Scene setting, it’s very unlikely that there’s high intensity lights shining from the ceiling that exceed the brightness of the daylight time.

When selecting color, try not to leave out any one of the color channels completely. This creates a light that has problem converging to the white point.

While it’s technically a valid light color, the light color on the left image removes all blue color from the final output. Having a limited final color palette in the Scene for a baseline isn’t a great idea, especially if you want to do color grading later on.

Emissive Surfaces
In Unity, emissive surfaces can contribute to lighting if Realtime GI or baked GI is enabled, giving the effect of area lighting. This is especially useful if Realtime GI is enabled. Content creators can modify the intensity and color of the emissive surface and get the feedback immediately, assuming that precompute has been done ahead of time.

The image above showcases the subtle diffuse lighting from meshes on the ceiling.

Sample project file

Unity San Francisco Spotlight Team has created the Spotlight Tunnel Sample Scene to help content creators do hands on learning and experimentation.

Get the Spotlight Tunnel Sample project file here.

Simply extract the project to the folder and open the project using Unity.

Spotlight Tunnel Project was made with Unity 2017.1.0f3.

Opening this project in a newer version of Unity will require lighting rebuild as there might be lighting data format incompatibility between versions.

All assets provided in this project may only be used in a project developed with the Unity Engine.

As mentioned before, there are more of things that you need to know about when making believable visuals. You can learn more about this topic in this tutorial. We’re also going to add a full Best Practices Guide to the Unity Docs. Stay tuned!

Now it’s your turn to push the limit.

Hopefully this blog helps content creators to stay on track in achieving believable visuals in Unity. We can’t wait to be dazzled by all Unity content creators out there.

March 9, 2018 in Engine & platform | 13 min. read

Is this article helpful for you?

Thank you for your feedback!

Topics covered
Related Posts