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

Geometric-error based point cloud attenuation and eye dome lighting #6069

Merged
merged 17 commits into from
Jan 30, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
<!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="Point Cloud Attenuation and Eye Dome Lighting example.">
<meta name="cesium-sandcastle-labels" content="3D Tiles">
<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);
#toolbar {
background: rgba(42, 42, 42, 0.8);
padding: 4px;
border-radius: 4px;
}
#toolbar input {
vertical-align: middle;
padding-top: 2px;
padding-bottom: 2px;
}
#toolbar .header {
font-weight: bold;
}
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>Loading...</h1></div>
<div id="toolbar">
<table><tbody>
<tr>
<td>Maximum Screen Space Error</td>
<td>
<input type="range" min="0.0" max="64.0" step="0.1" data-bind="value: maximumScreenSpaceError, valueUpdate: 'input'">
<input type="text" size="5" data-bind="value: maximumScreenSpaceError">
</td>
</tr>
<tr><td class="header">Attenuation</td></tr>
<tr>
<td>Geometric Error Scale</td>
<td>
<input type="range" min="0.0" max="2.0" step="0.1" data-bind="value: geometricErrorScale, valueUpdate: 'input'">
<input type="text" size="5" data-bind="value: geometricErrorScale">
</td>
</tr>
<tr>
<td>Maximum Attenuation</td>
<td>
<input type="range" min="0.0" max="64.0" step="1.0" data-bind="value: maximumAttenuation, valueUpdate: 'input'">
<input type="text" size="5" data-bind="value: maximumAttenuation">
</td>
</tr>
<tr>
<td>Base Resolution</td>
<td>
<input type="range" min="0.0" max="10.0" step="0.01" data-bind="value: baseResolution, valueUpdate: 'input'">
<input type="text" size="5" data-bind="value: baseResolution">
</td>
</tr>
<tr><td class="header">Eye Dome Lighting</td></tr>
<tr>
<td>Eye Dome Lighting Strength</td>
<td>
<input type="range" min="0.0" max="10.0" step="0.1" data-bind="value: eyeDomeLightingStrength, valueUpdate: 'input'">
<input type="text" size="5" data-bind="value: eyeDomeLightingStrength">
</td>
</tr>
<tr>
<td>Eye Dome Lighting Radius</td>
<td>
<input type="range" min="0.0" max="10.0" step="0.1" data-bind="value: eyeDomeLightingRadius, valueUpdate: 'input'">
<input type="text" size="5" data-bind="value: eyeDomeLightingRadius">
</td>
</tr>
</tbody></table>
</div>
<script id="cesium_sandcastle_script">
function startup(Cesium) {
'use strict';
//Sandcastle_Begin
var viewer = new Cesium.Viewer('cesiumContainer', {
baseLayerPicker : false
});

var scene = viewer.scene;

// Mt. St. Helens 3D Tileset generated from LAS provided by https://www.liblas.org/samples/
var url = 'https://beta.cesium.com/api/assets/3523?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzNDBlZDJhZS1jMDlmLTRiNWEtODhiMC1hMjExNGUzYmY5NzYiLCJpZCI6MjUsImlhdCI6MTQ4NTQ1OTAwMn0.PJQ7H5FsfSPBpQ2-_0jYNI4FnJBwuNpXnqfa7MZXFtc';
var tileset = scene.primitives.add(new Cesium.Cesium3DTileset({
url : url
}));

tileset.readyPromise.then(function() {
var boundingSphere = tileset.boundingSphere;
viewer.camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0.0, -1.0, boundingSphere.radius));
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
tileset.maximumScreenSpaceError = 16.0;
});

// The viewModel tracks the state of our mini application.
var viewModel = {
maximumScreenSpaceError : 16.0,
geometricErrorScale : 1.0,
maximumAttenuation : 0, // Equivalent to undefined
baseResolution : 0, // Equivalent to undefined
eyeDomeLightingStrength : 1.0,
eyeDomeLightingRadius : 1.0
};

function checkZero(newValue) {
var newValueFloat = parseFloat(newValue);
return (newValueFloat === 0.0) ? undefined : newValueFloat;
}

// 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, 'maximumScreenSpaceError').subscribe(
function(newValue) {
tileset.maximumScreenSpaceError = parseFloat(newValue);
}
);

Cesium.knockout.getObservable(viewModel, 'geometricErrorScale').subscribe(
function(newValue) {
tileset.pointAttenuationOptions.geometricErrorScale = parseFloat(newValue);
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure about the "options" suffix for pointAttenuationOptions.

Perhaps pointShading?

Copy link
Contributor

Choose a reason for hiding this comment

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

This will also make eyeDomeLightingStrength and eyeDomeLightingRadius make more sense since it doesn't seem - at least from the user's perspective - that they should be a property on an attenuation object.

}
);

Cesium.knockout.getObservable(viewModel, 'maximumAttenuation').subscribe(
function(newValue) {
tileset.pointAttenuationOptions.maximumAttenuation = checkZero(newValue);
}
);

Cesium.knockout.getObservable(viewModel, 'baseResolution').subscribe(
function(newValue) {
tileset.pointAttenuationOptions.baseResolution = checkZero(newValue);
}
);

Cesium.knockout.getObservable(viewModel, 'eyeDomeLightingStrength').subscribe(
function(newValue) {
tileset.pointAttenuationOptions.eyeDomeLightingStrength = parseFloat(newValue);
}
);

Cesium.knockout.getObservable(viewModel, 'eyeDomeLightingRadius').subscribe(
function(newValue) {
tileset.pointAttenuationOptions.eyeDomeLightingRadius = parseFloat(newValue);
}
);

Sandcastle.addToggleButton('Enable Attenuation', false, function(checked) {
tileset.pointAttenuationOptions.geometricErrorAttenuation = checked;
});

Sandcastle.addToggleButton('Enable Eye Dome Lighting', false, function(checked) {
tileset.pointAttenuationOptions.eyeDomeLighting = checked;
});
//Sandcastle_End
Sandcastle.finishedLoading();
}
if (typeof Cesium !== "undefined") {
startup(Cesium);
} else if (typeof require === "function") {
require(["Cesium"], startup);
}
</script>
</body>
</html>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Change Log
* Fixed globe materials when `Globe.enableLighting` was `false`. [#6042](https://github.com/AnalyticalGraphicsInc/cesium/issues/6042)
* Fixed shader compilation failure on pick when globe materials were enabled. [#6039](https://github.com/AnalyticalGraphicsInc/cesium/issues/6039)
* Fixed crash when `invertClassification` was enabled, the invert color had an alpha less than `1.0`, and the window was resized. [#6046](https://github.com/AnalyticalGraphicsInc/cesium/issues/6046)
* Added geometric-error-based point cloud attenuation and eye dome lighting for point clouds using additive refinement.

### 1.40 - 2017-12-01

Expand Down
96 changes: 58 additions & 38 deletions Source/Scene/Cesium3DTileset.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
define([
'../Core/Cartesian2',
'../Core/Cartesian3',
'../Core/Cartographic',
'../Core/Check',
'../Core/defaultValue',
'../Core/defined',
'../Core/defineProperties',
'../Core/destroyObject',
'../Core/DeveloperError',
'../Core/DoublyLinkedList',
'../Core/Event',
'../Core/getBaseUri',
'../Core/getExtensionFromUri',
'../Core/isDataUri',
'../Core/joinUrls',
'../Core/JulianDate',
'../Core/loadJson',
'../Core/ManagedArray',
'../Core/Math',
'../Core/Matrix4',
'../Core/RuntimeError',
'../Renderer/ClearCommand',
'../Renderer/Pass',
'../ThirdParty/when',
'./Axis',
'./Cesium3DTile',
'./Cesium3DTileColorBlendMode',
'./Cesium3DTileOptimizations',
'./Cesium3DTilesetStatistics',
'./Cesium3DTilesetTraversal',
'./Cesium3DTileStyleEngine',
'./LabelCollection',
'./SceneMode',
'./ShadowMode',
'./TileBoundingRegion',
'./TileBoundingSphere',
'./TileOrientedBoundingBox'
'../Core/Cartesian2',
'../Core/Cartesian3',
'../Core/Cartographic',
'../Core/Check',
'../Core/defaultValue',
'../Core/defined',
'../Core/defineProperties',
'../Core/destroyObject',
'../Core/DeveloperError',
'../Core/DoublyLinkedList',
'../Core/Event',
'../Core/getBaseUri',
'../Core/getExtensionFromUri',
'../Core/isDataUri',
'../Core/joinUrls',
'../Core/JulianDate',
'../Core/loadJson',
'../Core/ManagedArray',
'../Core/Math',
'../Core/Matrix4',
'../Core/RuntimeError',
'../Renderer/ClearCommand',
'../Renderer/Pass',
'../ThirdParty/when',
'./Axis',
'./Cesium3DTile',
'./Cesium3DTileColorBlendMode',
'./Cesium3DTileOptimizations',
'./Cesium3DTilesetStatistics',
'./Cesium3DTilesetTraversal',
'./Cesium3DTileStyleEngine',
'./LabelCollection',
'./PointAttenuationOptions',
'./PointCloudEyeDomeLighting',
'./SceneMode',
'./ShadowMode',
'./TileBoundingRegion',
'./TileBoundingSphere',
'./TileOrientedBoundingBox'
], function(
Cartesian2,
Cartesian3,
Expand Down Expand Up @@ -69,6 +71,8 @@ define([
Cesium3DTilesetTraversal,
Cesium3DTileStyleEngine,
LabelCollection,
PointAttenuationOptions,
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment.

Copy link
Contributor

Choose a reason for hiding this comment

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

Throughout.

PointCloudEyeDomeLighting,
SceneMode,
ShadowMode,
TileBoundingRegion,
Expand Down Expand Up @@ -112,6 +116,7 @@ define([
* @param {Boolean} [options.debugShowRenderingStatistics=false] For debugging only. When true, draws labels to indicate the number of commands, points, triangles and features for each tile.
* @param {Boolean} [options.debugShowMemoryUsage=false] For debugging only. When true, draws labels to indicate the texture and geometry memory in megabytes used by each tile.
* @param {Boolean} [options.debugShowUrl=false] For debugging only. When true, draws labels to indicate the url of each tile.
* @param {Object} [options.pointAttenuationOptions] Options for constructing a PointAttenuationOptions object to control point attenuation based on geometric error.
*
* @exception {DeveloperError} The tileset must be 3D Tiles version 0.0 or 1.0. See {@link https://github.com/AnalyticalGraphicsInc/3d-tiles#spec-status}
*
Expand Down Expand Up @@ -317,6 +322,14 @@ define([
*/
this.colorBlendAmount = 0.5;

/**
* Options for controlling point attenuation based on geometric error.
* @type {PointAttenuationOptions}
*/
this.pointAttenuationOptions = new PointAttenuationOptions(options.pointAttenuationOptions);

this._pointCloudEyeDomeLighting = new PointCloudEyeDomeLighting();

/**
* The event fired to indicate progress of loading new tiles. This event is fired when a new tile
* is requested, when a requested tile is finished downloading, and when a downloaded tile has been
Expand Down Expand Up @@ -1467,6 +1480,7 @@ define([
}
}
var lengthAfterUpdate = commandList.length;
var addedCommandsLength = lengthAfterUpdate - lengthBeforeUpdate;

tileset._backfaceCommands.trim();

Expand Down Expand Up @@ -1496,7 +1510,6 @@ define([
*/

var backfaceCommands = tileset._backfaceCommands.values;
var addedCommandsLength = (lengthAfterUpdate - lengthBeforeUpdate);
var backfaceCommandsLength = backfaceCommands.length;

commandList.length += backfaceCommandsLength;
Expand All @@ -1515,6 +1528,13 @@ define([
// Number of commands added by each update above
statistics.numberOfCommands = (commandList.length - numberOfInitialCommands);

// Only run EDL if simple attenuation is on
if (tileset.pointAttenuationOptions.geometricErrorAttenuation &&
tileset.pointAttenuationOptions.eyeDomeLighting &&
(addedCommandsLength > 0)) {
tileset._pointCloudEyeDomeLighting.update(frameState, numberOfInitialCommands, tileset);
}

if (tileset.debugShowGeometricError || tileset.debugShowRenderingStatistics || tileset.debugShowMemoryUsage || tileset.debugShowUrl) {
if (!defined(tileset._tileDebugLabels)) {
tileset._tileDebugLabels = new LabelCollection();
Expand Down
Loading