We'd like to change it so that fog calculations are done directly in shader code. Good things out of that:

Fog starts working on WinPhone, Metal, consoles.

Makes it easier to add better fog modes (like height-based fog).

Practical implications for users / shader writers:

Fog command in shaderlab would stop working, except for cases like "Fog { Mode Off }" (which just disabled fog for this shader). In all other cases, most likely result is that fog as specified in render settings will be used. TLDR: no changing of fog modes / parameters per-shader, unless you're willing to implement your own fog calculations.

For vertex+fragment program shaders (i.e. not surface shaders), you'll have to add some macros / function calls to make fog work.

In order to avoid "well now you ship & load 4x more shader variants", we'll probably look at which fog modes are used in the scenes, and only include these shader variants into build.

Which would mean, don't change fog modes at runtime.

In case you do need that, we'll provide some UI somewhere to explicitly tell "hey I'll need these fog modes in the game".

Unity Technologies

Not much activity here, but quite some discussion (& approval) on the beta testing list. So here's the current plan; quite likely to become reality in Unity 5.0:

For surface shaders, nothing needs to be done; fog variants & code will be generated. You can add "nofog" to #pragma surface line, if you really don't want fog.

For vertex/fragment shaders, if you want fog you have to do this:

Add #pragma multi_compile_fog

Add UNITY_FOG_COORDS(n) to your vertex-to-fragment struct

Add UNITY_TRANSFER_FOG(o,o.vertex); to your vertex shader. "o" is output struct name, and "o.vertex" is position in clip space.

Add UNITY_APPLY_FOG(i.fogCoord, col); to end of your pixel shader. "i" is input struct name, and "col" is the color computed in your pixel shader. This applies standard fog color; if you want custom fog color (as some particle/additive shaders do, for example), you can do UNITY_APPLY_FOG_COLOR(i.fogCoord, col, fixed4(0,0,0,0)); to fog towards black for example.

For fixed function shaders, nothing needs to be done. "Fog { ... }" command in shaderlab still works, but now it only affects fixed function shaders (for non-fixed function, see point 2 above).

By default, fog modes used by scenes are included into game data build. If you know you'll want to change them at runtime, you can choose "Custom fog modes" (default is "automatic") under project's Graphics Settings, and tick checkboxes you need.

I have all the above working, and now fog "just works" on WP8/WinRT/consoles. Also, Unity codebase got smaller by 3500 lines of code. So there, yay.

Unity Technologies

You can do that right now (using ShaderLab's "Fog" command - each shader can have totally arbitrary fog). The plan is to remove support for that. However, since fog would be done "manually", you could just as well do "whatever you want" calculations there. There's nothing stopping you from not using our built-in fog macros.

i see, thx for the explanation, i've gotta say i never did anything serious with the current fog system, hence my confusion

I've noticed this current system uses a textcoord, light attenuation already uses 2, aren't we getting a bit short on these? I remember having created a complex shader that used all of the available ones, does using arrays of them help or solve the problem?

It sounds good, but the thing is there is not much to play with fog except what unity already provides, we just need an additional height based fog.
While we can write our own, it would be nice to have an option on the editor for global settings rather than adjusting fog for individual materials.
Soo, just add the height based macro there and thats done.
Or, just expose a fog function somewhere which we can overwrite with our own(if needed)?

Unity Technologies

You can't change built-in fog "into" a shader, since it needs to be done as part of other shaders while rendering.

Of course you can do fog as a post-processing effect, and do whatever fancy calculations you want there! In fact, that's exactly what GlobalFog effect does (which I'm also changing for 5.0 to do something more sensible - but anyone can do that at any time; it's just a script+shader with full source).

Woops...i mean "in the shader" not "into the shader", sorry
Problem with GlobalFog is it doesn't work well with some transparent object ,out of the box of course except it's already changed in 5 .
Alright i don't want to derail this thread into GlobalFog discussion .
Except if it is included in this thread topic.

Wooh seems like a great chance Aras, the less shader patching the better. What kind of unity specific shader patching is still being done? Any improvments to lower memory and prewarming times are very welcome (does 5.0 still store shaders in hex instead of binary format?)

I do not agree with Aubergine, Fog also needs to be used as complex fog volume if we want to have a seamless transition between over the water to under the water the way Crytek and Ubi does it. What Aras proposes is a good thing in order to make fog matching any type of mesh for example.

It sounds good, but the thing is there is not much to play with fog except what unity already provides, we just need an additional height based fog.
While we can write our own, it would be nice to have an option on the editor for global settings rather than adjusting fog for individual materials.
Soo, just add the height based macro there and thats done.
Or, just expose a fog function somewhere which we can overwrite with our own(if needed)?

Unity Technologies

I just made some tests. It seems OK but Legacy Shaders should use the old way. Otherwise porting 4.x projects to 5.x will be a nightmare if we have to add these macros in every shader we've already created.

"It sounds good, but the thing is there is not much to play with fog except what unity already provides, we just need an additional height based fog.": Aubergine.

I do not agree about the fact we "only need additional height based fog".. That's what I mean. Fog can be used in a lot of different ways, and if we want to have a fog matching a moving surface for example, we need to access to how the fog is calculated and possibly change it.
Also having access to the Grabpass code and being able to modify it would be great (but it is another subject)

Digital ApeModerator

Well, I already do fog in shader as it's a lot faster and looks practically the same as Unity fog (we just do it per vert and pass in few floats globally).

Since fog is the job of shaders, having it outside of shaders is just misleading at this point. We need less mystery and more tweakability just my two cents.

5 will change a lot of things. Physics, code, shaders. This is the best time to make changes. Some people will moan about changing their shaders, but really is that more than 5 mins work? I don't see it as a reason to worry.

I'd like it to be explicitly asked for in the shader via a macro or whatever to avoid shipping 4x the amount, of course since not all my shaders use fog. Obviously

"It sounds good, but the thing is there is not much to play with fog except what unity already provides, we just need an additional height based fog.": Aubergine.

I do not agree about the fact we "only need additional height based fog".. That's what I mean. Fog can be used in a lot of different ways, and if we want to have a fog matching a moving surface for example, we need to access to how the fog is calculated and possibly change it.
Also having access to the Grabpass code and being able to modify it would be great (but it is another subject)

Click to expand...

You can already do whatever you want, moving CUSTOM fog around surfaces is already possible as well as any type of fog.

i am pretty glad that i have found this thread and the little and new #pragma nofog!
using the new deferred rendering you have to add fog as global image effect as only objects using forward rendering will get fog applied to.
so objects that are not transparent but still uses a forward shader (due to a custom lighting function e.g.) while the camera is set to deferred will get the double amount of fog: 1 x by shader + 1 x image effect.

and to give a pretty realistic example: tree creator leaves would not render correctly without #pragma nofog!

I just ran into the issue where, as of Unity 5, I cannot change fog modes at runtime. You mention:

In case you do need that, we'll provide some UI somewhere to explicitly tell "hey I'll need these fog modes in the game".

But I can't find any reference to how this is actually done. Can someone point me in the right direction? Took me a long time to track down the source of this bug, and I'd really like to get it fixed. It's difficult because changing fog modes at runtime does work in the editor, just not the build. Very confusing.

Does anyone know of a way to use a custom property value for the density of an exponential fog, while still using the macros?
I don't really know the shader syntax yet, so I suppose I could learn that and write it explicitly. But i still don't know which calculations the macros do.

Sorry for resurrecting this old thread but ive hit a wall regarding the fog.
Ive a standard shader with an additional pass to add some detail as soft additive blending. Fog is applied to the 2nd pass and no fog in the first surface shader, but then fog color is also additively blending and it looks weird.
I can solve the issue with a 3rd pass to only add fog, though is there a way to finish it with 2 passes only?

One thing that I don't understand is why the default unity particle additive shader use "UNITY_APPLY_FOG_COLOR(i.fogCoord, col, fixed4(0,0,0,0)); to fog towards black".
In what circumstance would we need a black fog effects on the particle?

Yeah,it makes sense.But sometimes particles are needed to be rendered to a gui RT image,so the RGB value extracted from the original render could be wrong(towards pure black or blackish),if using this black fade calculation,despite the alpha value would be right,I can change the RT cameras setting to deal with that although.

"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.