-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Fog #3154
Merged
Fog #3154
Changes from all commits
Commits
Show all changes
47 commits
Select commit
Hold shift + click to select a range
e0efc3a
Initial fog. WIP.
bagnell 7655844
Fog color WIP.
bagnell 7e59d39
Clean up different fog equations and remove uniform fog color.
bagnell 60e8bd5
More clean up.
bagnell b05a074
More fog color WIP.
bagnell 9b690c7
Merge branch 'master' into fog
bagnell 7894da3
Merge branch 'master' into fog
bagnell d397e32
Use atmosphere color for fog.
bagnell 8fd263d
Merge branch 'master' into fog
bagnell 41b9330
Minor shader clean up.
bagnell bebe65c
Add fog parameters to frame state. Cull globe tiles based on fog WIP.
bagnell 01f6a6c
Update density from experimentation. Fog culling WIP.
bagnell 9d3b07a
Interpolate fog density based on camera height.
bagnell ca742f9
Use preprocessor to enable fog.
bagnell 9d6a8e6
Make scene.fog property. Factor out fog computations. When getting th…
bagnell 80f3f28
Update Sandcastle example locations. Try new density function.
bagnell 8a8c75d
Remove fog density function, use look up table.
bagnell d2df9a1
Remove fog after zooming out a certain distance.
bagnell d2c927b
Clean up unused code and Sandcastle example.
bagnell 64a2be8
Increase SSE when tile is in fog.
bagnell 95048fd
Swap shader when tile is in/out of fog.
bagnell 582426a
Explicitly tag CesiumMath.fog private
pjcozzi dd54283
Doc tweak
pjcozzi 1a194b7
Add comment
pjcozzi d84186f
Add comment
pjcozzi f07d538
Fix whitespace
pjcozzi c5d7341
Tweak density look up table.
bagnell 325d393
Merge branch 'master' into fog
bagnell 35295de
Exploit temporal coherence of zoom level in table look up.
bagnell ff61da5
Clean up searching for height interval.
bagnell d11c50b
Only compute distance to tile once. Tweak frame state.
bagnell 85cc52b
Re-add ability to change the density by scaling the table.
bagnell 7902c29
Fade fog in as the camera is tilted towards the horizon.
bagnell 5420561
Fix tests.
bagnell 64828bc
Add fog tests.
bagnell 22de5d1
Add fog documentation.
bagnell 6f8fb41
Merge branch 'master' into fog
bagnell 403b049
Update fog Sandcastle example with positions that demonstrate perform…
bagnell 10a3b97
Fix cracking between the globe and the atmosphere.
bagnell c6ce4c2
Fix fog for views with negative altitude.
bagnell 333c8f0
Move fog code from scene to new Fog object.
bagnell 186c63f
Enable fog in the tests.
bagnell 7d7c3b2
Tweak CHANGES.md
pjcozzi ed30aa0
Merge branch 'master' into fog
bagnell 28d15df
Fix shader compile in Firefox/IE.
bagnell 4cccade
Only render atmosphere when terrain tiles are rendered.
bagnell 3ba3717
Add checkbox to enable/disable fog in the terrain sandcastle example.
bagnell File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> | ||
<meta name="description" content="Control fog parameters."> | ||
<meta name="cesium-sandcastle-labels" content="Development"> | ||
<title>Cesium Demo</title> | ||
<script type="text/javascript" src="../Sandcastle-header.js"></script> | ||
<script type="text/javascript" src="../../../ThirdParty/requirejs-2.1.20/require.js"></script> | ||
<script type="text/javascript"> | ||
require.config({ | ||
baseUrl : '../../../Source', | ||
waitSeconds : 60 | ||
}); | ||
</script> | ||
</head> | ||
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html"> | ||
<style> | ||
@import url(../templates/bucket.css); | ||
</style> | ||
<div id="cesiumContainer" class="fullSize"></div> | ||
<div id="loadingOverlay"><h1>Loading...</h1></div> | ||
<div id="toolbar"> | ||
<table><tbody> | ||
<tr> | ||
<td>enabled</td> | ||
<td><input type="checkbox" data-bind="checked: enabled"/></td> | ||
</tr> | ||
<tr> | ||
<td>density</td> | ||
<td><input type="text" size="5" data-bind="value: density"></td> | ||
</tr> | ||
<tr> | ||
<td>sse increase factor</td> | ||
<td><input type="text" size="5" data-bind="value: sse"></td> | ||
</tr> | ||
</tbody></table> | ||
<div id="zoomButtons"></div> | ||
</div> | ||
<script id="cesium_sandcastle_script"> | ||
function startup(Cesium) { | ||
"use strict"; | ||
//Sandcastle_Begin | ||
var viewer = new Cesium.Viewer('cesiumContainer'); | ||
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({ | ||
url : '//assets.agi.com/stk-terrain/world', | ||
requestWaterMask : true, | ||
requestVertexNormals : true | ||
}); | ||
|
||
viewer.extend(Cesium.viewerCesiumInspectorMixin); | ||
|
||
//The viewModel tracks the state of our mini application. | ||
var viewModel = { | ||
enabled : true, | ||
density : 0, | ||
sse : 0 | ||
}; | ||
// Convert the viewModel members into knockout observables. | ||
Cesium.knockout.track(viewModel); | ||
|
||
// Bind the viewModel to the DOM elements of the UI that call for it. | ||
var toolbar = document.getElementById('toolbar'); | ||
Cesium.knockout.applyBindings(viewModel, toolbar); | ||
|
||
Cesium.knockout.getObservable(viewModel, 'enabled').subscribe( | ||
function(newValue) { | ||
viewer.scene.fog.enabled = newValue; | ||
} | ||
); | ||
|
||
Cesium.knockout.getObservable(viewModel, 'density').subscribe( | ||
function(newValue) { | ||
viewer.scene.fog.density = newValue; | ||
} | ||
); | ||
|
||
Cesium.knockout.getObservable(viewModel, 'sse').subscribe( | ||
function(newValue) { | ||
viewer.scene.fog.screenSpaceErrorFactor = newValue; | ||
} | ||
); | ||
|
||
viewModel.enabled = viewer.scene.fog.enabled; | ||
viewModel.density = viewer.scene.fog.density; | ||
viewModel.sse = viewer.scene.fog.screenSpaceErrorFactor; | ||
|
||
Sandcastle.addToolbarButton("Horizon high altitude", function() { | ||
viewer.camera.setView({ | ||
destination: new Cesium.Cartesian3(-2467730.5740817646, -4390507.315824514, 3906155.113316938), | ||
orientation: { | ||
heading: 4.492211521856625, | ||
pitch: -0.2687139437696304 | ||
} | ||
}); | ||
}); | ||
|
||
Sandcastle.addToolbarButton("Horizon low altitude", function() { | ||
viewer.camera.setView({ | ||
destination : new Cesium.Cartesian3(-734001.9511656855, -4214090.596769834, 4715898.125886317), | ||
orientation : { | ||
heading : 5.634257362559497, | ||
pitch : -0.019548505785381032 | ||
} | ||
}); | ||
}); | ||
|
||
viewer.scene.globe._surface._debug.enableDebugOutput = true; | ||
|
||
Sandcastle.addToolbarButton("Snap", function() { | ||
var container = document.getElementById("cesiumContainer"); | ||
var tmpH = container.style.height; | ||
var tmpW = container.style.width; | ||
|
||
container.style.height = "600px"; | ||
container.style.width = "800px"; | ||
|
||
viewer.resize(); | ||
viewer.render(); | ||
window.open(viewer.canvas.toDataURL("image/png")); | ||
container.style.height = tmpH; | ||
container.style.width = tmpW; | ||
viewer.resize(); | ||
viewer.render(); | ||
}); | ||
|
||
//Sandcastle_End | ||
Sandcastle.finishedLoading(); | ||
} | ||
if (typeof Cesium !== "undefined") { | ||
startup(Cesium); | ||
} else if (typeof require === "function") { | ||
require(["Cesium"], startup); | ||
} | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/*global define*/ | ||
define([ | ||
'../Core/Cartesian3', | ||
'../Core/defined', | ||
'../Core/Math', | ||
'./SceneMode' | ||
], function( | ||
Cartesian3, | ||
defined, | ||
CesiumMath, | ||
SceneMode) { | ||
"use strict"; | ||
|
||
/** | ||
* Blends the atmosphere to geometry far from the camera for horizon views. Allows for additional | ||
* performance improvements by rendering less geometry and dispatching less terrain requests. | ||
* | ||
* @alias Fog | ||
* @constructor | ||
*/ | ||
var Fog = function() { | ||
/** | ||
* <code>true</code> if fog is enabled, <code>false</code> otherwise. | ||
* @type {Boolean} | ||
* @default true | ||
*/ | ||
this.enabled = true; | ||
|
||
/** | ||
* A scalar that determines the density of the fog. Terrain that is in full fog are culled. | ||
* The density of the fog increases as this number approaches 1.0 and becomes less dense as it approaches zero. | ||
* The more dense the fog is, the more aggressively the terrain is culled. For example, if the camera is a height of | ||
* 1000.0m above the ellipsoid, increasing the value to 3.0e-3 will cause many tiles close to the viewer be culled. | ||
* Decreasing the value will push the fog further from the viewer, but decrease performance as more of the terrain is rendered. | ||
* @type {Number} | ||
* @default 2.0e-4 | ||
*/ | ||
this.density = 2.0e-4; | ||
/** | ||
* A factor used to increase the screen space error of terrain tiles when they are partially in fog. The effect is to reduce | ||
* the number of terrain tiles requested for rendering. If set to zero, the feature will be disabled. If the value is increased | ||
* for mountainous regions, less tiles will need to be requested, but the terrain meshes near the horizon may be a noticeably | ||
* lower resolution. If the value is increased in a relatively flat area, there will be little noticeable change on the horizon. | ||
* @type {Number} | ||
* @default 2.0 | ||
*/ | ||
this.screenSpaceErrorFactor = 2.0; | ||
}; | ||
|
||
// These values were found by sampling the density at certain views and finding at what point culled tiles impacted the view at the horizon. | ||
var heightsTable = [359.393, 800.749, 1275.6501, 2151.1192, 3141.7763, 4777.5198, 6281.2493, 12364.307, 15900.765, 49889.0549, 78026.8259, 99260.7344, 120036.3873, 151011.0158, 156091.1953, 203849.3112, 274866.9803, 319916.3149, 493552.0528, 628733.5874]; | ||
var densityTable = [2.0e-5, 2.0e-4, 1.0e-4, 7.0e-5, 5.0e-5, 4.0e-5, 3.0e-5, 1.9e-5, 1.0e-5, 8.5e-6, 6.2e-6, 5.8e-6, 5.3e-6, 5.2e-6, 5.1e-6, 4.2e-6, 4.0e-6, 3.4e-6, 2.6e-6, 2.2e-6]; | ||
|
||
// Scale densities by 1e6 to bring lowest value to ~1. Prevents divide by zero. | ||
for (var i = 0; i < densityTable.length; ++i) { | ||
densityTable[i] *= 1.0e6; | ||
} | ||
// Change range to [0, 1]. | ||
var tableStartDensity = densityTable[1]; | ||
var tableEndDensity = densityTable[densityTable.length - 1]; | ||
for (var j = 0; j < densityTable.length; ++j) { | ||
densityTable[j] = (densityTable[j] - tableEndDensity) / (tableStartDensity - tableEndDensity); | ||
} | ||
|
||
var tableLastIndex = 0; | ||
|
||
function findInterval(height) { | ||
var heights = heightsTable; | ||
var length = heights.length; | ||
|
||
if (height < heights[0]) { | ||
tableLastIndex = 0; | ||
return tableLastIndex; | ||
} else if (height > heights[length - 1]) { | ||
tableLastIndex = length - 2; | ||
return tableLastIndex; | ||
} | ||
|
||
// Take advantage of temporal coherence by checking current, next and previous intervals | ||
// for containment of time. | ||
if (height >= heights[tableLastIndex]) { | ||
if (tableLastIndex + 1 < length && height < heights[tableLastIndex + 1]) { | ||
return tableLastIndex; | ||
} else if (tableLastIndex + 2 < length && height < heights[tableLastIndex + 2]) { | ||
++tableLastIndex; | ||
return tableLastIndex; | ||
} | ||
} else if (tableLastIndex - 1 >= 0 && height >= heights[tableLastIndex - 1]) { | ||
--tableLastIndex; | ||
return tableLastIndex; | ||
} | ||
|
||
// The above failed so do a linear search. | ||
var i; | ||
for (i = 0; i < length - 2; ++i) { | ||
if (height >= heights[i] && height < heights[i + 1]) { | ||
break; | ||
} | ||
} | ||
|
||
tableLastIndex = i; | ||
return tableLastIndex; | ||
} | ||
|
||
var scratchPositionNormal = new Cartesian3(); | ||
|
||
Fog.prototype.update = function(frameState) { | ||
var enabled = frameState.fog.enabled = this.enabled; | ||
if (!enabled) { | ||
return; | ||
} | ||
|
||
var camera = frameState.camera; | ||
var positionCartographic = camera.positionCartographic; | ||
|
||
// Turn off fog in space. | ||
if (!defined(positionCartographic) || positionCartographic.height > 800000.0 || frameState.mode !== SceneMode.SCENE3D) { | ||
frameState.fog.enabled = false; | ||
return; | ||
} | ||
|
||
var height = positionCartographic.height; | ||
var i = findInterval(height); | ||
var t = CesiumMath.clamp((height - heightsTable[i]) / (heightsTable[i + 1] - heightsTable[i]), 0.0, 1.0); | ||
var density = CesiumMath.lerp(densityTable[i], densityTable[i + 1], t); | ||
|
||
// Again, scale value to be in the range of densityTable (prevents divide by zero) and change to new range. | ||
var startDensity = this.density * 1.0e6; | ||
var endDensity = (startDensity / tableStartDensity) * tableEndDensity; | ||
density = (density * (startDensity - endDensity)) * 1.0e-6; | ||
|
||
// Fade fog in as the camera tilts toward the horizon. | ||
var positionNormal = Cartesian3.normalize(camera.positionWC, scratchPositionNormal); | ||
var dot = CesiumMath.clamp(Cartesian3.dot(camera.directionWC, positionNormal), 0.0, 1.0); | ||
density *= 1.0 - dot; | ||
|
||
frameState.fog.density = density; | ||
frameState.fog.sse = this.screenSpaceErrorFactor; | ||
}; | ||
|
||
return Fog; | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The globe is not visible in the default view. Should we update this?