godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.11k stars 69 forks source link

Control fog (both simple and volumetric) from shaders #2643

Open Dimev opened 3 years ago

Dimev commented 3 years ago

Describe the project you are working on

A flight sim

Describe the problem or limitation you are having in your project

It's hard to properly get my custom atmosphere shader to interact with objects the way I want to

Describe the feature / enhancement and how it helps to overcome the problem or limitation

As of now Godot 4.0 supports both volumetric fog and a simpler constant density fog model. Both of these can't really be controlled from shaders, besides the simpler fog which can take on the color of the sky to sort of simulate the atmosphere

My proposal is: Allow either the simple fog or the volumetric fog to be controlled from shaders, to help with these kinds of effects

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

The Fog and Volumetric Fog sections in WorldEnviroment will be changed to accept a Fog or VolumetricFog Resource instead of most of their current parameters. These resources work similar to Materials, with one subclass being the standard controls that are currently implemented, and one subclass that allows a shader, like ShaderMaterials

For regular Fog, the shader would take in the scene color, background color, scene depth, sun direction, camera position and camera ray direction, and as output it would output the new scene color, or something similar.

For volumetric fog, the shader would allow changing the volume density and color of the fog at different locations, but I don't really know how this would work best with how the volumetric fog is implemented.

If this enhancement will not be used often, can it be worked around with a few lines of script?

As for the simplified fog, it's possible with custom post processing, but it's quite hard to get that to look correct, and also still work with the background color. Transparent materials also don't work very well together with this approach.

Is there a reason why this should be core and not an add-on in the asset library?

It changes part of the rendering behavior, which can only be done via core

AaronRecord commented 3 years ago

Duplicate of https://github.com/godotengine/godot-proposals/issues/2261?

clayjohn commented 3 years ago

Fog is calculated during the regular drawing off meshes, not in its own pass.

For simple fog, we exposed the ability to override it in spatial shaders https://github.com/godotengine/godot/pull/41415

For volumetric fog we have #2261

Dimev commented 3 years ago

Ah hmm

Would it be possible to add a global override for it? as I feel like making almost every material in a game use a special shader just for doing fog would be rather unwieldly

Calinou commented 3 years ago

Would it be possible to add a global override for it? as I feel like making almost every material in a game use a special shader just for doing fog would be rather unwieldly

Unfortunately, this likely isn't possible for various reasons: https://github.com/godotengine/godot-proposals/issues/2595

You can convert a SpatialMaterial to a ShaderMaterial, but there isn't an easy way of making sure it's used everywhere right now.

@clayjohn Do you think a way to override SpatialMaterial could be exposed, in the same way the MainLoop can be overridden (for instance)? I suppose this would cause issues with the editor though, since gizmos assume that they have access to a "vanilla" SpatialMaterial (StandardMaterial3D in master).

Dimev commented 3 years ago

Hmm

I do think it would be nice to have some way to add features to the default spatial/shadermaterial.

Should I make a proposal for that instead and close this one?

Calinou commented 3 years ago

Should I make a proposal for that instead and close this one?

I wouldn't do it just now, because we don't know if this proposal (the one you've just posted) is technically feasible yet.

clayjohn commented 3 years ago

Would it be possible to add a global override for it?

Right now, no. In theory we could:

  1. Add something like your original proposal (i.e. a global fog override shader that is inserted into the main shader)
  2. Add a fog override feature to StandardMaterial3D (not sure that this would be beneficial other than to specify different fog parameters for individual objects)
  3. Add an include system to shaders to make it easy to share custom behaviour between shaders

I don't think any of these options actually solve your problem. It sounds like you are looking for a way to implement proper atmospheric scattering which is not the same thing as fog. In my opinion atmospheric scattering is a feature in its own right and should not be bundled in with fog.

I do think it would be nice to have some way to add features to the default spatial/shadermaterial.

No need to open a proposal for that, just add your additional thoughts to the already open proposal https://github.com/godotengine/godot-proposals/issues/1779

Calinou commented 3 years ago

I don't think any of these options actually solve your problem. It sounds like you are looking for a way to implement proper atmospheric scattering which is not the same thing as fog. In my opinion atmospheric scattering is a feature in its own right and should not be bundled in with fog.

For the record, I made a proposal for this: https://github.com/godotengine/godot-proposals/issues/1698

clayjohn commented 3 years ago

For the record, I made a proposal for this: #1698

Ah, not quite. Atmospheric scattering refers to the scattering that makes the sky blue and distant objects fade towards white/blue.

Dimev commented 3 years ago

Yeah As of now atmospheric scattering (as in atmosphere for a whole planet) is doable with an unshaded shader, and a cube mesh with inverted faces, but it doesn't play nicely with translucency and lighting from some sort of skysphere/background.

Adding a feature just for doing atmospheres like this would be a bit too specific, so that's why I made this proposal, as the normal distance fog seems to work a lot better for how I want the atmosphere to work, and it could be useful to other users as well for making custom fog effects.

Calinou commented 2 years ago

This is now implemented for volumetric fog using FogVolume nodes, which can be local to an area or global: https://github.com/godotengine/godot/pull/53353

Fixed (non-volumetric) fog does not have a way to be overridden globally yet. There are however several proposals on improving fixed fog to make it more usable, such as https://github.com/godotengine/godot-proposals/issues/3429 and https://github.com/godotengine/godot-proposals/issues/4102.

Fog can also be added on a per-material basis already with the FOG shader override (it can't override existing built-in fog).