Skip to content

Commit

Permalink
Merge pull request #10018 from CesiumGS/multi-feature-ids
Browse files Browse the repository at this point in the history
Handle multiple feature ID sets in `ModelExperimental`
  • Loading branch information
lilleyse committed Jan 28, 2022
2 parents a275c75 + 2a61e4f commit 9855a6d
Show file tree
Hide file tree
Showing 47 changed files with 2,069 additions and 1,093 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
const scene = viewer.scene;

const tileset = new Cesium.Cesium3DTileset({
url: Cesium.IonResource.fromAssetId(666297),
url: Cesium.IonResource.fromAssetId(775877),
});

const translation = new Cesium.Cartesian3(
Expand Down Expand Up @@ -107,8 +107,7 @@
"const float TOTAL_FEATURES = 12.0;",
"",
"void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {",
" // NOTE: This is exposing internal details of the shader. It would be better if this was added to fsInput somewhere...",
" float featureId = floor(texture2D(FEATURE_ID_TEXTURE, FEATURE_ID_TEXCOORD).FEATURE_ID_CHANNEL * 255.0 + 0.5);",
" float featureId = fsInput.featureIds.featureId_0;",
"",
" if (featureId == WINDOW || featureId == SKYLIGHT) {",
" material.alpha = 0.4;",
Expand Down Expand Up @@ -136,8 +135,7 @@
"const float TRAFFIC_LIGHT = 11.0;",
"",
"void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {",
" // NOTE: This is exposing internal details of the shader. It would be better if this was added to fsInput somewhere...",
" float featureId = floor(texture2D(FEATURE_ID_TEXTURE, FEATURE_ID_TEXCOORD).FEATURE_ID_CHANNEL * 255.0 + 0.5);",
" float featureId = fsInput.featureIds.featureId_0;",
"",
" if (featureId == CLOCK) {",
" // Shiny brass",
Expand Down Expand Up @@ -183,8 +181,7 @@
fragmentShaderText: [
"const float NOTHING_SELECTED = 12.0;",
"void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {",
" // NOTE: This is exposing internal details of the shader. It would be better if this was added to fsInput somewhere...",
" float featureId = floor(texture2D(FEATURE_ID_TEXTURE, FEATURE_ID_TEXCOORD).FEATURE_ID_CHANNEL * 255.0 + 0.5);",
" float featureId = fsInput.featureIds.featureId_0;",
"",
" if (u_selectedFeature < NOTHING_SELECTED && featureId == u_selectedFeature) {",
" material.specular = vec3(1.00, 0.85, 0.57);",
Expand All @@ -194,13 +191,48 @@
].join("\n"),
});

const multipleFeatureIdsShader = new Cesium.CustomShader({
uniforms: {
u_selectedFeature: {
type: Cesium.UniformType.FLOAT,
value: NOTHING_SELECTED,
},
},
lightingModel: Cesium.LightingModel.UNLIT,
fragmentShaderText: [
"const float IDS0_WINDOW = 0.0;",
"const float IDS1_FACADE = 2.0;",
"const float IDS1_ROOF = 3.0;",
"const vec3 PURPLE = vec3(0.5, 0.0, 1.0);",
"const vec3 YELLOW = vec3(1.0, 1.0, 0.0);",
"const vec3 NO_TINT = vec3(1.0);",
"",
"void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {",
" float featureId0 = fsInput.featureIds.featureId_0; // fine features",
" float featureId1 = fsInput.featureIds.featureId_1; // coarse features",
"",
" // use both feature ID sets to determine where the features are",
" float isWindow = float(featureId0 == IDS0_WINDOW);",
" float isFacade = float(featureId1 == IDS1_FACADE);",
" float isRoof = float(featureId1 == IDS1_ROOF);",
"",
" // Tint the roof windows yellow and facade windows purple",
" vec3 tint = NO_TINT;",
" tint = mix(tint, YELLOW, isWindow * isRoof);",
" tint = mix(tint, PURPLE, isWindow * isFacade);",
" material.diffuse *= tint;",
"}",
].join("\n"),
});

// Demo Functions =====================================================================

function defaults() {
tileset.style = undefined;
tileset.customShader = unlitShader;
tileset.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.HIGHLIGHT;
tileset.colorBlendAmount = 0.5;
tileset.featureIdIndex = 0;
}

const showPhotogrammetry = defaults;
Expand All @@ -211,6 +243,12 @@
tileset.colorBlendMode = Cesium.Cesium3DTileColorBlendMode.MIX;
}

function showAlternativeClassification() {
showClassification();
// This dataset has a second feature ID texture.
tileset.featureIdIndex = 1;
}

function translucentWindows() {
defaults();
tileset.customShader = translucentWindowsShader;
Expand All @@ -226,6 +264,11 @@
tileset.customShader = selectFeatureShader;
}

function multipleFeatureIds() {
defaults();
tileset.customShader = multipleFeatureIdsShader;
}

// Pick Handlers ======================================================================

// HTML overlay for showing feature name on mouseover
Expand Down Expand Up @@ -304,6 +347,10 @@
text: "Show Classification",
onselect: showClassification,
},
{
text: "Show Alternative Classification",
onselect: showAlternativeClassification,
},
{
text: "Translucent Windows",
onselect: translucentWindows,
Expand All @@ -316,6 +363,10 @@
text: "Golden Touch",
onselect: goldenTouch,
},
{
text: "Multiple Feature ID Sets",
onselect: multipleFeatureIds,
},
];
Sandcastle.addToolbarMenu(demos);

Expand Down
3 changes: 1 addition & 2 deletions Apps/Sandcastle/gallery/3D Tiles Next S2 Globe.html
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@
fragmentShaderText: [
"void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)",
"{",
" // NOTE: this is exposing internal details of the shader.",
" float featureId = floor(texture2D(FEATURE_ID_TEXTURE, FEATURE_ID_TEXCOORD).FEATURE_ID_CHANNEL * 255.0 + 0.5);",
" float featureId = fsInput.featureIds.featureId_0;",
" // Use cartesian coordinates but scale to be roughly [-1, 1]",
" vec3 positionWC = fsInput.attributes.positionWC / 6.3e6;",
" if (featureId == 60.0)",
Expand Down
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

##### Additions :tada:

- Feature IDs for styling and picking in `ModelExperimental` can now be selected via `(tileset|model).featureIdIndex` and `(tileset|model).instanceFeatureIdIndex`. [#10018](https://github.com/CesiumGS/cesium/pull/10018)
- Added support for all types of feature IDs in `CustomShader`. [#10018](https://github.com/CesiumGS/cesium/pull/10018)
- Added getters `Cesium3DTileFeature.featureId` and `ModelFeature.featureId` so the feature ID or batch ID can be accessed from a picked feature. [#10022](https://github.com/CesiumGS/cesium/pull/10022)
- Added `I3dmLoader` to transcode .i3dm to `ModelExperimental`. [#9968](https://github.com/CesiumGS/cesium/pull/9968)
- Added `PntsLoader` to transcode .pnts to `ModelExperimental`. [#9978](https://github.com/CesiumGS/cesium/pull/9978)
Expand Down
23 changes: 23 additions & 0 deletions Source/Scene/Cesium3DTileset.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js";
* @param {Boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed.
* @param {Boolean} [options.vectorClassificationOnly=false] Indicates that only the tileset's vector tiles should be used for classification.
* @param {Boolean} [options.vectorKeepDecodedPositions=false] Whether vector tiles should keep decoded positions in memory. This is used with {@link Cesium3DTileFeature.getPolylinePositions}.
* @param {Number} [options.featureIdIndex=0] The index into the list of primitive feature IDs used for picking and styling. For EXT_feature_metadata, feature ID attributes are listed before feature ID textures. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority.
* @param {Number} [options.instanceFeatureIdIndex=0] The index into the list of instance feature IDs used for picking and styling. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority.
* @param {String} [options.debugHeatmapTilePropertyName] The tile variable to colorize as a heatmap. All rendered tiles will be colorized relative to each other's specified variable value.
* @param {Boolean} [options.debugFreezeFrame=false] For debugging only. Determines if only the tiles from last frame should be used for rendering.
* @param {Boolean} [options.debugColorizeTiles=false] For debugging only. When true, assigns a random color to each tile.
Expand Down Expand Up @@ -963,6 +965,27 @@ function Cesium3DTileset(options) {
ExperimentalFeatures.enableModelExperimental
);

/**
* The index into the list of primitive feature IDs used for picking and
* styling. For EXT_feature_metadata, feature ID attributes are listed before
* feature ID textures. If both per-primitive and per-instance feature IDs are
* present, the instance feature IDs take priority.
*
* @type {Number}
* @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy.
*/
this.featureIdIndex = defaultValue(options.featureIdIndex, 0);

/**
* The index into the list of instance feature IDs used for picking and
* styling. If both per-primitive and per-instance feature IDs are present,
* the instance feature IDs take priority.
*
* @type {Number}
* @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy.
*/
this.instanceFeatureIdIndex = defaultValue(options.instanceFeatureIdIndex, 0);

this._schemaLoader = undefined;

const that = this;
Expand Down
Loading

0 comments on commit 9855a6d

Please sign in to comment.