CesiumGS / CesiumGS/cesium

Additional Procedural Cloud Features

Open
#9,764 0 comments 3 reactions 0 assignees View on GitHub
type - enhancement
Dominant language
JavaScript
Stars
15.7k
Forks
3.9k
Avg merge
4d 6h
Merged PRs (30d)
34

Description

Although procedural clouds are an upcoming feature, it's only the beginning of a larger clouds system in CesiumJS. There were many ideas that I wasn't able to implement within the scope of my internship. I added these ideas below with my thoughts on how I would implement them if I had the time.

## Cloud color adjustment
Similar to how [`SkyAtmosphere` can adjust its hue, saturation, and brightness](https://sandcastle.cesium.com/?src=Sky%20Atmosphere.html), clouds should have options to modify their color to match different sky backgrounds. For instance, it would be nice to color the clouds pink or orange to match the sky if a user is depicting a sunset.

I imagine this will be different from `SkyAtmosphere`'s implementation, however, because the cloud starts as a desaturated white / grey tone. As a result, hue-shifting won't actually change the color. (That's how HSL adjustment works in Photoshop, at least.) Perhaps the cloud should directly accept HSL values instead, so that users can look them up in a color picker and then apply them to their clouds. For reference, here's [the formulae to convert HSL to RGB values](https://en.wikipedia.org/wiki/HSL_and_HSV#Color_conversion_formulae).

## Cloud shading based on sun direction
The algorithm for cloud texturing includes a factor for diffuse (Lambertian) shading, but I used a fixed light direction so that the appearance of the cloud would be constant. It would be nice to have an option to toggle on shading with `czm_lightDirection`, where the cloud takes into account the light of the sun. This would require more than replacing `lightDir` in the code with `czm_lightDirection`, however. The billboard follows the user, so there needs to be extra calculation to account for the change in rotation as the user rotates around the cloud. Otherwise, the cloud will be constantly lit from one side, such that when the user looks at it from the other side, it will look incorrect.

This calculation will probably involve passing the cloud's position in some capacity to the fragment shader (`CloudCollectionFS`). Additionally, the algorithm will need to account for when the sun is on the other side of the world. Otherwise, when the scene is dark, the cloud will still be lit from underneath.

## Better texture filtering
The procedural noise used to shape the clouds is computed and stored in a texture before the actual clouds are drawn. Because 3D textures aren't supported by WebGL1, the noise is stored in one long texture divided into z-slices. Because of this, if the texture filter is set to `LINEAR`, the values on the borders of the z-slices will blend together, which is undesired. To circumvent this, texture filtering is set to `NEAREST`, and the `CloudCollectionFS` shader performs trilinear interpolation of eight samples of the texture. It would be nice to find a way to take of hardware linear filtering instead of doing it ourselves.

## Make `CloudCollection` contain a `BillboardCollection`
From @lilleyse's notes on #9737:

> Some more meta feedback - now that I've reviewed the code I think CloudCollection could possibly contain a BillboardCollection under the hood, but there would have to be some changes to get it to work:
> - BillboardCollection deals with both the position/sizing/orientation of billboards and texture atlasing. These two aspects would need to be decoupled since CloudCollection only needs the first as it does its own procedural texturing.
> - BillboardCollection would need to allow for custom attributes - like cloud brightness and the various noise parameters
> - BillboardCollection would need to support a shader hook in point in the frag shader, so that CloudCollection can insert its own procedural shading

## Fade by distance options
It would be nice to have fade by distance options for clouds, the same way that `Billboard` has those options. Perhaps implementing the above optimization (putting a `BillboardCollection` in the cloudCollection) can eliminate the need for larger in code.

## Additional types of clouds
The `CumulusCloud` class is named the way it is (and not just `Cloud`) to distinguish itself from other cloud classes, should they be introduced. I have not thought enough about how to restructure `CloudCollection` for this.
- Maybe there can be a general `Cloud` class to better interface with `CloudCollection`.
- Or, since the implementations for clouds will be different between cloud classes, perhaps the variables for managing `CumulusClouds` should be duplicated for each type of cloud.
- Perhaps there should be an overall `Clouds` class that manages several `CloudCollection` instances, where each collection manages a specific cloud type.

Some cloud types that would be nice to implement are:
### Cirrus clouds
![image](https://user-images.githubusercontent.com/32226860/130988814-a700c21b-7a9e-4d74-a856-196e85417873.png)
Cirrus clouds are high-altitude, wispy clouds that have been compared to feathers and hair. Gardner's [_Visual Simulation of CLouds_](https://www.cs.drexel.edu/~david/Classes/Papers/p297-gardner.pdf) models cirrus clouds using an infinite 2D plane, @lilleyse suggested they would look better as [partial `EllipsoidGeometry` panels](https://sandcastle.cesium.com/?src=Partial%20Ellipsoids.html). This way, they would be textured planes that are curved along the surface of the Earth. Gardner's cloud texturing function can still be used for cirrus clouds, with some notes:
- The parameters need to be tuned in a certain way according to the paper, but I think the paper is incorrect about them. The translucence function they use for the 2D cloud plane is: : ![image](https://user-images.githubusercontent.com/32226860/130990849-b341ce9f-3f3e-47bf-abc1-2b5082574235.png) where `It` is the value returned by the cloud texture function. Gardner claims to use "high values of `T1` and `D` to produce large regions of complete translucence fading gradually into opaque clouds," but looking at the map, it is actually low values of `T1` and `D` that accomplish this.
- Additionally, I believe the 2D plane that Gardner is texturing is infinite, which means that without modifications to the code, the clouds will run over the edge of the geometry. Perhaps noise can be used to erode the opacity at the edges. I also experimented with adding Perlin Noise to Gardner's algorithm and got decent results.
### Stratus clouds
![image](https://user-images.githubusercontent.com/32226860/130991004-c9303cc1-5874-49d3-ad08-80d8f6812f04.png)
Stratus clouds are lower in altitude and usually form a cloud layer like shown. WIP

## WIP
I will add more details about these later

- **Animation**
- **3D clouds**
- **Shadows**
- **Automatic cloud generation**

Contributor guide

Open the contributing guide

Research direction

This issue contains several separate proposals spanning CloudCollection, CumulusCloud, CloudCollectionFS, BillboardCollection, and SkyAtmosphere, with references to czm_lightDirection and issue #9737. First choose one narrowly scoped feature and read the relevant cloud implementation and shader entry points; done should mean that one feature has an agreed design, implementation scope, and verification criteria.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
computer-graphics
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
15/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.