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

Generate outlines 2 #75

Draft
wants to merge 19 commits into
base: terriajs
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 10 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
4 changes: 4 additions & 0 deletions Source/Scene/Batched3DModel3DTileContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,8 @@ function initialize(content, arrayBuffer, byteOffset) {
sphericalHarmonicCoefficients: tileset.sphericalHarmonicCoefficients,
specularEnvironmentMaps: tileset.specularEnvironmentMaps,
backFaceCulling: tileset.backFaceCulling,
outlineGenerationMode: tileset.outlineGenerationMode,
outlineGenerationMinimumAngle: tileset.outlineGenerationMinimumAngle
});
content._model.readyPromise.then(function (model) {
model.activeAnimations.addAll({
Expand Down Expand Up @@ -541,6 +543,8 @@ Batched3DModel3DTileContent.prototype.update = function (tileset, frameState) {
this._model.sphericalHarmonicCoefficients = this._tileset.sphericalHarmonicCoefficients;
this._model.specularEnvironmentMaps = this._tileset.specularEnvironmentMaps;
this._model.backFaceCulling = this._tileset.backFaceCulling;
this._model.outlineGenerationMode = this._tileset.outlineGenerationMode;
this._model.outlineGenerationMinimumAngle = this._tileset.outlineGenerationMinimumAngle;
this._model.debugWireframe = this._tileset.debugWireframe;

// Update clipping planes
Expand Down
38 changes: 38 additions & 0 deletions Source/Scene/Cesium3DTileset.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import StencilConstants from "./StencilConstants.js";
import TileBoundingRegion from "./TileBoundingRegion.js";
import TileBoundingSphere from "./TileBoundingSphere.js";
import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js";
import ModelOutlineGenerationMode from "./ModelOutlineGenerationMode.js";

/**
* A {@link https://github.com/CesiumGS/3d-tiles/tree/master/specification|3D Tiles tileset},
Expand Down Expand Up @@ -90,6 +91,8 @@ import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js";
* @param {Cartesian3[]} [options.sphericalHarmonicCoefficients] The third order spherical harmonic coefficients used for the diffuse color of image-based lighting.
* @param {String} [options.specularEnvironmentMaps] A URL to a KTX file that contains a cube map of the specular lighting and the convoluted specular mipmaps.
* @param {Boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the glTF material's doubleSided property; when false, back face culling is disabled.
* @param {ModelOutlineGenerationMode} [options.outlineGenerationMode] Determines whether outlines should be generated for this model.
* @param {Number} [options.outlineGenerationMinimumAngle] If generating outlines for this model, determines what the minimum angle between the normals of two faces has to be for the edge between them to receive an outline.
* @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 @@ -760,6 +763,41 @@ function Cesium3DTileset(options) {
*/
this.backFaceCulling = defaultValue(options.backFaceCulling, true);

/**
* Determines whether outlines should be generated for this tileset.
*
* @type {ModelOutlineGenerationMode}
*
* @default ModelOutlineGenerationMode.USE_GLTF_SETTINGS
*
* @see ModelOutlineGenerator
*/
this.outlineGenerationMode = defaultValue(
options.outlineGenerationMode,
ModelOutlineGenerationMode.USE_GLTF_SETTINGS
);

/**
* If generating outlines for this model, determines what the minimum angle
* between the normals of two faces has to be for the edge between them to
* receive an outline.
*
* This follows @see Cesium3DTileset.outlineGenerationMode — if outlineGenerationMode is
* OFF or USE_GLTF_SETTINGS, this value will be ignored. If undefined, it will
* use the value from the glTF if it exists, or otherwise the default value
* specified by ModelOutlineGenerator.
*
* @type {number}
*
* @default undefined
*
* @see ModelOutlineGenerator
*/
this.outlineGenerationMinimumAngle = defaultValue(
options.outlineGenerationMinimumAngle,
undefined
);

/**
* This property is for debugging only; it is not optimized for production use.
* <p>
Expand Down
79 changes: 58 additions & 21 deletions Source/Scene/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import processModelMaterialsCommon from "./processModelMaterialsCommon.js";
import processPbrMaterials from "./processPbrMaterials.js";
import SceneMode from "./SceneMode.js";
import ShadowMode from "./ShadowMode.js";
import ModelOutlineGenerationMode from "./ModelOutlineGenerationMode.js";

var boundingSphereCartesian3Scratch = new Cartesian3();

Expand Down Expand Up @@ -209,6 +210,8 @@ var uriToGuid = {};
* @param {Number} [options.colorBlendAmount=0.5] Value used to determine 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.
* @param {Color} [options.silhouetteColor=Color.RED] The silhouette color. If more than 256 models have silhouettes enabled, there is a small chance that overlapping models will have minor artifacts.
* @param {Number} [options.silhouetteSize=0.0] The size of the silhouette in pixels.
* @param {ModelOutlineGenerationMode} [options.outlineGenerationMode] Determines whether outlines should be generated for this model.
* @param {Number} [options.outlineGenerationMinimumAngle] If generating outlines for this model, determines what the minimum angle between the normals of two faces has to be for the edge between them to receive an outline.
* @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the model.
* @param {Boolean} [options.dequantizeInShader=true] Determines if a {@link https://github.com/google/draco|Draco} encoded model is dequantized on the GPU. This decreases total memory usage for encoded models.
* @param {Cartesian2} [options.imageBasedLightingFactor=Cartesian2(1.0, 1.0)] Scales diffuse and specular image-based lighting from the earth, sky, atmosphere and star skybox.
Expand Down Expand Up @@ -317,6 +320,41 @@ function Model(options) {
*/
this.silhouetteSize = defaultValue(options.silhouetteSize, 0.0);

/**
* Determines whether outlines should be generated for this model.
*
* @type {ModelOutlineGenerationMode}
*
* @default ModelOutlineGenerationMode.USE_GLTF_SETTINGS
*
* @see ModelOutlineGenerator
*/
this.outlineGenerationMode = defaultValue(
options.outlineGenerationMode,
ModelOutlineGenerationMode.USE_GLTF_SETTINGS
);

/**
* If generating outlines for this model, determines what the minimum angle
* between the normals of two faces has to be for the edge between them to
* receive an outline.
*
* This follows @see Model.outlineGenerationMode — if outlineGenerationMode is
* OFF or USE_GLTF_SETTINGS, this value will be ignored. If undefined, it will
* use the value from the glTF if it exists, or otherwise the default value
* specified by ModelOutlineGenerator.
*
* @type {number}
*
* @default undefined
*
* @see ModelOutlineGenerator
*/
this.outlineGenerationMinimumAngle = defaultValue(
options.outlineGenerationMinimumAngle,
undefined
);

/**
* The 4x4 transformation matrix that transforms the model from model to world coordinates.
* When this is the identity matrix, the model is drawn in world coordinates, i.e., Earth's WGS84 coordinates.
Expand Down Expand Up @@ -2454,16 +2492,15 @@ function createProgram(programToCreate, model, context) {
var drawVS = modifyShader(vs, programId, model._vertexShaderLoaded);
var drawFS = modifyShader(fs, programId, model._fragmentShaderLoaded);


if (isOutline) {
drawFS = drawFS.replace(
"czm_writeLogDepth();",
" czm_writeLogDepth();\n" +
"#if defined(LOG_DEPTH) && !defined(DISABLE_LOG_DEPTH_FRAGMENT_WRITE)\n" +
" gl_FragDepthEXT -= 5e-5;\n" +
"#endif"
);
}
if (isOutline) {
drawFS = drawFS.replace(
"czm_writeLogDepth();",
" czm_writeLogDepth();\n" +
"#if defined(LOG_DEPTH) && !defined(DISABLE_LOG_DEPTH_FRAGMENT_WRITE)\n" +
" gl_FragDepthEXT -= 5e-5;\n" +
"#endif"
);
}
if (!defined(model._uniformMapLoaded)) {
drawFS = "uniform vec4 czm_pickColor;\n" + drawFS;
}
Expand Down Expand Up @@ -2582,17 +2619,16 @@ function recreateProgram(programToCreate, model, context) {
var drawVS = modifyShader(vs, programId, model._vertexShaderLoaded);
var drawFS = modifyShader(finalFS, programId, model._fragmentShaderLoaded);


var isOutline = program.isOutline;
if (isOutline) {
drawFS = drawFS.replace(
"czm_writeLogDepth();",
" czm_writeLogDepth();\n" +
"#if defined(LOG_DEPTH) && !defined(DISABLE_LOG_DEPTH_FRAGMENT_WRITE)\n" +
" gl_FragDepthEXT -= 5e-5;\n" +
"#endif"
);
}
var isOutline = program.isOutline;
if (isOutline) {
drawFS = drawFS.replace(
"czm_writeLogDepth();",
" czm_writeLogDepth();\n" +
"#if defined(LOG_DEPTH) && !defined(DISABLE_LOG_DEPTH_FRAGMENT_WRITE)\n" +
" gl_FragDepthEXT -= 5e-5;\n" +
"#endif"
);
}
if (!defined(model._uniformMapLoaded)) {
drawFS = "uniform vec4 czm_pickColor;\n" + drawFS;
}
Expand Down Expand Up @@ -5276,6 +5312,7 @@ Model.prototype.update = function (frameState) {

var options = {
addBatchIdToGeneratedShaders: this._addBatchIdToGeneratedShaders,
outlineGenerationMode: this.outlineGenerationMode,
};

processModelMaterialsCommon(gltf, options);
Expand Down
18 changes: 18 additions & 0 deletions Source/Scene/ModelOutlineGenerationMode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Defines different modes for automatically generating outlines for models.
*
* USE_GLTF_SETTINGS will follow whatever is set in the glTF underlying the model.
* OFF forces outlines to not be generated, overriding what is specified in the model.
* ON forces outlines to be generated, overriding what is specified in the model.
*
* @enum {Number}
*
* @see Model.generateOutlines
*/
var ModelOutlineGenerationMode = {
OFF: 0,
ON: 1,
USE_GLTF_SETTINGS: 2,
};

export default Object.freeze(ModelOutlineGenerationMode);
Loading