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

Support for model outlining #4314

Merged
merged 42 commits into from
Dec 14, 2016
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
9f58e9c
Working on drawing highlighted models
jasonbeverage Aug 31, 2016
de364e9
Changed demo to be able to modify the highlight size
jasonbeverage Aug 31, 2016
cea7291
Better outlining algorithm
jasonbeverage Aug 31, 2016
c72757b
Documentation and slight tweaks
jasonbeverage Sep 1, 2016
b8a2c44
Changed Cartesian4 to Color
jasonbeverage Sep 1, 2016
6a532d1
Making vertex shader for highlighting more generic, works with animat…
jasonbeverage Sep 1, 2016
2362111
Terrible code for looking up the projection matrix uniform name
jasonbeverage Sep 1, 2016
aa759ac
Merge branch 'master' into modelhighlight
jasonbeverage Sep 8, 2016
590bafc
Spelling and added a highlightCommand2D
jasonbeverage Sep 8, 2016
73d9fb2
Comment
jasonbeverage Sep 9, 2016
116bdfc
Moved outline example to it's own sandcastle example and reverted the…
jasonbeverage Sep 9, 2016
fa23733
Fix jshint issues
jasonbeverage Sep 13, 2016
751fbda
Added new getUniformNameForSemantic function
jasonbeverage Sep 13, 2016
f41bb6e
Changed the highlightSize parameter to be in pixels instead of clip s…
jasonbeverage Sep 13, 2016
36f046d
Simplified highlight shader just using cesium builtins
jasonbeverage Sep 13, 2016
d247a65
Merge branch 'master' into modelhighlight
jasonbeverage Sep 13, 2016
32d74a1
Merge branch 'master' into modelhighlight
jasonbeverage Oct 17, 2016
af86c9a
Defaulting highlight to true in 3D Models Outline example. Changed h…
jasonbeverage Oct 17, 2016
817da19
Changed highlightColor default to default constructed color and highl…
jasonbeverage Oct 17, 2016
a492379
Changed hilightSize default to 2.0 in Model.js and highlightColor to …
jasonbeverage Oct 17, 2016
20a7149
Removed extra whitespace
jasonbeverage Oct 17, 2016
d98e0ea
Not setting face in highlightRS, just enabled: false
jasonbeverage Oct 17, 2016
aa62d4d
Whitespace
jasonbeverage Oct 17, 2016
c2a8ed1
Whitespace
jasonbeverage Oct 17, 2016
df36205
Enabling ALPHA_BLEND blending on highlight state
jasonbeverage Oct 17, 2016
fa3c2e9
Added opacity slider to 3D Models Outline demo.
jasonbeverage Oct 17, 2016
1bcce58
Explicitly requesting a stencil buffer in the 3D Models Outline demo …
jasonbeverage Oct 17, 2016
fee0674
Only rendering highlight commands if stencilBits is greater than 0, o…
jasonbeverage Oct 17, 2016
508b14d
ModelGraphicSpec tests for model highlighting
jasonbeverage Oct 17, 2016
1c33371
Model testing
jasonbeverage Oct 17, 2016
bd77f27
Merge branch 'master' into modelhighlight
lilleyse Dec 6, 2016
5f93bf1
Reorganized silhouetting
lilleyse Dec 6, 2016
93d4e68
Prevent divide-by-zero during unpremultiply
lilleyse Dec 7, 2016
d7ae242
Issue clear command
lilleyse Dec 7, 2016
5e1e9cf
More accurate translucencly check
lilleyse Dec 8, 2016
246dc83
Fix spec
lilleyse Dec 8, 2016
60caefa
Change order of stencilReference
lilleyse Dec 8, 2016
11fc0da
Doc and stencil clear after ground pass
lilleyse Dec 12, 2016
cb35414
No longer hardcoding v_normal
lilleyse Dec 12, 2016
95d024e
Updated CHANGES.md
lilleyse Dec 12, 2016
077e225
Added tests
lilleyse Dec 12, 2016
7a399f2
Merge branch 'master' into modelhighlight
lilleyse Dec 13, 2016
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
64 changes: 56 additions & 8 deletions Apps/Sandcastle/gallery/3D Models Coloring.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,15 @@
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 class="header">Model Color</td></tr>
<tr>
<td>Mode</td>
<td><select data-bind="options: colorBlendModes, value: colorBlendMode"></select></td>
Expand All @@ -56,6 +60,25 @@
<input type="text" size="5" data-bind="value: colorBlendAmount, enable: colorBlendAmountEnabled">
</td>
</tr>
<tr><td class="header">Model Silhouette</td></tr>
<tr>
<td>Color</td>
<td><select data-bind="options: silhouetteColors, value: silhouetteColor"></select></td>
</tr>
<tr>
<td>Alpha</td>
<td>
<input type="range" min="0.0" max="1.0" step="0.01" data-bind="value: silhouetteAlpha, valueUpdate: 'input'">
<input type="text" size="5" data-bind="value: silhouetteAlpha">
</td>
</tr>
<tr>
<td>Size</td>
<td>
<input type="range" min="0.0" max="10.0" step="0.01" data-bind="value: silhouetteSize, valueUpdate: 'input'">
<input type="text" size="5" data-bind="value: silhouetteSize">
</td>
</tr>
</tbody></table>
</div>
<script id="cesium_sandcastle_script">
Expand All @@ -74,8 +97,9 @@
return Cesium.ColorBlendMode[colorBlendMode.toUpperCase()];
}

function getColor(color) {
return Cesium.Color[color.toUpperCase()];
function getColor(colorName, alpha) {
var color = Cesium.Color[colorName.toUpperCase()];
return Cesium.Color.fromAlpha(color, parseFloat(alpha));
}

// The viewModel tracks the state of our mini application.
Expand All @@ -86,7 +110,11 @@
colorBlendMode : 'Highlight',
colorBlendModes : ['Highlight', 'Replace', 'Mix'],
colorBlendAmount : 0.5,
colorBlendAmountEnabled : false
colorBlendAmountEnabled : false,
silhouetteColor : 'Red',
silhouetteColors : ['Red', 'Green', 'Blue', 'Yellow', 'Gray'],
silhouetteAlpha : 1.0,
silhouetteSize : 2.0
};

// Convert the viewModel members into knockout observables.
Expand All @@ -98,13 +126,13 @@

Cesium.knockout.getObservable(viewModel, 'color').subscribe(
function(newValue) {
entity.model.color = Cesium.Color.fromAlpha(getColor(newValue), viewModel.alpha);
entity.model.color = getColor(newValue, viewModel.alpha);
}
);

Cesium.knockout.getObservable(viewModel, 'alpha').subscribe(
function(newValue) {
entity.model.color = Cesium.Color.fromAlpha(getColor(viewModel.color), newValue);
entity.model.color = getColor(viewModel.color, newValue);
}
);

Expand All @@ -118,7 +146,25 @@

Cesium.knockout.getObservable(viewModel, 'colorBlendAmount').subscribe(
function(newValue) {
entity.model.colorBlendAmount = newValue;
entity.model.colorBlendAmount = parseFloat(newValue);
}
);

Cesium.knockout.getObservable(viewModel, 'silhouetteColor').subscribe(
function(newValue) {
entity.model.silhouetteColor = getColor(newValue, viewModel.silhouetteAlpha);
}
);

Cesium.knockout.getObservable(viewModel, 'silhouetteAlpha').subscribe(
function(newValue) {
entity.model.silhouetteColor = getColor(viewModel.silhouetteColor, newValue);
}
);

Cesium.knockout.getObservable(viewModel, 'silhouetteSize').subscribe(
function(newValue) {
entity.model.silhouetteSize = parseFloat(newValue);
}
);

Expand All @@ -140,9 +186,11 @@
uri : url,
minimumPixelSize : 128,
maximumScale : 20000,
color : Cesium.Color.fromAlpha(getColor(viewModel.color), viewModel.alpha),
color : getColor(viewModel.color, viewModel.alpha),
colorBlendMode : getColorBlendMode(viewModel.colorBlendMode),
colorBlendAmount : viewModel.colorBlendAmount
colorBlendAmount : parseFloat(viewModel.colorBlendAmount),
silhouetteColor : getColor(viewModel.silhouetteColor, viewModel.silhouetteAlpha),
silhouetteSize : parseFloat(viewModel.silhouetteSize)
}
});
viewer.trackedEntity = entity;
Expand Down
2 changes: 2 additions & 0 deletions Source/DataSources/CzmlDataSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -1417,6 +1417,8 @@ define([
processPacketData(Boolean, model, 'runAnimations', modelData.runAnimations, interval, sourceUri, entityCollection);
processPacketData(ShadowMode, model, 'shadows', modelData.shadows, interval, sourceUri, entityCollection);
processPacketData(HeightReference, model, 'heightReference', modelData.heightReference, interval, sourceUri, entityCollection);
processPacketData(Color, model, 'silhouetteColor', modelData.silhouetteColor, interval, sourceUri, entityCollection);
processPacketData(Number, model, 'silhouetteSize', modelData.silhouetteSize, interval, sourceUri, entityCollection);
processPacketData(Color, model, 'color', modelData.color, interval, sourceUri, entityCollection);
processPacketData(ColorBlendMode, model, 'colorBlendMode', modelData.colorBlendMode, interval, sourceUri, entityCollection);
processPacketData(Number, model, 'colorBlendAmount', modelData.colorBlendAmount, interval, sourceUri, entityCollection);
Expand Down
26 changes: 26 additions & 0 deletions Source/DataSources/ModelGraphics.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ define([
* @param {Property} [options.shadows=ShadowMode.ENABLED] An enum Property specifying whether the model casts or receives shadows from each light source.
* @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to.
* @param {Property} [options.distanceDisplayCondition] A Property specifying at what distance from the camera that this model will be displayed.
* @param {Property} [options.silhouetteColor=Color.RED] A Property specifying the {@link Color} of the silhouette.
* @param {Property} [options.silhouetteSize=0.0] A numeric Property specifying the size of the silhouette in pixels.
* @param {Property} [options.color=Color.WHITE] A Property specifying the {@link Color} that blends with the model's rendered color.
* @param {Property} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] An enum Property specifying how the color blends with the model.
* @param {Property} [options.colorBlendAmount=0.5] A numeric Property specifying the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two.
Expand Down Expand Up @@ -80,6 +82,10 @@ define([
this._heightReferenceSubscription = undefined;
this._distanceDisplayCondition = undefined;
this._distanceDisplayConditionSubscription = undefined;
this._silhouetteColor = undefined;
this._silhouetteColorSubscription = undefined;
this._silhouetteSize = undefined;
this._silhouetteSizeSubscription = undefined;
this._color = undefined;
this._colorSubscription = undefined;
this._colorBlendMode = undefined;
Expand Down Expand Up @@ -197,6 +203,22 @@ define([
*/
distanceDisplayCondition : createPropertyDescriptor('distanceDisplayCondition'),

/**
* Gets or sets the Property specifying the {@link Color} of the silhouette.
* @memberof ModelGraphics.prototype
* @type {Property}
* @default Color.RED
*/
silhouetteColor: createPropertyDescriptor('silhouetteColor'),

/**
* Gets or sets the numeric Property specifying the size of the silhouette in pixels.
* @memberof ModelGraphics.prototype
* @type {Property}
* @default 0.0
*/
silhouetteSize : createPropertyDescriptor('silhouetteSize'),

/**
* Gets or sets the Property specifying the {@link Color} that blends with the model's rendered color.
* @memberof ModelGraphics.prototype
Expand Down Expand Up @@ -245,6 +267,8 @@ define([
result.nodeTransformations = this.nodeTransformations;
result.heightReference = this._heightReference;
result.distanceDisplayCondition = this.distanceDisplayCondition;
result.silhouetteColor = this.silhouetteColor;
result.silhouetteSize = this.silhouetteSize;
result.color = this.color;
result.colorBlendMode = this.colorBlendMode;
result.colorBlendAmount = this.colorBlendAmount;
Expand Down Expand Up @@ -275,6 +299,8 @@ define([
this.runAnimations = defaultValue(this.runAnimations, source.runAnimations);
this.heightReference = defaultValue(this.heightReference, source.heightReference);
this.distanceDisplayCondition = defaultValue(this.distanceDisplayCondition, source.distanceDisplayCondition);
this.silhouetteColor = defaultValue(this.silhouetteColor, source.silhouetteColor);
this.silhouetteSize = defaultValue(this.silhouetteSize, source.silhouetteSize);
this.color = defaultValue(this.color, source.color);
this.colorBlendMode = defaultValue(this.colorBlendMode, source.colorBlendMode);
this.colorBlendAmount = defaultValue(this.colorBlendAmount, source.colorBlendAmount);
Expand Down
4 changes: 4 additions & 0 deletions Source/DataSources/ModelVisualizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ define([
var defaultIncrementallyLoadTextures = true;
var defaultShadows = ShadowMode.ENABLED;
var defaultHeightReference = HeightReference.NONE;
var defaultSilhouetteColor = Color.RED;
var defaultSilhouetteSize = 0.0;
var defaultColor = Color.WHITE;
var defaultColorBlendMode = ColorBlendMode.HIGHLIGHT;
var defaultColorBlendAmount = 0.5;
Expand Down Expand Up @@ -147,6 +149,8 @@ define([
model.shadows = Property.getValueOrDefault(modelGraphics._shadows, time, defaultShadows);
model.heightReference = Property.getValueOrDefault(modelGraphics._heightReference, time, defaultHeightReference);
model.distanceDisplayCondition = Property.getValueOrUndefined(modelGraphics._distanceDisplayCondition, time);
model.silhouetteColor = Property.getValueOrDefault(modelGraphics.silhouetteColor, time, defaultSilhouetteColor);
model.silhouetteSize = Property.getValueOrDefault(modelGraphics.silhouetteSize, time, defaultSilhouetteSize);
model.color = Property.getValueOrDefault(modelGraphics._color, time, defaultColor, color);
model.colorBlendMode = Property.getValueOrDefault(modelGraphics._colorBlendMode, time, defaultColorBlendMode);
model.colorBlendAmount = Property.getValueOrDefault(modelGraphics._colorBlendAmount, time, defaultColorBlendAmount);
Expand Down
13 changes: 13 additions & 0 deletions Source/Renderer/Context.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ define([

// Override select WebGL defaults
webglOptions.alpha = defaultValue(webglOptions.alpha, false); // WebGL default is true
webglOptions.stencil = defaultValue(webglOptions.stencil, true); // WebGL default is false

var defaultToWebgl2 = false;
var webgl2Supported = (typeof WebGL2RenderingContext !== 'undefined');
Expand Down Expand Up @@ -507,6 +508,18 @@ define([
}
},

/**
* <code>true</code> if the WebGL context supports stencil buffers.
* Stencil buffers are not supported by all systems.
* @memberof Context.prototype
* @type {Boolean}
*/
stencilBuffer : {
get : function() {
return this._stencilBits >= 8;
Copy link
Contributor

Choose a reason for hiding this comment

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

I've never seen less than 8 (or anything other than 8), but are you sure this is the right test?

Copy link
Contributor

Choose a reason for hiding this comment

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

When the context is created without stencil : true, gl.getParameter(gl.STENCIL_BITS); returns 0 so this test should be fine.

Copy link
Contributor

Choose a reason for hiding this comment

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

I get that it is fine in practice (we think), but are you sure that > 0 isn't more correct according to the spec?

Copy link
Contributor

Choose a reason for hiding this comment

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

According to the spec 8 bits is the minimum: https://www.khronos.org/registry/webgl/specs/latest/1.0/#2.2

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, thanks for checking.

}
},

/**
* <code>true</code> if the WebGL context supports antialiasing. By default
* antialiasing is requested, but it is not supported by all systems.
Expand Down
2 changes: 1 addition & 1 deletion Source/Renderer/RenderState.js
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ define([
// Section 6.8 of the WebGL spec requires the reference and masks to be the same for
// front- and back-face tests. This call prevents invalid operation errors when calling
// stencilFuncSeparate on Firefox. Perhaps they should delay validation to avoid requiring this.
gl.stencilFunc(stencilTest.frontFunction, stencilTest.reference, stencilTest.mask);
gl.stencilFunc(frontFunction, reference, mask);
Copy link
Contributor

Choose a reason for hiding this comment

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

Good eye.

gl.stencilFuncSeparate(gl.BACK, backFunction, reference, mask);
gl.stencilFuncSeparate(gl.FRONT, frontFunction, reference, mask);

Expand Down
3 changes: 3 additions & 0 deletions Source/Scene/ColorBlendMode.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ define([
MIX : 2
};

/**
* @private
*/
ColorBlendMode.getColorBlend = function(colorBlendMode, colorBlendAmount) {
if (colorBlendMode === ColorBlendMode.HIGHLIGHT) {
return 0.0;
Expand Down
2 changes: 1 addition & 1 deletion Source/Scene/GroundPrimitive.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ define([
* @returns {Boolean} <code>true</code> if GroundPrimitives are supported; otherwise, returns <code>false</code>
*/
GroundPrimitive.isSupported = function(scene) {
return scene.context.fragmentDepth;
return scene.context.fragmentDepth && scene.context.stencilBuffer;
};

GroundPrimitive._defaultMaxTerrainHeight = 9000.0;
Expand Down
Loading