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

11716 visualize fog #11744

Merged
merged 60 commits into from
Jan 18, 2024
Merged

11716 visualize fog #11744

merged 60 commits into from
Jan 18, 2024

Conversation

ptrgags
Copy link
Contributor

@ptrgags ptrgags commented Jan 5, 2024

Description

While #11718 enabled and tuned the performance aspects of fog for 3D Tiles, this PR is about rendering the fog for 3D Tiles. This includes atmosphere color and dynamic lighting to make more realistic looking fog that accounts for Rayleigh and Mie scattering. The goal is to make world-scale 3D Tiles tilesets like Google Photorealistic 3D Tiles look more realistic like we do for terrain.

image
image

Local Sandcastle Example

To do this, it involves quite a few moving parts, as Model does not have access to the Scene, and the model isn't always added to the scene anyway.

  • Created an Atmosphere class (scene.atmosphere) that will hold the atmosphere related settings (see Proposal: Consolidate SkyAtmosphere and Globe atmosphere settings? #11681 for the longer-term plan which involves breaking changes to the API)
  • The atmosphere updates the FrameState each frame (this is modeled after what Fog does)
  • The UniformState adds some new uniforms (czm_atmosphere*) whose values come from the FrameState.
  • A new Model pipeline stage, FogPipelineStage adds the shader code for enabling fog
    All this together,

Issue number and link

Fixes #11716

Testing plan

For testing, I've been adjusting

Here's a roundup of the Sandcastles I used for testing:

Author checklist

  • I have submitted a Contributor License Agreement
  • I have added my name to CONTRIBUTORS.md
  • I have updated CHANGES.md with a short summary of my change
  • I have added or updated unit tests to ensure consistent code coverage
  • I have update the inline documentation, and included code examples where relevant
  • I have performed a self-review of my code
  • Loose ends
    • Try the other method of computing the ellipsoid position mentioned in Visualize fog for 3D Tiles/Models #11716 and compare visual quality and performance. The first method does a reasonable job
    • Find a way to mark a tile as being "in fog" -- the fog density calculation for dynamic SSE will be relevant here, and only apply the shader to tiles in fog
    • Allow selecting between vertex/fragment shader for doing the atmosphere calculations.
    • Add a render test that puts a tileset on the horizon, adjusts the sun position, and verifies that the color changes. This may require turning off dynamic SSE so the tileset doesn't get culled.
    • Go through GlobeVS and GlobeFS and see what other details I might have overlooked, as those shaders are rather involved.

Copy link
Contributor Author

@ptrgags ptrgags left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notes on things I still need to do

packages/engine/Source/Shaders/Model/FogStageFS.glsl Outdated Show resolved Hide resolved
packages/engine/Source/Shaders/Model/FogStageFS.glsl Outdated Show resolved Hide resolved
packages/engine/Source/Shaders/Model/FogStageFS.glsl Outdated Show resolved Hide resolved
packages/engine/Source/Shaders/Model/FogStageFS.glsl Outdated Show resolved Hide resolved
packages/engine/Source/Shaders/Model/FogStageFS.glsl Outdated Show resolved Hide resolved
* @param {vec3} mieColor The Mie scattering color computed by a scattering function
* @param {float} opacity The opacity computed by a scattering function.
*/
vec4 czm_computeAtmosphereColor(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a note to #11681 that this can be used in other shaders once the API change happens.

Copy link
Contributor

@jjhembd jjhembd Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we eliminate the code duplication even before the API change?
I know at one point you mentioned the Globe uses defines rather than a uniform. That seems like a change we could make internally without affecting the API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I certainly would like that but I need to examine how big of a change this would be. The problem is one version of these functions use uniforms set by a specific primitive (u_atmosphereWhatever) and others use the new automatic uniforms (czm_atmosphereWhatever). You'd need to tie the two together. I have an idea about how to do that, but I have to see if it's too big for this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#11681 (comment) -- here are more ideas of how to make this work during the deprecation period (in short, have the globe/sky hold a reference to the atmosphere whenever attached to a scene, and the old parameters will just update the new common one).

While certainly this could be done before the API deprecation, I think it's beyond the scope of this PR since it would add a decent chunk of code here. @ggetz would you agree?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's try to keep the scope of this PR small if possible.

@ggetz
Copy link
Contributor

ggetz commented Jan 5, 2024

Thanks @ptrgags! Can/Should there be an API option to alter the fog falloff visually in order to bring it closer to the camera?

@ptrgags
Copy link
Contributor Author

ptrgags commented Jan 5, 2024

@ggetz there already is, fog.density controls that

@ptrgags
Copy link
Contributor Author

ptrgags commented Jan 8, 2024

Today I've been comparing the different approaches to computing the ellipsoid position in the shader to see the visual differences and performance differences.

Observations:

  • The curvature method and the iterative method (1 iter) don't produce a perceptible difference: (and yes I've double checked that the button does change which shader function is called)
    2024-01-08_IterativeNoChange, so it really comes down to performance difference.
  • For future reference, there is a difference between the two computations given the approximation methods used. The GIF below is visualizing abs(curvature - iterative1) / 1000. The difference is bigger at larger camera distances
    2024-01-08_CurvatureVsIterative
  • Also, following @jjhembd's suggestion, I tried comparing 1 iteration vs 3 iterations for the iterative method. the difference is small, less than 100m and this happens mostly at the equator, with a smaller difference happening at the poles.
    image
    image
  • In light of the above, if we use the iterative method, one iteration seems sufficient to give realistic fog.

I tried the FPS monitor but it doesn't really have the granularity I need to distinguish the two methods (both hover at 59-60 FPS) . I'll see if there's another way to measure it. If there isn't a large perf difference, I'd rather use the iterative method since it better matches the ellipsoid model of the earth.

@ptrgags
Copy link
Contributor Author

ptrgags commented Jan 8, 2024

Since it's hard to get a precise number for the shader execution time, I'm trying the approach of running the code many times in a loop to amplify differences so it's noticeable in the FPS monitor.

Also note that I have the fog density turned up and fog still is being applied to tiles, so this is giving a measure of worst-case performance.

In the views below I made sure to include close-up, zoomed out, near-equator and near-poles views.

View Curvature method 1-iteration method
image 14 FPS 20 FPS
image 25 FPS 32 FPS
image 23 FPS 31 FPS
image 13 FPS 17 FPS

So it looks like the 1-iteration method is a clear winner.

@ptrgags
Copy link
Contributor Author

ptrgags commented Jan 9, 2024

I made a local Sandcastle to give a visual comparison of P3DT with terrain.

Case Globe P3DT Notes
No fog/atmosphere image image
+ fog enabled image image Even though both implementations use scene.fog.density and the same math, for some reason the fog looks closer to the camera for terrain 🤔
+ sky atmosphere image image
+ dynamic lighting image image Color is slightly different. See notes below.
+ adjust timeline image image Sunset colors are noticeably different. See notes below.

Notes:

  • The terrain geometry is a bit different between the two datasets and/or the culling methods used.
  • There's still some code that I need to add to the shader that may impact color. Most notably, There's a block of code in the globe shader that darkens the color based on the view and light direction. This might impact why the sunset colors are so different. I'll work on adding this today.

@ptrgags
Copy link
Contributor Author

ptrgags commented Jan 9, 2024

Next, a side-by-side with Google Earth. To give a fairer comparison, I adjusted the following settings:

  • globe.atmosphereLightIntensity/atmosphere.lightIntensity I turned up to 25 from the default of 10 since our fog tends to look darker and hazier by default
  • Google Earth tends to put the fog closer to the camera, so I set fog.density to 1 / (2 * 1500m)
  • Google Earth doesn't use dynamic lighting like we do, so I turned that off

Sandcastle with updated settings

Globe P3DT Google Earth
image image image

The thing that stands out to me is Google Earth's atmosphere effects have more pinks and purples when ours only has blue and white (with dynamic lighting off). Even our sunsets are more orange than the pinks and purples.

@ptrgags
Copy link
Contributor Author

ptrgags commented Jan 9, 2024

I added the code to darken the lighting, now the colors match better between 3D Tiles and the globe:
2024-01-09_DarkenLighting

Perhaps due to different geometry and different methods for computing the ellipsoid position, 3D Tiles fog tends to go dark at slightly higher sun angles than terrain does: (but if I wasn't looking for such subtle differences I might not have noticed this.
2024-01-09_DifferenceInSunsets

@ggetz
Copy link
Contributor

ggetz commented Jan 11, 2024

Thanks @ptrgags! Would you mind updating the Testing Plan section in the PR description when you get the chance?

@ptrgags
Copy link
Contributor Author

ptrgags commented Jan 11, 2024

@ggetz I rounded up all the Sandcastles from the issue and this PR and put them in the description (+ some new ones!).

I'll look into the test failure, I must have formatted my JSDoc incorrectly or referenced something incorrectly.

@ptrgags
Copy link
Contributor Author

ptrgags commented Jan 11, 2024

@ggetz I've addressed your feedback, this is ready for review again.

packages/engine/Source/Scene/Atmosphere.js Outdated Show resolved Hide resolved
packages/engine/Source/Scene/Atmosphere.js Outdated Show resolved Hide resolved
packages/engine/Source/Scene/Scene.js Outdated Show resolved Hide resolved
packages/engine/Source/Scene/Scene.js Outdated Show resolved Hide resolved
@ggetz
Copy link
Contributor

ggetz commented Jan 12, 2024

@jjhembd Would you mind taking a pass on the shaders in this PR?

@ptrgags
Copy link
Contributor Author

ptrgags commented Jan 16, 2024

@ggetz @jjhembd Updated the PR based on @ggetz's feedback.

Copy link
Contributor

@jjhembd jjhembd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ptrgags, the Model implementation looks good, and this also looks like a very nice cleanup of the atmosphere shaders.
My main question is: can we drop some of the old versions sooner, even before the API change suggested in #11681? Some of the smaller functions can be trivially consolidated (see comments below). It would be nice to do a bigger consolidation now if we can.

packages/engine/Source/Shaders/GlobeFS.glsl Outdated Show resolved Hide resolved
packages/engine/Source/Scene/FrameState.js Outdated Show resolved Hide resolved
* @param {vec3} mieColor The Mie scattering color computed by a scattering function
* @param {float} opacity The opacity computed by a scattering function.
*/
vec4 czm_computeAtmosphereColor(
Copy link
Contributor

@jjhembd jjhembd Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we eliminate the code duplication even before the API change?
I know at one point you mentioned the Globe uses defines rather than a uniform. That seems like a change we could make internally without affecting the API.

@ptrgags
Copy link
Contributor Author

ptrgags commented Jan 18, 2024

@ggetz @jjhembd I addressed all the remaining feedback

@ggetz
Copy link
Contributor

ggetz commented Jan 18, 2024

@jjhembd Please merge once you are happy!

Copy link
Contributor

@jjhembd jjhembd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks @ptrgags!

@jjhembd jjhembd merged commit 5046889 into main Jan 18, 2024
9 checks passed
@jjhembd jjhembd deleted the 11716-visualize-fog branch January 18, 2024 22:03
@jjhembd jjhembd mentioned this pull request Feb 1, 2024
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Visualize fog for 3D Tiles/Models
3 participants