Open ptrgags opened 11 months ago
I'm thinking
Globe
, but open to suggestions
I think the atmosphere options should be in its own object under Scene
in case you don't have a globe
@lilleyse That's a good point, I like that for 2 more reasons:
scene.fog
is implementedI made a forum post to see if the community has any further thoughts on this.
A couple more thoughts:
Setting | Purpose | (Globe ) ground atmosphere |
SkyAtmosphere |
(Globe ) Terrain fog |
Fog culling |
---|---|---|---|---|---|
Viewer constructor: options.globe |
If false, the globe is not created/rendered | If false, does not render. | If false, cannot use lighting from sun, but otherwise not affected | If false, not rendered | If false, no terrain so no fog culling. |
globe.enableLighting |
turns on lighting from the sun or other light source | Toggles lighting | toggles lighting (flag synced via Scene ) |
Toggles lighting regardless of globe.showGroundAtmosphere |
No effect |
globe.dynamicAtmosphereLighting |
Use the sun or other light source. If false, use a light directly overhead of the vertex/fragment | Toggles dynamic lighting | Toggles dynamic lighting (flag synced via Scene ) |
Toggles dynamic lighting (regardless of globe.showGroundAtmosphere |
No effect |
globe.dynamicAtmosphereLightingFromSun |
forces using the sun rather than the scene's current light source (sun or directional light) | Toggles forced sunlight | Toggles forced sunlight (flag synced via Scene ) |
Toggles forced sunlight regardless of globe.showGroundAtmosphere |
No effect |
globe.showGroundAtmosphere |
Turns off rendering of the ground atmosphere | Not rendered | No effect | No effect | No effect |
skyAtmosphere.show |
Turns off rendering the sky atmosphere | No effect | Not rendered | No effect | No effect |
fog.enabled |
Turn off anything to do with fog. | No effect | no effect | Not rendered | No fog culling |
fog.renderable |
Toggle showing fog, but still allow fog culling | No effect | No effect | Not rendered | No effect |
Some of these settings might be better off stored in the new scene.atmosphere
so all the systems always are synced to it via FrameState
and/or AutomaticUniforms
After thinking about the above parameters, here's a proposal for how this might be structured to make the UX for adjusting lighting better, and make it easier for atmosphere and fog settings to be applied to 3D Tiles (and any future system that needs them)
The tricky thing is this does involve quite a few breaking changes to the API, and deprecating things would be a bit tricky. Though at least for some of the settings, #11655 might be a good reference for determining how to deprecate settings.
Purpose: Store common settings that affect all atmosphere rendering affects. This object does not do any rendering, but updates the FrameState
so other systems can access the parameters.
Parameters:
atmosphere.dynamicLighting: DynamicAtmosphereLightSource
- New enum to control which light source is used:
OFF
- No dynamic lighting, atmosphere will be lit from above for every vertex/fragmentSUNLIGHT
- Dynamic lighting that always uses the sun directionSCENE_LIGHT
- Dynamic lighting that uses the scene's current light sourceatmosphere.LightIntensity
- Light intensity for all atmosphere-related effects.atmosphere.Mie{Anisotropy, Coefficient, ScaleHeight}
- Mie scattering settingsatmosphere.Rayleigh{CoefficientScaleHeight}
- Rayleigh scattering settings.atmosphere.perFragmentShading: bool
- Force using the fragment shader. When false, the vertex shader will be used when possible for better performance.Purpose: Store common settings that affect ground atmosphere (impacts the globe and 3D Tiles) This will update the FrameState
so other systems can access the parameters.
Parameters:
groundAtmosphere.show: bool
- Turn on ground atmosphere rendering for the globe and/or 3D Tiles. This does not affect fog.groundAtmosphere.hueShift/saturationShift/brightnessShift/: number
- Adjust the HSB color of the ground atmosphere independent from other atmosphere rendering. This impacts both ground atmosphere and fog (since fog color is derived from ground atmosphere)groundAtmosphere.nightFadeInDistance/nightFadeOutDistance
- Settings for when the darkness of night-time are appliedgroundAtmosphere.lightingFadeInDistance/lightingFadeOutDistance
- Settings for when the ground atmosphere is lit by the sun/other light source.Purpose: Renderable sky atmosphere. It manages any settings specific to the sky rendering
Parameters:
(unchanged) skyAtmosphere.show: bool
- Turn on sky atmosphere rendering
(unchanged) skyAtmosphere.hueShift/saturationShift/brightnessShift/: number
- Adjust the HSB color of the sky atmosphere independent from other atmosphere rendering.
(remove) skyAtmosphere.atmosphere*
-- move scattering settings to the common Atmosphere
Other details:
Scene
sync the lighting settings from the globe, pull them from the FrameState
Purpose: Renderable globe that handles terrain, imagery and other rendering details. It also renders the ground atmosphere and fog for terrain. The main change is to unload some of the rendering settings to Atmosphere
and GroundAtmosphere
so other systems can access them even when the globe is turned off.
Parameters:
(unchanged) globe.atmosphereHueShift/atmosphereSaturationShift/atmosphereBrightnessShift/: number
-- Adjust the HSB color of the ground atmosphere and terrain fog only.
(remove) globe.atmosphere*
-- move scattering settings to the common Atmosphere
(remove) globe.enableLighting, globe.dynamicAtmosphere*
-- These flags were confusing and weirdly coupled to SkyAtmosphere and fog. Replace this with Atmosphere.dynamicLighting
(now an enum)
(remove) globe.showGroundAtmosphere
- Move to groundAtmosphere.show
so this setting can be used for 3D Tiles as well.
I think the settings for Fog are sufficient for now. The main change is that this will now impact 3D Tiles as well.
The fog color is still dependent on the ground atmosphere, but now the dedicated GroundAtmosphere
will put the relevant settings in the FrameState
so both terrain and 3D Tiles can access it.
After talking with @ggetz the other day, we think that the above is a bit of overkill. A couple changes to streamline the above:
GroundAtmosphere
class isn't really needed, just add the settings to scene.atmosphere
(except for show
which should be scoped to the primitive responsible for rendering, whether that's the globe or the tileset)scene.atmosphere
). This means the colors for sky and ground atmosphere will always be in sync (before they were independent.So to summarize the overall architecture
scene.atmosphere
will contain atmosphere settings for any of the systems that need it and update the FrameState
scene.skyAtmosphere
will still be there because it's needed for rendering the sky, but some of the parameters will move to scene.atmosphere
scene.globe
will have some of its parameters moved to scene.atmosphere
Some implementation details from #11744 that will need changes after we change the API:
(I'll update this as I find more)
FogStage(FS|VS).glsl
now use built-in functions for scattering such as czm_computeGroundAtmosphereScattering()
, czm_getDynamicAtmosphereLightDirection()
czm_computeAtmosphereColor()
, etc. These ones use automatic uniforms, compared with the old globe shader that supplied the uniforms itself. Once the API changes to move parameters out of globe, switch to these new functions and remove the dead code that remainsScene#updateEnvironment()
, there's a section of code that calls skyAtmosphere.setDynamicLighting()
from the globe flags. The if defined(globe)
branch will no longer be needed once all atmosphere settings come from scene.atmosphere
, the else clause will always run. Also DynamicAtmosphereLightingType.fromGlobeFlags()
can be removed when this happens.czm_getDynamicAtmosphereLightDirection()
. It might make sense for the globe and SkyAtmosphere to use this function too if possibleSome thoughts about how to make the Globe
and SkyAtmosphere
settings work during the deprecation period:
Scene.globe
's setter is called, also set globe._atmosphere = this.atmosphere
so the globe now has a reference to the atmosphere struct.Scene.skyAtmosphere
to a setter, and do a similar skyAtmosphere._atmosphere = this.atmosphere
Scene.atmosphere
setter that updates globe._atmosphere
and skyAtmosphere._atmosphere
to the new atmosphere object (if the globe/sky exist)Globe
/SkyAtmosphere
, turn all of the atmosphere-related members into properties, and the setters should: A. log a deprecation warning, and B. Don't update the globe/sky, update _atmosphere.<propertyNameHere>
instead (checking first if _atmosphere
is defined). If it's not defined... maybe another warning is needed (not the most elegant, but this is temporary for the deprecation period)czm_atmosphere*
builtins and functionsu_atmosphere*
) and the code used to configure them, as these will become dead code (note, make sure to check through GlobeSurfaceTileProvider.js
and GlobeSurfaceShaderSet.js
carefully.)
As I'm looking into #4196, one thing I notice is that the following settings exist on both
viewer.scene.skyAtmosphere
(for the sky) andviewer.scene.globe
(for ground and fog for terrain):atmosphereBrightnessShift
/brightnessShift
atmosphereHueShift
/hueShift
atmosphereLightIntensity
atmosphereMieAnisotropy
atmosphereMieCoefficient
atmosphereMieScaleHeight
atmosphereRayleighCoefficient
atmosphereRayleighScaleHeight
atmosphereSaturationShift
/saturationShift
Ultimately these impact the shader uniforms in
AtmosphereCommon.glsl
:Since the ground and sky atmosphere both represent the Earth's atmosphere, conceptually they should always use the same settings.
There's also two other benefits of combining them:
Globe
, but open to suggestions).AutomaticUniforms
, this way it's easier to implement fog for 3D Tiles.I'm curious if the community would find this to be a reasonable breaking change, or if there are use cases where configuring
SkyAtmosphere
andGroundAtmosphere
differently is helpful. I'll ask about this on the forum as well.