Академический Документы
Профессиональный Документы
Культура Документы
4
VOLUMETRIC FOG FOR UNITY 5
WHAT’S
FOG VOLUME?
Fog Volume is a volumetric fog solution
for Unity 5.
If you would like to feature your project in the showroom, send me your request along with the requested info to contact@davidmiranda.me
FEATURED PROJECTS
How are you using Fog Volume? How are you using Fog Volume?
Your company logo Your company logo
● Light Halo
● Self Shadows
● In-scattering
● Point lights
● Volume shadows
● Projected soft shadows
● Cloud animation
● Light absorption
● Lambert Diffuse
● Distance fields
Control map:
Camera up E RT
Camera down Q LT
FOV Z, C RMB
FPS counter F
Menu and camera not working with wacom tablets. No bugs in editor though.
Press Escape to exit. Xbox Gamepad compatible.
SCENES
INFINITE CLOUD
In this case we have an example of generic cloudscape
that can be used as preset or starting point.
Developed for shader level 4.0 Lower level compatibility is in the works. We will expect some limitations on lower end GPUs
COMPATIBILITY
WITH UNITY FEATURES
Orthographic cameras
Reflection probes
MSAA
Prefabs
SpeedTree
COMPATIBILITY
TESTED UNITY VERSIONS
5.5
5.6.1p1
2017.1.0b10
2017.2.0b8
2018.2.0b4
COMPATIBILITY PlayWay Water
WITH OTHER ASSETS
COMPATIBILITY Helios
WITH OTHER ASSETS
POST-PROCESSING STACK
Link
EXPLORATION CAMERA
Xbox controller support: Download the input manager file from here and copy it to \ProjectSettings
COLOR SPACE
Linear recommended. Fog Volume will look similar in both cases, but light intensity will change.
Demo content has been adjusted for linear.
PROJECT REQUIREMENTS
4 layer slots available
UPDATING
Delete all the content in Assets/FogVolume before importing.
Fresh updates will be available from my site.
SCENE REQUIREMENTS
1 Directional light. It can be disabled, but FV needs its rotation, color and intensity.
GETTING STARTED
CREATING A FOG VOLUME
Gameobject > Create Other > Fog Volume Fog Volume > Fog Volume
Parameters are very easy to understand. Here we only use visibility, size, color and
in-scattering.
FOG TYPES
GRADIENTS
Things are now much more complex. We have Gradient activated here. This means
we are now executing raymarching. You will see a new tab called Renderer. Here is
where we adjust the raymarching parameters.
You may noticed that Visibility disappeared. We have now to use “Intensity” inside
the Renderer tab.
Scene Collision will be activated by default. Turn it off if there aren’t objects
intersecting the volume.
The softness value adjusts the intersection range. 1 by default.
Jitter is useful to hide the gap between each raymarch iteration. Don’t abuse, it
makes things more expensive ;)
Sampling method defines the view ray method. You can choose between ray
distance to box or view aligned planes.
Unless the camera doesn’t look around, Eye2Box will be the best choice.
The color parameter is now called Light Energy. With raymarch activated, this
name has more sense, since we have now a light equation. This value will multiply
the outgoing light.
We see now more lighting parameters. Ambient, which I set here to black and
absorption to zero. Those parameters have more sense when we have noise
activated.
FOG TYPES
NOISE
Noise has many options, and here is where performance will suffer more. Scale is the
global size of the noise. It multiplies Base Tiling and Detail layer tiling. Density makes
clouds more dense, affecting opacity and light absorption. Octaves represent the amount
of noise layers computed. When it is set to 1 it means: 1 base layer + 1 detail layer. By
default, 2 layers of noise are active. You can turn off the detail layer if Draw distance ==
1. Note that the more it repeats, the more expensive it will be.
Base layer has its own intensity value; Coverage, [0, 1] and own speed.
Detail layer will only be rendered when:
● Base layer opacity >0
● Base layer opacity < Cutoff
This saves a lot of unnecessary work.
Masking Threshold makes a soft transition to the detail layer where it starts.
Ambient and Absorption are active for this cloudy layer. Ambient is added to the light
equation and Absorption will play an important role. It is very cheap compared to other
lighting options. It will darken the dense parts of the noise and brighten the edges. It will
also affect In-scattering anisotropy and Halo opacity and diffusion.
In this case, lighting is a bit more complex. Directional Lighting is activated. One iteration
will be enough. Distance is used to displace the lighting result and Density will increase
light absorption and opacity.
Intensity and Contrast shapes the noise. To modify opacity without affecting the shape,
use Density.
We need Scene Collision activated to make it intersect correctly with the mountain and
trees. With Coordinates/Scroll we add a little of movement.
Jitter is activated in this case, since the gaps are more obvious when noise is activated.
Height Gradient sets a grayscale gradient from the bottom of the volume to the top given
min and max values to fade noise. This shapes the cloud opacity.
FOG TYPES
NOISE
In this scene we don’t activate Scene Collision in clouds because they do
not intersect the terrain, we must avoid unnecessary gpu work.
Height Gradient shapes the clouds making them less populated on top of
the volume.
Detail is added only at the edges of the base layer. Adjust the edge size
with Trim Threshold. Trim is used to subtract base layer with detail
layer. Making base layer dense with sharp edges will reduce the detail
sampling area, thus less expensive.
FOG TYPES
NOISE: RADIUS FADE
We can push this effect with Start distance and make the transition softer
with Transition Wideness
Use the Ambient Color alpha to control the amount of ambient applied to the
volumetric shadow.
Low visibility will make the render cheaper. Raymarch stops once an opaque
pixel is drawn.
FOG VOLUME DATA
CAMERA SELECTION
A new object named “Fog Volume Data” will be created when there is a Each Volume will show now the camera in use at the very bottom of the
FV in the scene. We will manage from here what camera will be used to inspector. By clicking this button we will select that camera:
render Fog Volume.
If Game Camera is empty, it will search in the scene for a valid camera. If
none is found, Fog Volume will be disabled until a new camera is added
to the scene.
When we have several cameras in the scene we can assign any of them
manually or via scripting.
FOG VOLUME DATA
VIVE
After adding a Fog Volume, jump to Fog Volume Data and assign the eye camera:
Download sample scene
DEPTH & COLLISION WITH SCENE CameraDepthTexture will be used when Downsampling is 0 or
Camera Script is disabled. When enabled and set to 1, Fog Volume will
generate its own Depth map, so Fog Volume won't need
_CameraDepthTexture for textured fog (noise or gradient)
Depth is required when a textured Fog Volume (non uniform) intersects the scene and we use Downscale . With it enabled, we need Scene Collision active in our
volume:
Camera script
VIEWER
Use the prefab RT_Viewer to see the
generated buffers
● Scene View
● Game view with FogVolumeRenderer.cs not in use
RENDERER
Ztest
In the case of background clouds, it will not be necessary to generate the depth buffer. Let's see how the scene “Fast Clouds” is set
Ztest
Ztest is hardcoded in Surrogates.
Their Ztest is managed by the camera
script.
RENDERER
Ztest
If set to Always this is what we
would get.
It is seen correctly in Game
viewport because the Ztest is
internally managed for the
surrogate.
Edge fix and DeNoise don’t play well together because of the nature of DeNoise, which is a temporal effect
RENDERER
SURROGATES
We talk now about “surrogates”, which are cubes that sample the result of the offscreen render of the volumes. They are like TV screens, they just show the low-res
version in the scene. This way we can sort transparencies correctly.
When we turn on downsampling, textured fog volumes won’t be visible for the assigned camera. Our game camera will render the surrogates instead.
Auto Generated surrogates are made of a copy of the original volume mesh.
Every Textured Fog Volume will generate its surrogate (by default) when Downscale >0
We can cancel the surrogate at the very bottom of the Fog Volume UI:
Auto-generated surrogates have some limitations. They are good for a quick preview though.
LIMITATION
We can’t set the draw order in automatically created surrogates
Shadows rotate with sun direction, but the angle between the assigned
light and the Volume can’t exceed 30º Beyond this angle, the shadows
position won’t be correct.
Attach light==true will lock the light rotation to the volume rotation. It is
useful to cast shadows from rotated volumes.
https://youtu.be/OdvzG7oNR80?t=3m32s
NOTE
Shadows only affect direct light components:
● In-scattering
● Directional lighting
Directional light: view range
By default, the shadow camera will use the assigned volume size (X axis) to determine the view range. The whole volume will be visible and we will get
volumetric shadows for the whole volume.
Directional light: focus position
By default It will focus on the center of the assigned volume. But we can change that switching to Scale mode: Manual and Focus point: Game camera
position or GameObject. This way we can render the shadowmap only for a specific location when we have a large volume.
Example:
We want to bake a static shadow for these towers:
Directional light: baked shadow
With Update mode set to Interleaved (dynamic) we tweak Zoom and our game camera position until we have a good view of the area of interest where
we want to bake the shadow. Once we are happy with the location and view range we can switch to Update Mode: On Start.
We can now fly anywhere and the shadows will stay in the correct position. The cost of sampling this shadow depends on its size and FV iterations.
Directional light: shadowmap edges transition
If not taken into account, the edges of the shadowmap will cause shadows to appear suddenly. We will adjust the borders fade using “Edge Softness”.
Notice the smooth black frame in the miniature:
Smoothing range
Halo is an optical phenomena easily visible in cloudy nights
around the moonlight. Light gets refracted as it travels
throughout the cloud.
Halo
You will find Halo in the lighting tab. It starts with a
texture like this:
LIGHTING
It contains a 1D Grayscale gradient, which is used to
generate the colorful dispersion.
Left side corresponds to the center point of the
lightsource. Right side is where the halo phenomena is
more evident. We paint there sharper gradients.
HALO
Width and Radius will define the main shape of the ring.
Absorption will simulate how much light is scattered in
the cloud, becoming more blurry according to opacity.
LIGHTING
For existing lights, add the script FogVolumeLight.cs and Fog Volume will automatically recognize
it. To create new lights, use the Fog Volume menu
METHODS
We can create lights that are not Unity lights, but simulated lights that only works in fog volume
and don’t cast shadows:
●
●
Fog Volume Point Light
Fog Volume Spot Light
LIGHTS
Turn Real-time search ON to refresh or hit play once. Lights found inside the volume will be
added. Turn Inside box only off to also add lights that are outside of the volume. LIMITATION
Once it is refreshed, turn off real-time search. Because of the big amount
of registers required,
Pointlights have been
disabled from 3.1.4 for
machines with shader level
below 4
Range Clamp helps to save gpu power, especially with Inverse square attenuation, which extends
over long distances.
Draw Distance is used to discard the lights according to its distance from the camera.
Lights discarding
Lights outside of the view frustum will be discarded from rendering. Light range is represented with a box and this is used to discard lights. When this box is not visible by the camera,
this light is discarded from the render. Usually, when we use the attenuation method: inverse square, which is extended along large distances, we have to increase the size of this box
so that the light is not discarded before it becomes not visible.
To view this box, enable other/ debug options / draw debug gizmos
Result:
Use Light visibility to increase the size of this box.
This value multiplies the light range
Self - shadowing
SELF - SHADOWING
Directional
LIGHTING
Directional lighting models the behaviour of light when it
travels inside the cloud. The amount of absorbed light is
defined by Density and the color inside the cloud is given
METHODS
by Extinction Color. Quality of this feature is adjusted
with Iterations. Adjust Distance to determinate the
distance between each iteration.
DIRECTIONA L
Lambertian
LIGHTING
Normals are computed to calculate diffuse lighting. This
method is extremely expensive, but we can compute it
only at a given Distance from the camera.
PROXY VOLUME
Proxy Volume
In some cases we will want to tint our (textured) Fog Color with the ambient, specially when using these GI probes
Proxy Volume: performance
Sampling the probe grid is a complex operation and performance suffers quite a lot:
Fog Volume allows to use box meshes to model / mask noise.
PRIMITIVES
We can create a primitive via menu button
Turn off Real-time search once the list is filled with your
primitives. -Noise nor Gradients are not
computed outside the distance
Turn it on only to update the list. field.
-Each primitive you add increases
cost
PRIMITIVES
Let’s see another case where primitives would
be useful. Imagine the following situation
Only 20 primitives are rendered at once. The system will render the 20 closest ones and discard
the rest according to the camera proximity when persistence type == Cullable. To avoid a
primitive to be discarded, set the “Persistence type” to Persistent.
PRIMITIVES
BOX
We have now 3 different spaces resolved with a
single Fog Volume
DEBUG VIEW
We find a drop-down list at the very bottom of the
Renderer tab containing all the debug view modes
currently available:
MODES
ITERATIONS
DEBUG VIEW
We can also isolate the effect of incident light scattering
MODES
IN - SCATTERING
DEBUG VIEW
This will show the depth we set in the Volume Fog
In-scattering panel, in the lighting tab.
MODES
Start Distance is set to 0 by default, in that case what we
get is a linear depth [0, 1].
IN - SCATTERING CLAMP
DEBUG VIEW
With this view mode we can isolate the final Volume Fog
In-scattering
MODES
RECOMMENDATION
Don’t ever use FogVolume layer as density
input, use FogVolumeSurrogate and it will be
free!!
IMPORTANT:
_CameraDepthTexture is required to make this work, but in some configurations it is not generated. With a deferred camera it
will always work, but lets see some cases with forward camera
● Using Postprocess-stack: it disables depth generation unless we turn on DOF, Motion blur, AO or TAA
● Not using PP stack?: you can use EnableDepthInForwardCamera.cs
No _CameraDepthTexture available
Screen FX: parameters
LIGHTING
● Directional volumetric shadows
● Spotlights
● Density-based shadow convolution
● Point & spot lights volumetric shadows
USABILITY
● Preset system
● More debug view modes
PRIMITIVES
● Subtractive spherical
distance field
● Independent softness
BEYOND BETA
values
RENDERER
● Low-res rendering for VR
● Temporal sampling
● Adaptative resolution? This is the roadmap for the upcoming
● Low-res scene integration
versions of Fog Volume.
INTERFACE Feel free to contribute with feedback, ideas,
Custom inspector for requests or bug reports. Contact me directly
FogVolumeRenderer.cs
or post in the forum.
DAVID
MIRANDA
davidmiranda.me
ACKNOWLEDGMENTS
FOR SUPPORT IN DIVERSE FORMATS
Indie game programmer Concept & Technical Artist Director at Infinite-Realities Rendering Engineer at DICE Software fellow at Unity Technologies
THANKS