-
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
Add Material Support to Globe #5919
Changes from 34 commits
24ff46b
4e3ae37
6c2d17c
ce71917
a2152cc
5139bad
29d4ae2
11325f2
9b7f7d9
60c0121
46d1a17
3ba02db
cbcaea1
cff763d
5c619a9
7493d7c
5e4aab6
c045a6c
8f4a8a1
e8f9b04
8ca9ac9
0697c45
83dedf0
a5fd43f
e469dd7
560caa5
cc77f3a
8c30e90
5bd104f
a71d73a
b42d079
0264ab1
8eb3bd4
217ce3a
fc88b02
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,283 @@ | ||
<!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="Apply materials to the globe."> | ||
<meta name="cesium-sandcastle-labels" content="Showcases"> | ||
<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"> | ||
if(typeof require === "function") { | ||
require.config({ | ||
baseUrl : '../../../Source', | ||
waitSeconds : 120 | ||
}); | ||
} | ||
</script> | ||
</head> | ||
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html"> | ||
<style> | ||
@import url(../templates/bucket.css); | ||
.demo-container { | ||
background-color: #303336; | ||
border-radius: 5px; | ||
padding: 5px; | ||
margin: 5px 3px; | ||
} | ||
.demo-container input { | ||
vertical-align: middle; | ||
margin-top: 0; | ||
} | ||
</style> | ||
<div id="cesiumContainer" class="fullSize"></div> | ||
<div id="loadingOverlay"><h1>Loading...</h1></div> | ||
<div id="toolbar"> | ||
<div id="zoomButtons"></div> | ||
<div class="demo-container"> | ||
<label><input type="radio" name="shadingMaterials" value="none" data-bind="checked: selectedShading"> No shading</label> | ||
<label><input type="radio" name="shadingMaterials" value="elevation" data-bind="checked: selectedShading"> Elevation</label> | ||
<label><input type="radio" name="shadingMaterials" value="slope" data-bind="checked: selectedShading"> Slope</label> | ||
</div> | ||
<div class="demo-container"> | ||
<div> | ||
<label><input type="checkbox" data-bind="checked: enableContour">Enable Contour Lines</label> | ||
</div> | ||
<div> | ||
Spacing <input style="width: 136px" type="range" min="1.0" max="500.0" step="1.0" data-bind="value: contourSpacing, valueUpdate: 'input', enable: enableContour"> <span data-bind="text: contourSpacing"></span>m | ||
</div> | ||
<div> | ||
Line Width <input style="width: 125px" type="range" min="1.0" max="10.0" step="1.0" data-bind="value: contourWidth, valueUpdate: 'input', enable: enableContour"> <span data-bind="text: contourWidth"></span>px | ||
</div> | ||
<div> | ||
<button type="button" data-bind="click: changeColor, enable: enableContour">Change color</button> | ||
</div> | ||
</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 : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles', | ||
requestWaterMask : true, | ||
requestVertexNormals : true | ||
}); | ||
viewer.scene.globe.enableLighting = true; | ||
|
||
function getElevationContourMaterial() { | ||
// Creates a composite material with both elevation shading and contour lines | ||
return new Cesium.Material({ | ||
fabric: { | ||
type: 'ElevationColorContour', | ||
materials: { | ||
contourMaterial: { | ||
type: 'ElevationContour' | ||
}, | ||
elevationRampMaterial: { | ||
type: 'ElevationRamp' | ||
} | ||
}, | ||
components: { | ||
diffuse: 'contourMaterial.alpha == 0.0 ? elevationRampMaterial.diffuse : contourMaterial.diffuse', | ||
alpha: 'max(contourMaterial.alpha, elevationRampMaterial.alpha)' | ||
} | ||
}, | ||
translucent: false | ||
}); | ||
} | ||
|
||
function getSlopeContourMaterial() { | ||
// Creates a composite material with both slope shading and contour lines | ||
return new Cesium.Material({ | ||
fabric: { | ||
type: 'SlopeColorContour', | ||
materials: { | ||
contourMaterial: { | ||
type: 'ElevationContour' | ||
}, | ||
slopeRampMaterial: { | ||
type: 'SlopeRamp' | ||
} | ||
}, | ||
components: { | ||
diffuse: 'contourMaterial.alpha == 0.0 ? slopeRampMaterial.diffuse : contourMaterial.diffuse', | ||
alpha: 'max(contourMaterial.alpha, slopeRampMaterial.alpha)' | ||
} | ||
}, | ||
translucent: false | ||
}); | ||
} | ||
|
||
var elevationRamp = [0.0, 0.045, 0.1, 0.15, 0.37, 0.54, 1.0]; | ||
var slopeRamp = [0.0, 0.29, 0.5, Math.sqrt(2)/2, 0.87, 0.91, 1.0]; | ||
function getColorRamp(selectedShading) { | ||
var ramp = document.createElement('canvas'); | ||
ramp.width = 100; | ||
ramp.height = 1; | ||
var ctx = ramp.getContext('2d'); | ||
|
||
var values = selectedShading === 'elevation' ? elevationRamp : slopeRamp; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @hpinkos can the color ramp be tweaked to be a bit less subtle for the default view? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or change the default view. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed the default view to be of the Himalayas |
||
|
||
var grd = ctx.createLinearGradient(0, 0, 100, 0); | ||
grd.addColorStop(values[0], '#000000'); //black | ||
grd.addColorStop(values[1], '#2747E0'); //blue | ||
grd.addColorStop(values[2], '#D33B7D'); //pink | ||
grd.addColorStop(values[3], '#D33038'); //red | ||
grd.addColorStop(values[4], '#FF9742'); //orange | ||
grd.addColorStop(values[5], '#ffd700'); //yellow | ||
grd.addColorStop(values[6], '#ffffff'); //white | ||
|
||
ctx.fillStyle = grd; | ||
ctx.fillRect(0, 0, 100, 1); | ||
|
||
return ramp; | ||
} | ||
|
||
var minHeight = -414.0; // approximate dead sea elevation | ||
var maxHeight = 8777.0; // approximate everest elevation | ||
var contourColor = Cesium.Color.RED.clone(); | ||
var contourUniforms = {}; | ||
var shadingUniforms = {}; | ||
|
||
// The viewModel tracks the state of our mini application. | ||
var viewModel = { | ||
enableContour: false, | ||
contourSpacing: 150.0, | ||
contourWidth: 2.0, | ||
selectedShading: 'none', | ||
changeColor: function() { | ||
contourUniforms.color = Cesium.Color.fromRandom({alpha: 1.0}, contourColor); | ||
} | ||
}; | ||
|
||
// 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); | ||
|
||
function updateMaterial() { | ||
var hasContour = viewModel.enableContour; | ||
var selectedShading = viewModel.selectedShading; | ||
var globe = viewer.scene.globe; | ||
var material; | ||
if (hasContour) { | ||
if (selectedShading === 'elevation') { | ||
material = getElevationContourMaterial(); | ||
shadingUniforms = material.materials.elevationRampMaterial.uniforms; | ||
shadingUniforms.minHeight = minHeight; | ||
shadingUniforms.maxHeight = maxHeight; | ||
contourUniforms = material.materials.contourMaterial.uniforms; | ||
} else if (selectedShading === 'slope') { | ||
material = getSlopeContourMaterial(); | ||
shadingUniforms = material.materials.slopeRampMaterial.uniforms; | ||
contourUniforms = material.materials.contourMaterial.uniforms; | ||
} else { | ||
material = Cesium.Material.fromType('ElevationContour'); | ||
contourUniforms = material.uniforms; | ||
} | ||
contourUniforms.width = viewModel.contourWidth; | ||
contourUniforms.spacing = viewModel.contourSpacing; | ||
contourUniforms.color = contourColor; | ||
} else if (selectedShading === 'elevation') { | ||
material = Cesium.Material.fromType('ElevationRamp'); | ||
shadingUniforms = material.uniforms; | ||
shadingUniforms.minHeight = minHeight; | ||
shadingUniforms.maxHeight = maxHeight; | ||
} else if (selectedShading === 'slope') { | ||
material = Cesium.Material.fromType('SlopeRamp'); | ||
shadingUniforms = material.uniforms; | ||
} | ||
if (selectedShading !== 'none') { | ||
shadingUniforms.image = getColorRamp(selectedShading); | ||
} | ||
|
||
globe.material = material; | ||
} | ||
|
||
Cesium.knockout.getObservable(viewModel, 'enableContour').subscribe(function(newValue) { | ||
updateMaterial(); | ||
}); | ||
|
||
Cesium.knockout.getObservable(viewModel, 'contourWidth').subscribe(function(newValue) { | ||
contourUniforms.width = parseFloat(newValue); | ||
}); | ||
|
||
Cesium.knockout.getObservable(viewModel, 'contourSpacing').subscribe(function(newValue) { | ||
contourUniforms.spacing = parseFloat(newValue); | ||
}); | ||
|
||
Cesium.knockout.getObservable(viewModel, 'selectedShading').subscribe(function(value) { | ||
updateMaterial(); | ||
}); | ||
|
||
Sandcastle.addToolbarMenu([{ | ||
text : 'Himalayas', | ||
onselect : function() { | ||
viewer.camera.setView({ | ||
destination: new Cesium.Cartesian3(322100.7492728492, 5917960.047024654, 3077602.646977297), | ||
orientation: { | ||
heading: 5.988151498702285, | ||
pitch: -1.5614542839414822, | ||
roll: 0 | ||
} | ||
}); | ||
viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601('2017-09-22T04:00:00Z'); | ||
} | ||
}, { | ||
text : 'Half Dome', | ||
onselect : function() { | ||
viewer.camera.setView({ | ||
destination: new Cesium.Cartesian3(-2495709.521843174, -4391600.804712465, 3884463.7192916023), | ||
orientation: { | ||
heading: 1.7183056487769202, | ||
pitch: -0.06460370548034144, | ||
roll: 0.0079181631783527 | ||
} | ||
}); | ||
viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601('2017-09-22T18:00:00Z'); | ||
} | ||
}, { | ||
text : 'Vancouver', | ||
onselect : function() { | ||
viewer.camera.setView({ | ||
destination: new Cesium.Cartesian3(-2301222.367751603, -3485269.915771613, 4812080.961755785), | ||
orientation: { | ||
heading: 0.11355958593902571, | ||
pitch: -0.260011078090858, | ||
roll: 0.00039019018274721873 | ||
} | ||
}); | ||
viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601('2017-09-22T18:00:00Z'); | ||
} | ||
}, { | ||
text : 'Mount Everest', | ||
onselect : function() { | ||
viewer.camera.setView({ | ||
destination: new Cesium.Cartesian3(282157.6960889096, 5638892.465594703, 2978736.186473513), | ||
orientation: { | ||
heading: 4.747266966349747, | ||
pitch: -0.2206998858596192, | ||
roll: 6.280340554587955 | ||
} | ||
}); | ||
viewer.clockViewModel.currentTime = Cesium.JulianDate.fromIso8601('2017-09-22T04:00:00Z'); | ||
} | ||
}], 'zoomButtons'); | ||
|
||
//Sandcastle_End | ||
Sandcastle.finishedLoading(); | ||
} | ||
if (typeof Cesium !== "undefined") { | ||
startup(Cesium); | ||
} else if (typeof require === "function") { | ||
require(["Cesium"], startup); | ||
} | ||
</script> | ||
</body> | ||
</html> |
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 demo works better without lighting. Related to my comment below, we should be able to get the normals properly without this being set.
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 color ramps are better with lighting so you can see the terrain features. The terrain all blends together without the shadows.
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 lighting does look fine most of the time, it's mainly when it's completely dark that it's hard to see what's going on.
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.
I disagree. For example, there are some random Appalachian mountains with and without lighting:
Having the lighting enabled makes a big difference.
To make sure the lighting always looks good with the preset views, we can add a line to set the clock time:
viewer.clockViewModel.currentTime = Cesium.JulianDate.fromDate(new Date(2017, 8, 22, 0, 0, 0));
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.
Ok yeah, setting the clock is good. I should have been clearer, my main issue was that whenever I would open the demo it would be night at Everest and just hard to see anything.
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.
I've pushed a change to set the clock time.