Skip to content

Commit

Permalink
Merge pull request #6621 from AnalyticalGraphicsInc/billboard-depth-test
Browse files Browse the repository at this point in the history
Fix billboards when clamped to ground with depthTestAgainstTerrain
  • Loading branch information
bagnell authored Jun 21, 2018
2 parents 21dafa7 + 4c3da3b commit 0a23971
Show file tree
Hide file tree
Showing 6 changed files with 339 additions and 90 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Change Log
* Fixed a bug with Draco encoded i3dm tiles, and loading two Draco models with the same url. [#6668](https://github.com/AnalyticalGraphicsInc/cesium/issues/6668)
* Fixed terrain clipping when the camera was close to flat terrain and was using logarithmic depth. [#6701](https://github.com/AnalyticalGraphicsInc/cesium/pull/6701)
* Fixed KML bug that constantly requested the same image if it failed to load. [#6710](https://github.com/AnalyticalGraphicsInc/cesium/pull/6710)
* Improved billboard and label rendering so they no longer sink into terrain when clamped to ground. [#6621](https://github.com/AnalyticalGraphicsInc/cesium/pull/6621)
* Fixed an issue where KMLs containing a `colorMode` of `random` could return the exact same color on successive calls to `Color.fromRandom()`.

### 1.46.1 - 2018-06-01
Expand Down
6 changes: 5 additions & 1 deletion Source/Scene/Billboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ define([
this._imageWidth = undefined;
this._imageHeight = undefined;

this._labelDimensions = undefined;
this._labelHorizontalOrigin = undefined;

var image = options.image;
var imageId = options.imageId;
if (defined(image)) {
Expand Down Expand Up @@ -210,7 +213,8 @@ define([
var PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX = Billboard.PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX = 13;
var DISTANCE_DISPLAY_CONDITION = Billboard.DISTANCE_DISPLAY_CONDITION = 14;
var DISABLE_DEPTH_DISTANCE = Billboard.DISABLE_DEPTH_DISTANCE = 15;
Billboard.NUMBER_OF_PROPERTIES = 16;
Billboard.TEXTURE_COORDINATE_BOUNDS = 16;
Billboard.NUMBER_OF_PROPERTIES = 17;

function makeDirty(billboard, propertyChanged) {
var billboardCollection = billboard._billboardCollection;
Expand Down
164 changes: 140 additions & 24 deletions Source/Scene/BillboardCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ define([
var SCALE_BY_DISTANCE_INDEX = Billboard.SCALE_BY_DISTANCE_INDEX;
var TRANSLUCENCY_BY_DISTANCE_INDEX = Billboard.TRANSLUCENCY_BY_DISTANCE_INDEX;
var PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX = Billboard.PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX;
var DISTANCE_DISPLAY_CONDITION_INDEX = Billboard.DISTANCE_DISPLAY_CONDITION_INDEX;
var DISTANCE_DISPLAY_CONDITION_INDEX = Billboard.DISTANCE_DISPLAY_CONDITION;
var DISABLE_DEPTH_DISTANCE = Billboard.DISABLE_DEPTH_DISTANCE;
var TEXTURE_COORDINATE_BOUNDS = Billboard.TEXTURE_COORDINATE_BOUNDS;
var NUMBER_OF_PROPERTIES = Billboard.NUMBER_OF_PROPERTIES;

var attributeLocations;
Expand All @@ -99,8 +100,9 @@ define([
eyeOffset : 5, // 4 bytes free
scaleByDistance : 6,
pixelOffsetScaleByDistance : 7,
distanceDisplayConditionAndDisableDepth : 8,
a_batchId : 9
compressedAttribute3 : 8,
textureCoordinateBounds : 9,
a_batchId : 10
};

var attributeLocationsInstanced = {
Expand All @@ -113,8 +115,9 @@ define([
eyeOffset : 6, // texture range in w
scaleByDistance : 7,
pixelOffsetScaleByDistance : 8,
distanceDisplayConditionAndDisableDepth : 9,
a_batchId : 10
compressedAttribute3 : 9,
textureCoordinateBounds : 10,
a_batchId : 11
};

/**
Expand Down Expand Up @@ -208,6 +211,9 @@ define([
this._shaderDisableDepthDistance = false;
this._compiledShaderDisableDepthDistance = false;

this._shaderClampToGround = false;
this._compiledShaderClampToGround = false;

this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES);

this._maxSize = 0.0;
Expand Down Expand Up @@ -302,7 +308,8 @@ define([
BufferUsage.STATIC_DRAW, // SCALE_BY_DISTANCE_INDEX
BufferUsage.STATIC_DRAW, // TRANSLUCENCY_BY_DISTANCE_INDEX
BufferUsage.STATIC_DRAW, // PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX
BufferUsage.STATIC_DRAW // DISTANCE_DISPLAY_CONDITION_INDEX
BufferUsage.STATIC_DRAW, // DISTANCE_DISPLAY_CONDITION_INDEX
BufferUsage.STATIC_DRAW // TEXTURE_COORDINATE_BOUNDS
];

this._highlightColor = Color.clone(Color.WHITE); // Only used by Vector3DTilePoints
Expand Down Expand Up @@ -732,10 +739,15 @@ define([
componentDatatype : ComponentDatatype.FLOAT,
usage : buffersUsage[PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX]
}, {
index : attributeLocations.distanceDisplayConditionAndDisableDepth,
componentsPerAttribute : 3,
index : attributeLocations.compressedAttribute3,
componentsPerAttribute : 4,
componentDatatype : ComponentDatatype.FLOAT,
usage : buffersUsage[DISTANCE_DISPLAY_CONDITION_INDEX]
}, {
index : attributeLocations.textureCoordinateBounds,
componentsPerAttribute : 4,
componentDatatype : ComponentDatatype.FLOAT,
usage : buffersUsage[TEXTURE_COORDINATE_BOUNDS]
}];

// Instancing requires one non-instanced attribute.
Expand Down Expand Up @@ -818,6 +830,7 @@ define([
var UPPER_BOUND = 32768.0; // 2^15

var LEFT_SHIFT16 = 65536.0; // 2^16
var LEFT_SHIFT12 = 4096.0; // 2^12
var LEFT_SHIFT8 = 256.0; // 2^8
var LEFT_SHIFT7 = 128.0;
var LEFT_SHIFT5 = 32.0;
Expand Down Expand Up @@ -1020,6 +1033,9 @@ define([
var dimensions = billboardCollection._textureAtlas.texture.dimensions;
var imageHeight = Math.round(defaultValue(billboard.height, dimensions.y * height));
billboardCollection._maxSize = Math.max(billboardCollection._maxSize, imageHeight);
var labelHorizontalOrigin = defaultValue(billboard._labelHorizontalOrigin, -2);
labelHorizontalOrigin += 2;
var compressed3 = imageHeight * LEFT_SHIFT2 + labelHorizontalOrigin;

var red = Color.floatToByte(color.red);
var green = Color.floatToByte(color.green);
Expand All @@ -1036,13 +1052,13 @@ define([

if (billboardCollection._instanced) {
i = billboard._index;
writer(i, compressed0, compressed1, compressed2, imageHeight);
writer(i, compressed0, compressed1, compressed2, compressed3);
} else {
i = billboard._index * 4;
writer(i + 0, compressed0, compressed1, compressed2, imageHeight);
writer(i + 1, compressed0, compressed1, compressed2, imageHeight);
writer(i + 2, compressed0, compressed1, compressed2, imageHeight);
writer(i + 3, compressed0, compressed1, compressed2, imageHeight);
writer(i + 0, compressed0, compressed1, compressed2, compressed3);
writer(i + 1, compressed0, compressed1, compressed2, compressed3);
writer(i + 2, compressed0, compressed1, compressed2, compressed3);
writer(i + 3, compressed0, compressed1, compressed2, compressed3);
}
}

Expand Down Expand Up @@ -1158,9 +1174,9 @@ define([
}
}

function writeDistanceDisplayConditionAndDepthDisable(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) {
function writeCompressedAttribute3(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) {
var i;
var writer = vafWriters[attributeLocations.distanceDisplayConditionAndDisableDepth];
var writer = vafWriters[attributeLocations.compressedAttribute3];
var near = 0.0;
var far = Number.MAX_VALUE;

Expand All @@ -1176,6 +1192,10 @@ define([
}

var disableDepthTestDistance = billboard.disableDepthTestDistance;
if (billboard.heightReference === HeightReference.CLAMP_TO_GROUND && disableDepthTestDistance === 0.0 && billboardCollection._scene.context.depthTexture) {
disableDepthTestDistance = 2000.0;
}

disableDepthTestDistance *= disableDepthTestDistance;
if (disableDepthTestDistance > 0.0) {
billboardCollection._shaderDisableDepthDistance = true;
Expand All @@ -1184,15 +1204,89 @@ define([
}
}

var imageHeight;
var imageWidth;

if (!defined(billboard._labelDimensions)) {
var height = 0;
var width = 0;
var index = billboard._imageIndex;
if (index !== -1) {
var imageRectangle = textureAtlasCoordinates[index];

//>>includeStart('debug', pragmas.debug);
if (!defined(imageRectangle)) {
throw new DeveloperError('Invalid billboard image index: ' + index);
}
//>>includeEnd('debug');

height = imageRectangle.height;
width = imageRectangle.width;
}

imageHeight = Math.round(defaultValue(billboard.height, billboardCollection._textureAtlas.texture.dimensions.y * height));

var textureWidth = billboardCollection._textureAtlas.texture.width;
imageWidth = Math.round(defaultValue(billboard.width, textureWidth * width));
} else {
imageWidth = billboard._labelDimensions.x;
imageHeight = billboard._labelDimensions.y;
}

var w = Math.floor(CesiumMath.clamp(imageWidth, 0.0, LEFT_SHIFT12));
var h = Math.floor(CesiumMath.clamp(imageHeight, 0.0, LEFT_SHIFT12));
var dimensions = w * LEFT_SHIFT12 + h;

if (billboardCollection._instanced) {
i = billboard._index;
writer(i, near, far, disableDepthTestDistance, dimensions);
} else {
i = billboard._index * 4;
writer(i + 0, near, far, disableDepthTestDistance, dimensions);
writer(i + 1, near, far, disableDepthTestDistance, dimensions);
writer(i + 2, near, far, disableDepthTestDistance, dimensions);
writer(i + 3, near, far, disableDepthTestDistance, dimensions);
}
}

function writeTextureCoordinateBounds(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) {
if (billboard.heightReference === HeightReference.CLAMP_TO_GROUND) {
billboardCollection._shaderClampToGround = billboardCollection._scene.context.depthTexture;
}
var i;
var writer = vafWriters[attributeLocations.textureCoordinateBounds];

var minX = 0;
var minY = 0;
var width = 0;
var height = 0;
var index = billboard._imageIndex;
if (index !== -1) {
var imageRectangle = textureAtlasCoordinates[index];

//>>includeStart('debug', pragmas.debug);
if (!defined(imageRectangle)) {
throw new DeveloperError('Invalid billboard image index: ' + index);
}
//>>includeEnd('debug');

minX = imageRectangle.x;
minY = imageRectangle.y;
width = imageRectangle.width;
height = imageRectangle.height;
}
var maxX = minX + width;
var maxY = minY + height;

if (billboardCollection._instanced) {
i = billboard._index;
writer(i, near, far, disableDepthTestDistance);
writer(i, minX, minY, maxX, maxY);
} else {
i = billboard._index * 4;
writer(i + 0, near, far, disableDepthTestDistance);
writer(i + 1, near, far, disableDepthTestDistance);
writer(i + 2, near, far, disableDepthTestDistance);
writer(i + 3, near, far, disableDepthTestDistance);
writer(i + 0, minX, minY, maxX, maxY);
writer(i + 1, minX, minY, maxX, maxY);
writer(i + 2, minX, minY, maxX, maxY);
writer(i + 3, minX, minY, maxX, maxY);
}
}

Expand Down Expand Up @@ -1225,7 +1319,8 @@ define([
writeEyeOffset(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard);
writeScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard);
writePixelOffsetScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard);
writeDistanceDisplayConditionAndDepthDisable(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard);
writeCompressedAttribute3(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard);
writeTextureCoordinateBounds(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard);
writeBatchId(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard);
}

Expand Down Expand Up @@ -1421,8 +1516,12 @@ define([
writers.push(writePixelOffsetScaleByDistance);
}

if (properties[DISTANCE_DISPLAY_CONDITION_INDEX] || properties[DISABLE_DEPTH_DISTANCE]) {
writers.push(writeDistanceDisplayConditionAndDepthDisable);
if (properties[DISTANCE_DISPLAY_CONDITION_INDEX] || properties[DISABLE_DEPTH_DISTANCE] || properties[IMAGE_INDEX_INDEX] || properties[POSITION_INDEX]) {
writers.push(writeCompressedAttribute3);
}

if (properties[IMAGE_INDEX_INDEX] || properties[POSITION_INDEX]) {
writers.push(writeTextureCoordinateBounds);
}

var numWriters = writers.length;
Expand Down Expand Up @@ -1540,7 +1639,8 @@ define([
(this._shaderTranslucencyByDistance !== this._compiledShaderTranslucencyByDistance) ||
(this._shaderPixelOffsetScaleByDistance !== this._compiledShaderPixelOffsetScaleByDistance) ||
(this._shaderDistanceDisplayCondition !== this._compiledShaderDistanceDisplayCondition) ||
(this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistance)) {
(this._shaderDisableDepthDistance !== this._compiledShaderDisableDepthDistance) ||
(this._shaderClampToGround !== this._compiledShaderClampToGround)) {

vsSource = BillboardCollectionVS;
fsSource = BillboardCollectionFS;
Expand Down Expand Up @@ -1580,6 +1680,9 @@ define([
if (this._shaderDisableDepthDistance) {
vs.defines.push('DISABLE_DEPTH_DISTANCE');
}
if (this._shaderClampToGround) {
vs.defines.push('CLAMP_TO_GROUND');
}

var vectorFragDefine = defined(this._batchTable) ? 'VECTOR_TILE' : '';

Expand All @@ -1588,6 +1691,9 @@ define([
defines : ['OPAQUE', vectorFragDefine],
sources : [fsSource]
});
if (this._shaderClampToGround) {
fs.defines.push('CLAMP_TO_GROUND');
}
this._sp = ShaderProgram.replaceCache({
context : context,
shaderProgram : this._sp,
Expand All @@ -1600,6 +1706,9 @@ define([
defines : ['TRANSLUCENT', vectorFragDefine],
sources : [fsSource]
});
if (this._shaderClampToGround) {
fs.defines.push('CLAMP_TO_GROUND');
}
this._spTranslucent = ShaderProgram.replaceCache({
context : context,
shaderProgram : this._spTranslucent,
Expand All @@ -1614,6 +1723,9 @@ define([
defines : [vectorFragDefine],
sources : [fsSource]
});
if (this._shaderClampToGround) {
fs.defines.push('CLAMP_TO_GROUND');
}
this._sp = ShaderProgram.replaceCache({
context : context,
shaderProgram : this._sp,
Expand All @@ -1628,6 +1740,9 @@ define([
defines : [vectorFragDefine],
sources : [fsSource]
});
if (this._shaderClampToGround) {
fs.defines.push('CLAMP_TO_GROUND');
}
this._spTranslucent = ShaderProgram.replaceCache({
context : context,
shaderProgram : this._spTranslucent,
Expand All @@ -1644,6 +1759,7 @@ define([
this._compiledShaderPixelOffsetScaleByDistance = this._shaderPixelOffsetScaleByDistance;
this._compiledShaderDistanceDisplayCondition = this._shaderDistanceDisplayCondition;
this._compiledShaderDisableDepthDistance = this._shaderDisableDepthDistance;
this._compiledShaderClampToGround = this._shaderClampToGround;
}

var commandList = frameState.commandList;
Expand Down
Loading

0 comments on commit 0a23971

Please sign in to comment.