Skip to content

Commit

Permalink
Better billboard depth test against terrain for clamped to ground
Browse files Browse the repository at this point in the history
  • Loading branch information
hpinkos committed Jun 12, 2018
1 parent f13dc97 commit da3593d
Show file tree
Hide file tree
Showing 5 changed files with 272 additions and 14 deletions.
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,8 @@ define([
this._imageWidth = undefined;
this._imageHeight = undefined;

this._labelDimensions = undefined;

var image = options.image;
var imageId = options.imageId;
if (defined(image)) {
Expand Down Expand Up @@ -210,7 +212,9 @@ 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_OFFSET = 16;
Billboard.DIMENSIONS = 17;
Billboard.NUMBER_OF_PROPERTIES = 18;

function makeDirty(billboard, propertyChanged) {
var billboardCollection = billboard._billboardCollection;
Expand Down
154 changes: 148 additions & 6 deletions Source/Scene/BillboardCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ 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_OFFSET = Billboard.TEXTURE_OFFSET;
var DIMENSIONS = Billboard.DIMENSIONS;
var NUMBER_OF_PROPERTIES = Billboard.NUMBER_OF_PROPERTIES;

var attributeLocations;
Expand All @@ -100,7 +102,9 @@ define([
scaleByDistance : 6,
pixelOffsetScaleByDistance : 7,
distanceDisplayConditionAndDisableDepth : 8,
a_batchId : 9
textureOffset : 9,
dimensions : 10,
a_batchId : 11
};

var attributeLocationsInstanced = {
Expand All @@ -114,7 +118,9 @@ define([
scaleByDistance : 7,
pixelOffsetScaleByDistance : 8,
distanceDisplayConditionAndDisableDepth : 9,
a_batchId : 10
textureOffset : 10,
dimensions : 11,
a_batchId : 12
};

/**
Expand Down Expand Up @@ -208,6 +214,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 +311,9 @@ 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_OFFSET
BufferUsage.STATIC_DRAW // DIMENSIONS
];

this._highlightColor = Color.clone(Color.WHITE); // Only used by Vector3DTilePoints
Expand Down Expand Up @@ -736,6 +747,16 @@ define([
componentsPerAttribute : 3,
componentDatatype : ComponentDatatype.FLOAT,
usage : buffersUsage[DISTANCE_DISPLAY_CONDITION_INDEX]
}, {
index : attributeLocations.textureOffset,
componentsPerAttribute : 4,
componentDatatype : ComponentDatatype.FLOAT,
usage : buffersUsage[TEXTURE_OFFSET]
}, {
index : attributeLocations.dimensions,
componentsPerAttribute : 2,
componentDatatype : ComponentDatatype.FLOAT,
usage : buffersUsage[DIMENSIONS]
}];

// Instancing requires one non-instanced attribute.
Expand Down Expand Up @@ -1176,6 +1197,10 @@ define([
}

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

disableDepthTestDistance *= disableDepthTestDistance;
if (disableDepthTestDistance > 0.0) {
billboardCollection._shaderDisableDepthDistance = true;
Expand All @@ -1196,6 +1221,96 @@ define([
}
}

function writeTextureOffset(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) {
if (billboard.heightReference === HeightReference.CLAMP_TO_GROUND) {
billboardCollection._shaderClampToGround = true;
}
var i;
var writer = vafWriters[attributeLocations.textureOffset];

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, minX, minY, maxX, maxY);
} else {
i = billboard._index * 4;
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);
}
}

function writeDimensions(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) {
if (billboard.heightReference === HeightReference.CLAMP_TO_GROUND) {
billboardCollection._shaderClampToGround = true;
}
var i;
var writer = vafWriters[attributeLocations.dimensions];

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;
}

var dimensions = billboardCollection._textureAtlas.texture.dimensions;
imageHeight = Math.round(defaultValue(billboard.height, 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;
}

if (billboardCollection._instanced) {
i = billboard._index;
writer(i, imageWidth, imageHeight);
} else {
i = billboard._index * 2;
writer(i + 0, imageWidth, imageHeight);
writer(i + 1, imageWidth, imageHeight);
writer(i + 2, imageWidth, imageHeight);
writer(i + 3, imageWidth, imageHeight);
}
}

function writeBatchId(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) {
if (!defined(billboardCollection._batchTable)) {
return;
Expand Down Expand Up @@ -1226,6 +1341,8 @@ define([
writeScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard);
writePixelOffsetScaleByDistance(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard);
writeDistanceDisplayConditionAndDepthDisable(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard);
writeTextureOffset(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard);
writeDimensions(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard);
writeBatchId(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard);
}

Expand Down Expand Up @@ -1421,10 +1538,18 @@ define([
writers.push(writePixelOffsetScaleByDistance);
}

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

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

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

var numWriters = writers.length;
vafWriters = this._vaf.writers;

Expand Down Expand Up @@ -1540,7 +1665,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 +1706,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 +1717,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 +1732,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 +1749,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 +1766,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 +1785,7 @@ define([
this._compiledShaderPixelOffsetScaleByDistance = this._shaderPixelOffsetScaleByDistance;
this._compiledShaderDistanceDisplayCondition = this._shaderDistanceDisplayCondition;
this._compiledShaderDisableDepthDistance = this._shaderDisableDepthDistance;
this._compiledShaderClampToGround = this._shaderClampToGround;
}

var commandList = frameState.commandList;
Expand Down
19 changes: 14 additions & 5 deletions Source/Scene/LabelCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ define([
billboard = labelCollection._billboardCollection.add({
collection : labelCollection
});
billboard._labelDimensions = new Cartesian2();
}
glyph.billboard = billboard;
}
Expand Down Expand Up @@ -306,10 +307,9 @@ define([
var glyphLength = glyphs.length;

var backgroundBillboard = label._backgroundBillboard;
var backgroundPadding = scratchBackgroundPadding;
Cartesian2.clone(
var backgroundPadding = Cartesian2.clone(
(defined(backgroundBillboard) ? label._backgroundPadding : Cartesian2.ZERO),
backgroundPadding);
scratchBackgroundPadding);

for (glyphIndex = 0; glyphIndex < glyphLength; ++glyphIndex) {
if (text.charAt(glyphIndex) === '\n') {
Expand Down Expand Up @@ -341,6 +341,13 @@ define([
var widthOffset = calculateWidthOffset(lineWidth, horizontalOrigin, backgroundPadding);
var lineSpacing = defaultLineSpacingPercent * maxLineHeight;
var otherLinesHeight = lineSpacing * (numberOfLines - 1);
var totalLineWidth = maxLineWidth;
var totalLineHeight = maxLineHeight + otherLinesHeight;

if (defined(backgroundBillboard)) {
totalLineWidth += (backgroundPadding.x * 2);
totalLineHeight += (backgroundPadding.y * 2);
}

glyphPixelOffset.x = widthOffset * scale * resolutionScale;
glyphPixelOffset.y = 0;
Expand Down Expand Up @@ -371,6 +378,8 @@ define([

if (defined(glyph.billboard)) {
glyph.billboard._setTranslate(glyphPixelOffset);
glyph.billboard._labelDimensions.x = totalLineWidth;
glyph.billboard._labelDimensions.y = totalLineHeight;
}

//Compute the next x offset taking into acocunt the kerning performed
Expand Down Expand Up @@ -405,8 +414,8 @@ define([
}
glyphPixelOffset.y = glyphPixelOffset.y * scale * resolutionScale;

backgroundBillboard.width = maxLineWidth + (backgroundPadding.x * 2);
backgroundBillboard.height = maxLineHeight + otherLinesHeight + (backgroundPadding.y * 2);
backgroundBillboard.width = totalLineWidth;
backgroundBillboard.height = totalLineHeight;
backgroundBillboard._setTranslate(glyphPixelOffset);
}
}
Expand Down
Loading

0 comments on commit da3593d

Please sign in to comment.