Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design proposal: Atmosphere / Sky parameters #163

Open
birkskyum opened this issue May 13, 2023 · 37 comments
Open

Design proposal: Atmosphere / Sky parameters #163

birkskyum opened this issue May 13, 2023 · 37 comments
Labels
enhancement New feature or request

Comments

@birkskyum
Copy link
Member

birkskyum commented May 13, 2023

Design Proposal: Atmosphere / Sky

Motivation

It would be great to have not just a solid color, but a nice atmosphere gradient as the backdrop for the map. The suggested changes are in production here: https://www.maptoolkit.com/map/#/@13.02403,46.59774,12.6,-35.2,75,terrain,3d
A PR of that implementation is here

Proposed Change

Add a sky parameter, like this:

sky: {
     "sky-color": "#199EF3", // the color of the sky
     "sky-horizon-blend": 0.5, // a value between 0 and 1. 0 is the horizon, 1 is map-height / 2
     "horizon-color": "#ffffff", // the second sky color at the horizon, default is sky-color
     "horizon-fog-blend": 0.5, // with a value from 0 to 1. 0 is no blend, 1 is blend to height/2 (e.g. max visible sky at max pitch)
     "fog-color": "#0000ff", // the color of the fog
     "fog-ground-blend": 0.5, // with a value from 0 to 1. 0 is the map-center, 1 is the far-clipping-plane. This setting works only in 3d-mode, also fog is faded out when lowering pitch and disappears below pitch 60
     "atmosphere-blend": ["interpolate", // interpolate the atmosphere blend using expressions
          ["linear"],
          ["zoom"],
          0,1, // z0 - 1 - fully visible atmosphere
          10,1, // z10 - 1 - fully visible atmosphere
          12,0 // z12 - 0 - no atmosphere
          ] 
     ]
}

horizon-fog-blend: same as horizon-blend in current definition
fog-blend: same as current definition

  • sky-color
  • fog-color map below horizon is colored also with this color
  • horizon-blend with a value from 0 to 1. 0 is no blend, 1 is blend to height/2 (e.g. max visible sky at max pitch).
  • fog-blend with a value from 0 to 1. 0 is the map-center, 1 is the far-clipping-plane. This setting works only in 3d-mode, also fog is faded out when lowering pitch and disappers below pitch 60

API Modifications

Outline what modifications you expect on the API due to your change.

Migration Plan and Compatibility

We can have this disabled at first, with options to enable a feature flag. The code is supposed to be backwards compatible.

Rejected Alternatives

@birkskyum birkskyum changed the title Add atmosphere parameters Atmosphere / Sky parameters May 13, 2023
@birkskyum
Copy link
Member Author

@louwers - this would of course influence Native when the time for atmosphere comes

@HarelM
Copy link
Member

HarelM commented May 13, 2023

Also probably worth bringing this up in the next TSC meeting.

@HarelM
Copy link
Member

HarelM commented May 13, 2023

The only input I have regarding this proposal is that if in the future globe view will be implemented, how would this proposal change, if at all.
Otherwise looks good I think.

@HarelM
Copy link
Member

HarelM commented Aug 13, 2023

Seems like cesium has more parameters to the sky, including the sun:
https://cesium.com/blog/2022/05/26/improved-atmosphere-in-cesiumjs/
Not sure if and how this is relevant to this issue, but it's worth linking I believe.

@birkskyum
Copy link
Member Author

birkskyum commented Aug 13, 2023

Demo of all the many parameters of Cesium - https://sandcastle.cesium.com/?src=Atmosphere.html

@HarelM
Copy link
Member

HarelM commented Aug 13, 2023

The mobile version of the above page is just so bad... Man... I'm surprised people are still writing non-responsive sites theses days... 😕

@acalcutt
Copy link
Contributor

acalcutt commented Aug 14, 2023

I made PR #298 here to separate the style-spec changes from the maplibre-gl-js changes in maplibre/maplibre-gl-js#1713

The style spec changes at #298 are relevant to this issue since it implements the proposed change in style spec. I'm sure if we want more properties, more would need to be added to this.

I made @acalcutt/maplibre-gl-style-spec v19.3.2 which includes these changes, but I haven't quite had luck testing it in my test maplibre-gl-js branch yet (still testing with maplibre/maplibre-gl-js#2974).

@HarelM
Copy link
Member

HarelM commented Sep 3, 2023

Since I don't have a better idea what parameters can be add to the sky let's continue with this design proposal, these parameters make sense to me as opposed to the huge number of parameters in the cesium page which are not intuitive.
I've added some minor comments in the PR.
I prefer to approve the PR only if I know that we are planning to integrate the sky code of GL JS, otherwise limiting the spec to something we are not planning to implement in any platform isn't a great idea.
As far as I know the sky PR in GL JS, much like the one here, is missing tests to be integrated.

@HarelM HarelM changed the title Atmosphere / Sky parameters Design proposal: Atmosphere / Sky parameters Dec 31, 2023
@HarelM HarelM added the enhancement New feature or request label Dec 31, 2023
@HarelM
Copy link
Member

HarelM commented Jan 3, 2024

I'll push forward the linked PR.
I'll also add some experimental warnings ATM and also won't add any supported version.
If this won't be implemented we will remove it from the spec.
@sjg-wdw if you have any comments about the spec that was defined here it would be great, if any of this doesn't align with how things are in native, now would be a great time to raise this.

@sjg-wdw
Copy link

sjg-wdw commented Jan 3, 2024

Thanks for tagging me.

Cesium's approach is the right one if you're doing a true globe and want a real atmosphere both for space and the ground. So my suggestion is not to address that if there's no globe mode planned. The shader can get pretty complex.

But there's nothing wrong with hacking it. A gradient is a nice idea, going from horizon on up. Beyond that, maybe toss an image in there oriented with... I guess the horizon would do. Or maybe the middle of the image is the horizon and it goes up and down from the middle.

Thinking about how to implement that, it's probably not too hard either way.

@HarelM
Copy link
Member

HarelM commented Jan 3, 2024

There's is an implementation that got a bit stale here, I hope to push it forward after this issue is properly defined:
maplibre/maplibre-gl-js#1713

The parameters described in Cesium are very complicated and I wouldn't want a map designer to configure all of these, it's just too much (even with good defaults).

So the main question here, after the "is it possible?" question would be if the spec design is clear enough and makes sense, or you think there are other parameters that might be interesting?

@HarelM HarelM mentioned this issue Jan 7, 2024
8 tasks
@HarelM
Copy link
Member

HarelM commented Jan 7, 2024

I've created the above linked PR: #478, feel free to review it.
Once reviewed I'll merge it and release a new version of the style-spec package to allow continuing to work on maplibre-gl-js package.

@HarelM
Copy link
Member

HarelM commented Jan 7, 2024

I believe when looking at the map in 2D you don't want it "as realistic" as 3D. A design consideration I believe, not sure though. @prozessor13 do you remember why?

@prozessor13
Copy link

Hi Harel,

The sky is rendered beyond the map and is available in both, 2D and 3D.
The fog requires extra shader-code which is only implemented in the terrain shader. It was not a design consideration, more a "less work" consideration, because the fog logic has to be implemented in every single shader, and there a lot of them. So basically the 80/20 percent rule. In this case you get 80% benefit for 20% work.

@HarelM
Copy link
Member

HarelM commented Mar 13, 2024

I'm not sure this is finalized as there is a comment, which I'm not sure is well defined regarding the spec about a secondary color to the sky, see here:
maplibre/maplibre-gl-js#3645 (comment)

I'm not 100% sure how this would look in the spec though.
I've added this topic to the meeting tonight.

@birkskyum birkskyum reopened this Mar 13, 2024
@birkskyum
Copy link
Member Author

Okay, i had an impression it was done for this repo when this landed, but haven't tracked it close enough clearly - #478

@HarelM
Copy link
Member

HarelM commented Mar 25, 2024

Written by @prozessor13 here:

It should be easy to implement a second sky color to create a 2-color gradient, and i think i can find time for this the next weeks.

proposal:

  • sky-color: same as current definition
  • horizon-color: the second sky color at the horizon, default is sky-color
  • horizon-sky-blend: a value between 0 and 1. 0 is the horizon, 1 is map-height / 2
  • fog-color: same as current definition
  • horizon-fog-blend: same as horizon-blend in current definition
  • fog-blend: same as current definition

I am really not sure how to name the parameters. please make better suggestions. For sure this proposal is very limited in features, but may sufficient in most scenarios? What do you think?

@HarelM
Copy link
Member

HarelM commented Mar 25, 2024

I think the names are good, the only thing that is not intuitive is the fog-blend - blend between fog and what?
Others are describe and make sense to me, maybe add the word color to blend like horizon-fog-color-blend, but it might be redundant.

@prozessor13
Copy link

what do you think about: fog-map-blend or fog-terrain-blend. On the other hand the name fog is may also not 100% correct. It is more an atmospheric effect, that blurs the terrain near the horizon. Should i rename fog whith atmosphere?

@HarelM
Copy link
Member

HarelM commented Mar 26, 2024

@Pheonor what do you think since you are looking into atmosphere effects now?
I thought that "ground" might be the relevant word here: ground-atmosphere-blend or fog-ground-blend. It's true that currently it only applies to terrain, but it might not be the case in the (near?) future.

@syonfox
Copy link

syonfox commented Mar 26, 2024

As mention here the feature of accurate star map / sky box that shifts with the globe might be really an extension of the sky spec. maplibre/maplibre-gl-js#3889

as mentioned elsewhere this feature is like cesium https://sandcastle.cesium.com/?src=Atmosphere.html

Note how they split this into ground atmosphere and sky atmosphere and I'm not sure whether are 2 effects on the actual map and on the sky;

As mentions in the projection issue above it seems that he sky parameters would be used for both the globe mode and the terrain mode

I suspect there should be a general style that is easy for end users and describes the actual visual effect desired and the we would need to remap that to specific options in the terrain mode and globe mode

let style = {
projection: {
  type: "globe",
  sky: {...__globeSpecificScyOptions}
}

terrain: {
  sky: {...__terinaSpecificSkyOptions}
}

//note the above may be 'internal' 

sky: {
  "sky-color": "#199EF3", // maybe background-color sky is redundant
  "fog-color": "#00ff00",
  "horizon-blend": 0.5,
  "fog-blend": 0.6,
  //proposed
  "skybox": "simple static cube map background"
  
}

maybe this could be something like this:
https://cesium.com/learn/ion-sdk/ref-doc/SkyBox.html#SkyBox

let skybox = {
  sources : {
    positiveX : 'skybox_px.png',
    negativeX : 'skybox_nx.png',
    positiveY : 'skybox_py.png',
    negativeY : 'skybox_ny.png',
    positiveZ : 'skybox_pz.png',
    negativeZ : 'skybox_nz.png'
  }
  //
  real-time: true // ... needs implementation specific details
  // theoretically this would rotate the skybox such that the stars are positions correctly relative to the globe/ horizon
});

https://en.wikipedia.org/wiki/Galactic_coordinate_system (or a new innovated way of mapping / rendering the sky ???)

this is interesting also see that first comment for a for more links on the topic.

In theory this would be a nice addition as zooming out or rotating the camera up from terrain mode could offer users a realistic view of the night sky. I can think of many useful project that would love this such as mapping space objects. allowing users to view constellations from terrain mode etc. even render a skybox dependent on the local time of day would all be possible. Also it would just look really cool to map stuff on the earth as it actual is in the galaxy.

@Pheonor
Copy link

Pheonor commented Mar 26, 2024

@Pheonor what do you think since you are looking into atmosphere effects now? I thought that "ground" might be the relevant word here: ground-atmosphere-blend or fog-ground-blend. It's true that currently it only applies to terrain, but it might not be the case in the (near?) future.

Effectively, adding a 'ground' prefix could be a good idea.
I try to port the PoC of the atmosphere into the new globe code and after that I will come back here to discuss the new parameter we could add to configure it.

@Pheonor
Copy link

Pheonor commented Apr 20, 2024

The current proposition for atmosphere use three parameters:

  • 'full-atmo-zoom-level': Display the atmosphere when the zoom level is below
  • 'no-atmo-zoom-level': Hide the atmosphere when the zoom level is above
  • 'sun-date-and-time': If set, define the date and time to set the Sun position (else, use current date and time)

Do you think a dedicated 'atmosphere' section is possible ?

@HarelM
Copy link
Member

HarelM commented Apr 21, 2024

I believe we can have a section inside the sky for atmosphere, or do you think it should be a different section altogether? I find the sky and atmosphere to be connected.
How about atmosphere-minzoom and atmosphere-maxzoom?
Date and time have timezones, how do you purpose to solve this? Giving a time/date with timezone definition? I also think this option should give "current" or "auto" for the option instead of only support undefined.

@Pheonor
Copy link

Pheonor commented Apr 21, 2024

Effectively, an atmosphere section into the sky section could be a good option.
I think that a second implementation of the atmosphere could also used other sky parameter with an not realistic version but more like a glowing sphere.

atmosphere-minzoom is Ok. Bellow this value, the atmosphere is not render.
atmosphere-maxzoom do not reflect the intention. Above the maxzoom, the atmosphere is still render.
Between the two value, a linear coefficient is computed to fade in and out the atmosphere.

For the timezone, I propose to use only UTC. current or auto are good proposition to replace the undefined :)

@HarelM
Copy link
Member

HarelM commented Apr 21, 2024

Can you clarify the definitions then?
I'm not sure I understand what you are proposing in terms of when to render the atmosphere, when not to render and when to do a linear "gradient".
Try and give actual examples.
For example:
for z0-z10 draw atmosphere, for z10-z12 do a linear gradient, for z12 and above do not render the atmosphere at all.
If this is the intention of the above parameters I would consider something like:

sky: {
  ...
  atmosphere: {
    maxzoom: 10 // below this number the atmosphere will be fully rendered - in this case <= z10
    fadezooms: 2 // the number of zoom levels to fade the atmosphere - in this case 2 zoom levels z11 and z12
    // this definition implies that atmosphere will not be rendered for > z12
  }
}

Not sure the above spec is well defined in terms of spec and is intuitive enough, maybe we should get some inspiration from existing style spec definitions such as transition maybe... IDK...
I also am not sure this is what you intended, so feel free to correct my understanding of what you proposed.

@Pheonor
Copy link

Pheonor commented Apr 21, 2024

This is exactly what you are describing.

@HarelM
Copy link
Member

HarelM commented Apr 24, 2024

Maybe we can use something like the light position that is described here:
https://maplibre.org/maplibre-style-spec/light/
It says in the docs that position supports interpolate expression, which is similar I believe to what is needed here where we want to transition from "has atmosphere" (lets call it 1) to "no atmosphere" (lets call it 0).
I haven't looked deeply on how light position can be expressed, but I guess it's worth a look.

@Pheonor
Copy link

Pheonor commented Apr 24, 2024

Sun position could effectively be expressed with something similar.
Internaly, the date and time are converted into an 'equatorial coordinates' with the 'right ascension' and the 'declination'.
We could use a 2D position vector with first value the 'right ascension' and second value the 'declination'.

In fact, this system could be complicated to use and do not allow to create a realistic position of the Sun.
Another option could be to directly define the 'longitude' and 'latitude' of the Sun.
These differents options does not prevent to put the Sun in the North Pole.

@HarelM
Copy link
Member

HarelM commented Apr 27, 2024

Wait, shouldn't the sun's position be defined by the light angle?
I know 2D maps are usually using an incorrect light source in northern hemisphere, but the sun is basically the light source, shouldn't we update the light spec (if this is needed at all) to accommodate for the sun's position?

@kubapelc
Copy link

Some thoughts....

Sun position for atmosphere and sun position for fill-extrusion doesn't necessarily need to be the same, unless someone makes a map where fill-extrusion and (globe) atmosphere are visible at the same time, then light position should probably be consistent, but that can be the responsibility of whoever is creating the map style. Maybe both fill-extrusion and atmosphere can select a light, defined by the light spec?

This would require the light-spec to be modified to allow for multiple light sources.

Also, looking at the actual current implementation of light for fill-extrusion, doesn't the position property just get interpreted as a direction vector (which doesn't get normalized?), even though the spec says that it is a distance and two angles? See https://github.com/maplibre/maplibre-gl-js/blob/main/src/render/program/fill_extrusion_program.ts#L80

With the current spec, I don't think there is a point in specifying the light's distance, interpreting the light as a purely directional, infinitely-distant light source (such as the sun) is probably good enough. (Or does MapLibre need to support point lights?)

I think another anchor type for light would be useful, in addition to the unmodified first two. The functionality could be as follows:

  • map - The light direction is relative to the map's north, but also relative to the map's center - if the light source appears to be in the top left at null island, it will still appear in the top left if we change the map center's longitude.
  • viewport - Same as map, but pitching/rotating the map changes the light direction relative to map's objects, so that is it coming (eg.) always from the screen's top left.
  • planet - (new!) The light direction is specified relative to the planet, so if we set the light to be overhead at null island, a location at E90N0 will have the light coming from the west, a location at W90N0 from the east. (If we want to support point lights, this anchor would also be useful for placing a light at a specific place in the world.)

I think an intuitive way of specifying the light's direction is longitude and latitude of the location at which the sun is directly overhead. This works seamlessly with the planet anchor type, for the other two anchor types, these "coordinates" would specify the light direction as it would appear at null island, and that relative direction is then kept regardless map's center.

@HarelM
Copy link
Member

HarelM commented Apr 29, 2024

Note that light is also relevant to hill-shading, not just fill extrusion.
poistion can get an expression, so you can have different lights for different zoom level (I think, I haven't tested this theory), which might solve the switch from globe to mercator.

Looking at the definitions above with planet which sounds like the right direction to me, don't we need planet-viewport as well?

I think that sun direction over null island is a very intuitive definition (assuming the distance is infinity obviously), but we shouldn't change the current definition of light in order not to break backwards compatibility).

Regarding what I wrote above about maxzoom we can use the term already used for the fog and ground with an expression (since light already using an expression ability, this won't be totally new).

{
    ...
    atmosphere: {
        blend: ["interpolate", // interpolate the atmosphere blend using expressions
            ["linear"],
            ["zoom"],
            0,1, // z0 - 1 - fully visible atmosphere
            10,1, // z10 - 1 - fully visible atmosphere
            12,0 // z12 - 0 - no atmosphere
             ] 
        ]
    }
}

@Pheonor
Copy link

Pheonor commented Apr 30, 2024

Ok for the position definition of light. I propose to keep a parameter to define the mode as a position or 'auto' to compute the Sun position based on current date and time.
For the blend parameter using the expression, it was a very good proposition.

@HarelM
Copy link
Member

HarelM commented May 16, 2024

I've updated the initial post to have the most up-to-date definition I know of.
Feel free to add a comment If I missed anything.

@Pheonor
Copy link

Pheonor commented May 21, 2024

It is Ok for me for the atmosphere paremeters.
For the Sun position, we use the existing light spec, right ?

@HarelM
Copy link
Member

HarelM commented May 30, 2024

Yes, let's use the existing light property for the sun position over null island as an initial implementation.
See how it looks and behaves, get some feedback and then decide if this needs to be improved/extended or is good enough as is.

@HarelM
Copy link
Member

HarelM commented May 30, 2024

Currently atmosphere has only one parameter. I'll collapse it into the sky definition for now.
It will be an experimental definition until the implementation will be done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants