unity 3d fog for draw distance
Rendering xiv
Fog
- Apply fog to objects.
- Base fog on either distance or depth.
- Create an image effect.
- Support deferred fog.
This is part xiv of a tutorial series most rendering. The previous installment introduced deferred shading. This time we'll add fog to our scene.
This tutorial was fabricated with Unity 5.5.0f3.
Forwards Fog
Upwards to this point, nosotros've ever treated lite rays as if they traveled through a vacuum. This might be authentic when your scene is set in space, but otherwise light has to travel through an atmosphere or liquid. Under those circumstances, light rays can get captivated, scattered, and reflected anywhere in space, not only when hitting a solid surface.
An authentic rendering of atmospheric interference would require an expensive volumetric approach, which is something nosotros usually cannot beget. Instead, we'll settle for an approximation which relies on merely a few constant fog parameters. It's known as fog, because the effect is typically used for foggy atmospheres. The visual distortions causes by clear atmospheres are ordinarily so subtle that they can exist ignored for shorter distances.
Standard Fog
Unity's Lighting window contains a department with the scene'due south fog settings. It'due south disabled by default. When activated, you become a default gray fog. However, this only works for objects that are rendered using the forrard rendering path. When the deferred mode is active, this is mentioned in the fog section.
We'll deal with deferred style later. For at present, let's focus on frontwards fog. To do and then, we need to use forward rendering mode. You can change the global rendering mode, or strength the master photographic camera to use the desired rendering mode. So set up the camera's Rendering Path to Forward. Permit'southward also disable HDR rendering for now.
Create a modest test scene, like a few spheres on elevation of a airplane or cube. Use Unity's default white cloth.
With ambient lighting set to its default intensity of i, you'll go a few very bright objects and no noticeable fog at all.
Linear Fog
To brand the fog more noticeable, set its color to solid black. That would represent an atmosphere that absorbs light without much handful, like thick black smoke.
Ready the Fog Mode to Linear. This isn't realistic, but easy to configure. Y'all can gear up the distance at which the fog's influence begins and where it finer becomes solid. Information technology increases linearly in betwixt. This is measured in view distance. Before the fog starts, visibility is normal. Beyond that altitude, the fog will gradually obscure objects. Beyond the stop, nothing but the fog's color is visible.
The linear fog gene is computed with the office `f = (E - c) / (E - S)`, where `c` is the fog coordinate and `S` and `East` and the start and finish. This factor is then clamped to the 0–1 range and used to interpolate between the fog and the object'southward shaded color.
Exponential Fog
The second fog mode that Unity supports is exponential, which is a more realistic approximation of fog. It uses the office `f = 1 / ii^(cd) = ii^(-cd)` where `d` is the fog's density gene. This equation will never reach zero, unlike the linear version. Increase the density to 0.i to make the fog announced closer to the camera.
Exponential Squared Fog
The last fashion is exponential squared fog. This works similar exponential fog, but uses the office `f = 1 / 2^((cd)^ii) = ii^(-(cd)^2)` which results in less fog at close range, but it increases quicker.
Calculation Fog
At present that we know what fog looks similar, allow's add support for it to our own forwards shader. To make comparing easier, set up half of the objects to apply our own material, while the remainder keeps using the default fabric.
The fog style is controlled with shader keywords, so we have to add a multi-compile directive to support them. At that place is a pre-divers multi_compile_fog
directive that we can employ for this purpose. It results in extra shader variants for the FOG_LINEAR
, FOG_EXP
, and FOG_EXP2
keywords. Add this directive to the two forward passes only.
#pragma multi_compile_fog
Next, let'due south add a part to My Lighting to employ the fog to our fragment color. It takes the current color and the interpolators as parameters, and should render the final colour with fog applied.
float4 ApplyFog (float4 color, Interpolators i) { render color; }
The fog result is based on the view distance, which is equal to the length of the vector betwixt the camera position and the fragment'due south world position. We have access to both positions, so we can compute this distance.
float4 ApplyFog (float4 color, Interpolators i) { float viewDistance = length(_WorldSpaceCameraPos - i.worldPos); return colour; }
Then we use this every bit the fog coordinate for the fog density part, which is computed past the UNITY_CALC_FOG_FACTOR_RAW
macro. This macro creates the unityFogFactor
variable, which we tin employ to interpolate betwixt the fog and fragment color. The fog color is stored in unity_FogColor
, which is defined in ShaderVariables.
float4 ApplyFog (float4 color, Interpolators i) { bladder viewDistance = length(_WorldSpaceCameraPos - i.worldPos); UNITY_CALC_FOG_FACTOR_RAW(viewDistance); return lerp(unity_FogColor, colour, unityFogFactor); }
As the fog factor tin end up outside the 0–1 range, nosotros have to clamp information technology before interpolating.
return lerp(unity_FogColor, colour, saturate(unityFogFactor));
As well, considering fog doesn't bear on the alpha component, we tin leave that out of the interpolation.
color.rgb = lerp(unity_FogColor.rgb, color.rgb, saturate(unityFogFactor)); render colour;
At present nosotros can apply the fog to the terminal forward-pass color in MyFragmentProgram
.
#if defined(DEFERRED_PASS) #if !divers(UNITY_HDR_ON) color.rgb = exp2(-color.rgb);
0 Response to "unity 3d fog for draw distance"
Post a Comment