maplibre / maplibre-style-spec

MapLibre Style Specification & Utilities
https://maplibre.org/maplibre-style-spec/
Other
76 stars 62 forks source link

Design proposal: Atmosphere / Sky parameters #163

Open birkskyum opened 1 year ago

birkskyum commented 1 year ago

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

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 commented 1 year ago

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

HarelM commented 1 year ago

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

HarelM commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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

HarelM commented 1 year ago

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 commented 1 year ago

I made PR https://github.com/maplibre/maplibre-style-spec/pull/298 here to separate the style-spec changes from the maplibre-gl-js changes in https://github.com/maplibre/maplibre-gl-js/pull/1713

The style spec changes at https://github.com/maplibre/maplibre-style-spec/pull/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 https://github.com/maplibre/maplibre-gl-js/pull/2974).

HarelM commented 1 year ago

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 commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

There's is an implementation that got a bit stale here, I hope to push it forward after this issue is properly defined: https://github.com/maplibre/maplibre-gl-js/pull/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 commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

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 commented 6 months ago

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: https://github.com/maplibre/maplibre-gl-js/pull/3645#issuecomment-1985978097

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

birkskyum commented 6 months ago

Okay, i had an impression it was done for this repo when this landed, but haven't tracked it close enough clearly - https://github.com/maplibre/maplibre-style-spec/pull/478

HarelM commented 6 months ago

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:

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 commented 6 months ago

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 commented 6 months ago

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 commented 6 months ago

@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 commented 6 months ago

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. https://github.com/maplibre/maplibre-gl-js/issues/3889?notification_referrer_id=NT_kwDOAI6ajbI5OTcwODkzNjg5OjkzNDU2Nzc#issuecomment-2016832968

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 commented 6 months ago

@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 commented 5 months ago

The current proposition for atmosphere use three parameters:

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

HarelM commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

This is exactly what you are describing.

HarelM commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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:

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 commented 5 months ago

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 commented 5 months ago

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 commented 4 months ago

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 commented 4 months ago

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

HarelM commented 4 months ago

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 commented 4 months ago

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.

HarelM commented 4 months ago

I've added the definition to the style spec and released a new version. I'll keep this open in case more issues come up as we move this feature forward.