From da3593d859acbe09225c32f8346fe3dc189aa081 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 12 Jun 2018 11:02:26 -0400 Subject: [PATCH 01/12] Better billboard depth test against terrain for clamped to ground --- Source/Scene/Billboard.js | 6 +- Source/Scene/BillboardCollection.js | 154 +++++++++++++++++++++- Source/Scene/LabelCollection.js | 19 ++- Source/Shaders/BillboardCollectionFS.glsl | 54 +++++++- Source/Shaders/BillboardCollectionVS.glsl | 53 ++++++++ 5 files changed, 272 insertions(+), 14 deletions(-) diff --git a/Source/Scene/Billboard.js b/Source/Scene/Billboard.js index df8ad223d024..9fe78e54580c 100644 --- a/Source/Scene/Billboard.js +++ b/Source/Scene/Billboard.js @@ -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)) { @@ -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; diff --git a/Source/Scene/BillboardCollection.js b/Source/Scene/BillboardCollection.js index 2382486d757a..2e9c17688580 100644 --- a/Source/Scene/BillboardCollection.js +++ b/Source/Scene/BillboardCollection.js @@ -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; @@ -100,7 +102,9 @@ define([ scaleByDistance : 6, pixelOffsetScaleByDistance : 7, distanceDisplayConditionAndDisableDepth : 8, - a_batchId : 9 + textureOffset : 9, + dimensions : 10, + a_batchId : 11 }; var attributeLocationsInstanced = { @@ -114,7 +118,9 @@ define([ scaleByDistance : 7, pixelOffsetScaleByDistance : 8, distanceDisplayConditionAndDisableDepth : 9, - a_batchId : 10 + textureOffset : 10, + dimensions : 11, + a_batchId : 12 }; /** @@ -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; @@ -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 @@ -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. @@ -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; @@ -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; @@ -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); } @@ -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; @@ -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; @@ -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' : ''; @@ -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, @@ -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, @@ -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, @@ -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, @@ -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; diff --git a/Source/Scene/LabelCollection.js b/Source/Scene/LabelCollection.js index 5cdfa70bfee0..049810abdf32 100644 --- a/Source/Scene/LabelCollection.js +++ b/Source/Scene/LabelCollection.js @@ -249,6 +249,7 @@ define([ billboard = labelCollection._billboardCollection.add({ collection : labelCollection }); + billboard._labelDimensions = new Cartesian2(); } glyph.billboard = billboard; } @@ -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') { @@ -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; @@ -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 @@ -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); } } diff --git a/Source/Shaders/BillboardCollectionFS.glsl b/Source/Shaders/BillboardCollectionFS.glsl index 6d9a66cdcb7d..6fd371c897f0 100644 --- a/Source/Shaders/BillboardCollectionFS.glsl +++ b/Source/Shaders/BillboardCollectionFS.glsl @@ -5,10 +5,40 @@ uniform vec4 u_highlightColor; #endif varying vec2 v_textureCoordinates; - varying vec4 v_pickColor; varying vec4 v_color; +#ifdef CLAMP_TO_GROUND +varying vec4 v_textureOffset; +varying vec2 v_originTextureCoordinate; +varying vec2 v_leftTextureCoordinate; +varying vec2 v_rightTextureCoordinate; +varying vec2 v_dimensions; +varying vec2 v_imageSize; +varying vec2 v_translate; +varying float v_eyeDepth; +varying float v_disableDepthTestDistance; + +float getGlobeDepth(vec2 adjustedST, vec2 depthLookupST) +{ + vec2 a = v_imageSize.xy * (depthLookupST - adjustedST); + vec2 Dd = v_dimensions - v_imageSize; + vec2 px = v_translate.xy + (v_dimensions * v_originTextureCoordinate * vec2(0, -1)); // this is only needed for labels + + vec2 st = ((a - px + (depthLookupST * Dd)) + gl_FragCoord.xy) / czm_viewport.zw; + + float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, st)); + + if (logDepthOrDepth == 0.0) + { + return 0.0; + } + + vec4 eyeCoordinate = czm_windowToEyeCoordinates(gl_FragCoord.xy, logDepthOrDepth); + return eyeCoordinate.z / eyeCoordinate.w; +} +#endif + void main() { vec4 color = texture2D(u_atlas, v_textureCoordinates) * v_color; @@ -38,7 +68,27 @@ void main() #ifdef VECTOR_TILE color *= u_highlightColor; #endif - gl_FragColor = color; + czm_writeLogDepth(); + +#ifdef CLAMP_TO_GROUND + if (v_eyeDepth > -v_disableDepthTestDistance) { + vec2 adjustedST = v_textureCoordinates - v_textureOffset.xy; + adjustedST = adjustedST / vec2(v_textureOffset.z - v_textureOffset.x, v_textureOffset.w - v_textureOffset.y); + + float globeDepth1 = getGlobeDepth(adjustedST, v_originTextureCoordinate); + float globeDepth2 = getGlobeDepth(adjustedST, v_leftTextureCoordinate); + float globeDepth3 = getGlobeDepth(adjustedST, v_rightTextureCoordinate); + + float epsilonEyeDepth = v_eyeDepth + czm_epsilon5; + + // negative values go into the screen + if (globeDepth1 > epsilonEyeDepth && globeDepth2 > epsilonEyeDepth && globeDepth3 > epsilonEyeDepth) + { + discard; + } + } +#endif + } diff --git a/Source/Shaders/BillboardCollectionVS.glsl b/Source/Shaders/BillboardCollectionVS.glsl index 9c6f537e5856..e0f10233e967 100644 --- a/Source/Shaders/BillboardCollectionVS.glsl +++ b/Source/Shaders/BillboardCollectionVS.glsl @@ -10,11 +10,26 @@ attribute vec4 eyeOffset; // eye offset in mete attribute vec4 scaleByDistance; // near, nearScale, far, farScale attribute vec4 pixelOffsetScaleByDistance; // near, nearScale, far, farScale attribute vec3 distanceDisplayConditionAndDisableDepth; // near, far, disableDepthTestDistance +#ifdef CLAMP_TO_GROUND +attribute vec4 textureOffset; // the min and max x and y values for the texture coordinates +attribute vec2 dimensions; +#endif #ifdef VECTOR_TILE attribute float a_batchId; #endif varying vec2 v_textureCoordinates; +#ifdef CLAMP_TO_GROUND +varying vec4 v_textureOffset; +varying vec2 v_originTextureCoordinate; +varying vec2 v_leftTextureCoordinate; +varying vec2 v_rightTextureCoordinate; +varying vec2 v_dimensions; +varying vec2 v_imageSize; +varying vec2 v_translate; +varying float v_eyeDepth; +varying float v_disableDepthTestDistance; +#endif varying vec4 v_pickColor; varying vec4 v_color; @@ -116,6 +131,9 @@ void main() origin.y = floor(compressed * SHIFT_RIGHT3); compressed -= origin.y * SHIFT_LEFT3; +#ifdef CLAMP_TO_GROUND + vec2 depthOrigin = origin.xy * 0.5; +#endif origin -= vec2(1.0); float show = floor(compressed * SHIFT_RIGHT2); @@ -145,10 +163,34 @@ void main() translate.y += (temp - floor(temp)) * SHIFT_LEFT8; translate.y -= UPPER_BOUND; + v_translate = translate.xy; + temp = compressedAttribute1.x * SHIFT_RIGHT8; vec2 imageSize = vec2(floor(temp), compressedAttribute2.w); +#ifdef CLAMP_TO_GROUND + v_textureOffset = textureOffset; + v_originTextureCoordinate = vec2(1.0) - depthOrigin; //the origin + if (v_originTextureCoordinate.y == 1.0) //vertical origin is top + { + v_leftTextureCoordinate = vec2(0.0, 0.0); //bottom left + v_rightTextureCoordinate = vec2(1.0, 0.0); //bottom right + } + else + { + if (v_originTextureCoordinate.y == 0.0) + { + v_originTextureCoordinate.y = 0.1; + } + + v_leftTextureCoordinate = vec2(0.0, 1.0); //top left + v_rightTextureCoordinate = vec2(1.0, 1.0); //top right + } + v_dimensions = dimensions.xy; + v_imageSize = imageSize.xy; +#endif + #ifdef EYE_DISTANCE_TRANSLUCENCY vec4 translucencyByDistance; translucencyByDistance.x = compressedAttribute1.z; @@ -200,6 +242,11 @@ void main() vec4 p = czm_translateRelativeToEye(positionHigh, positionLow); vec4 positionEC = czm_modelViewRelativeToEye * p; + +#ifdef CLAMP_TO_GROUND + v_eyeDepth = positionEC.z; +#endif + positionEC = czm_eyeOffset(positionEC, eyeOffset.xyz); positionEC.xyz *= show; @@ -264,6 +311,11 @@ void main() #ifdef DISABLE_DEPTH_DISTANCE float disableDepthTestDistance = distanceDisplayConditionAndDisableDepth.z; + + #ifdef CLAMP_TO_GROUND + v_disableDepthTestDistance = disableDepthTestDistance; + #endif + if (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0) { disableDepthTestDistance = czm_minimumDisableDepthTestDistance; @@ -289,4 +341,5 @@ void main() v_color = color; v_color.a *= translucency; + } From bd633129449d15508b73dca13a7733607c48d87c Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 12 Jun 2018 12:47:46 -0400 Subject: [PATCH 02/12] cleanup --- Source/Scene/Billboard.js | 2 +- Source/Scene/BillboardCollection.js | 20 ++++++++++---------- Source/Shaders/BillboardCollectionFS.glsl | 23 ++++++++++++++--------- Source/Shaders/BillboardCollectionVS.glsl | 10 +++++----- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/Source/Scene/Billboard.js b/Source/Scene/Billboard.js index 9fe78e54580c..49cbfa7fb011 100644 --- a/Source/Scene/Billboard.js +++ b/Source/Scene/Billboard.js @@ -212,7 +212,7 @@ 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.TEXTURE_OFFSET = 16; + Billboard.TEXTURE_COORDINATE_BOUNDS = 16; Billboard.DIMENSIONS = 17; Billboard.NUMBER_OF_PROPERTIES = 18; diff --git a/Source/Scene/BillboardCollection.js b/Source/Scene/BillboardCollection.js index 2e9c17688580..fa6c4a30fd19 100644 --- a/Source/Scene/BillboardCollection.js +++ b/Source/Scene/BillboardCollection.js @@ -86,7 +86,7 @@ define([ var PIXEL_OFFSET_SCALE_BY_DISTANCE_INDEX = Billboard.PIXEL_OFFSET_SCALE_BY_DISTANCE_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 TEXTURE_COORDINATE_BOUNDS = Billboard.TEXTURE_COORDINATE_BOUNDS; var DIMENSIONS = Billboard.DIMENSIONS; var NUMBER_OF_PROPERTIES = Billboard.NUMBER_OF_PROPERTIES; @@ -102,7 +102,7 @@ define([ scaleByDistance : 6, pixelOffsetScaleByDistance : 7, distanceDisplayConditionAndDisableDepth : 8, - textureOffset : 9, + textureCoordinateBounds : 9, dimensions : 10, a_batchId : 11 }; @@ -118,7 +118,7 @@ define([ scaleByDistance : 7, pixelOffsetScaleByDistance : 8, distanceDisplayConditionAndDisableDepth : 9, - textureOffset : 10, + textureCoordinateBounds : 10, dimensions : 11, a_batchId : 12 }; @@ -312,7 +312,7 @@ define([ 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, // TEXTURE_OFFSET + BufferUsage.STATIC_DRAW, // TEXTURE_COORDINATE_BOUNDS BufferUsage.STATIC_DRAW // DIMENSIONS ]; @@ -748,10 +748,10 @@ define([ componentDatatype : ComponentDatatype.FLOAT, usage : buffersUsage[DISTANCE_DISPLAY_CONDITION_INDEX] }, { - index : attributeLocations.textureOffset, + index : attributeLocations.textureCoordinateBounds, componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[TEXTURE_OFFSET] + usage : buffersUsage[TEXTURE_COORDINATE_BOUNDS] }, { index : attributeLocations.dimensions, componentsPerAttribute : 2, @@ -1221,12 +1221,12 @@ define([ } } - function writeTextureOffset(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { + function writeTextureCoordinateBounds(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { if (billboard.heightReference === HeightReference.CLAMP_TO_GROUND) { billboardCollection._shaderClampToGround = true; } var i; - var writer = vafWriters[attributeLocations.textureOffset]; + var writer = vafWriters[attributeLocations.textureCoordinateBounds]; var minX = 0; var minY = 0; @@ -1341,7 +1341,7 @@ 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); + writeTextureCoordinateBounds(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); writeDimensions(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); writeBatchId(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); } @@ -1543,7 +1543,7 @@ define([ } if (properties[IMAGE_INDEX_INDEX] || properties[POSITION_INDEX]) { - writers.push(writeTextureOffset); + writers.push(writeTextureCoordinateBounds); } if (properties[IMAGE_INDEX_INDEX] || properties[POSITION_INDEX]) { diff --git a/Source/Shaders/BillboardCollectionFS.glsl b/Source/Shaders/BillboardCollectionFS.glsl index 6fd371c897f0..1c19328e01e2 100644 --- a/Source/Shaders/BillboardCollectionFS.glsl +++ b/Source/Shaders/BillboardCollectionFS.glsl @@ -9,7 +9,7 @@ varying vec4 v_pickColor; varying vec4 v_color; #ifdef CLAMP_TO_GROUND -varying vec4 v_textureOffset; +varying vec4 v_textureCoordinateBounds; varying vec2 v_originTextureCoordinate; varying vec2 v_leftTextureCoordinate; varying vec2 v_rightTextureCoordinate; @@ -74,19 +74,24 @@ void main() #ifdef CLAMP_TO_GROUND if (v_eyeDepth > -v_disableDepthTestDistance) { - vec2 adjustedST = v_textureCoordinates - v_textureOffset.xy; - adjustedST = adjustedST / vec2(v_textureOffset.z - v_textureOffset.x, v_textureOffset.w - v_textureOffset.y); - - float globeDepth1 = getGlobeDepth(adjustedST, v_originTextureCoordinate); - float globeDepth2 = getGlobeDepth(adjustedST, v_leftTextureCoordinate); - float globeDepth3 = getGlobeDepth(adjustedST, v_rightTextureCoordinate); + vec2 adjustedST = v_textureCoordinates - v_textureCoordinateBounds.xy; + adjustedST = adjustedST / vec2(v_textureCoordinateBounds.z - v_textureCoordinateBounds.x, v_textureCoordinateBounds.w - v_textureCoordinateBounds.y); float epsilonEyeDepth = v_eyeDepth + czm_epsilon5; + float globeDepth1 = getGlobeDepth(adjustedST, v_originTextureCoordinate); // negative values go into the screen - if (globeDepth1 > epsilonEyeDepth && globeDepth2 > epsilonEyeDepth && globeDepth3 > epsilonEyeDepth) + if (globeDepth1 > epsilonEyeDepth) { - discard; + float globeDepth2 = getGlobeDepth(adjustedST, v_leftTextureCoordinate); + if (globeDepth2 > epsilonEyeDepth) + { + float globeDepth3 = getGlobeDepth(adjustedST, v_rightTextureCoordinate); + if (globeDepth3 > epsilonEyeDepth) + { + discard; + } + } } } #endif diff --git a/Source/Shaders/BillboardCollectionVS.glsl b/Source/Shaders/BillboardCollectionVS.glsl index e0f10233e967..8c38fd9dc46f 100644 --- a/Source/Shaders/BillboardCollectionVS.glsl +++ b/Source/Shaders/BillboardCollectionVS.glsl @@ -11,7 +11,7 @@ attribute vec4 scaleByDistance; // near, nearScale, f attribute vec4 pixelOffsetScaleByDistance; // near, nearScale, far, farScale attribute vec3 distanceDisplayConditionAndDisableDepth; // near, far, disableDepthTestDistance #ifdef CLAMP_TO_GROUND -attribute vec4 textureOffset; // the min and max x and y values for the texture coordinates +attribute vec4 textureCoordinateBounds; // the min and max x and y values for the texture coordinates attribute vec2 dimensions; #endif #ifdef VECTOR_TILE @@ -20,7 +20,7 @@ attribute float a_batchId; varying vec2 v_textureCoordinates; #ifdef CLAMP_TO_GROUND -varying vec4 v_textureOffset; +varying vec4 v_textureCoordinateBounds; varying vec2 v_originTextureCoordinate; varying vec2 v_leftTextureCoordinate; varying vec2 v_rightTextureCoordinate; @@ -170,11 +170,11 @@ void main() vec2 imageSize = vec2(floor(temp), compressedAttribute2.w); #ifdef CLAMP_TO_GROUND - v_textureOffset = textureOffset; + v_textureCoordinateBounds = textureCoordinateBounds; v_originTextureCoordinate = vec2(1.0) - depthOrigin; //the origin if (v_originTextureCoordinate.y == 1.0) //vertical origin is top { - v_leftTextureCoordinate = vec2(0.0, 0.0); //bottom left + v_leftTextureCoordinate = vec2(0.0); //bottom left v_rightTextureCoordinate = vec2(1.0, 0.0); //bottom right } else @@ -185,7 +185,7 @@ void main() } v_leftTextureCoordinate = vec2(0.0, 1.0); //top left - v_rightTextureCoordinate = vec2(1.0, 1.0); //top right + v_rightTextureCoordinate = vec2(1.0); //top right } v_dimensions = dimensions.xy; v_imageSize = imageSize.xy; From 3f019cc4b19f11da0b774988d9e9feb46ffc432d Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 12 Jun 2018 16:59:42 -0400 Subject: [PATCH 03/12] compress the things --- Source/Scene/Billboard.js | 3 +- Source/Scene/BillboardCollection.js | 131 +++++++++------------- Source/Shaders/BillboardCollectionFS.glsl | 49 ++++---- Source/Shaders/BillboardCollectionVS.glsl | 53 +++++---- 4 files changed, 105 insertions(+), 131 deletions(-) diff --git a/Source/Scene/Billboard.js b/Source/Scene/Billboard.js index 49cbfa7fb011..52946cd882dc 100644 --- a/Source/Scene/Billboard.js +++ b/Source/Scene/Billboard.js @@ -213,8 +213,7 @@ define([ var DISTANCE_DISPLAY_CONDITION = Billboard.DISTANCE_DISPLAY_CONDITION = 14; var DISABLE_DEPTH_DISTANCE = Billboard.DISABLE_DEPTH_DISTANCE = 15; Billboard.TEXTURE_COORDINATE_BOUNDS = 16; - Billboard.DIMENSIONS = 17; - Billboard.NUMBER_OF_PROPERTIES = 18; + Billboard.NUMBER_OF_PROPERTIES = 17; function makeDirty(billboard, propertyChanged) { var billboardCollection = billboard._billboardCollection; diff --git a/Source/Scene/BillboardCollection.js b/Source/Scene/BillboardCollection.js index fa6c4a30fd19..a0647289f835 100644 --- a/Source/Scene/BillboardCollection.js +++ b/Source/Scene/BillboardCollection.js @@ -87,7 +87,6 @@ define([ 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 DIMENSIONS = Billboard.DIMENSIONS; var NUMBER_OF_PROPERTIES = Billboard.NUMBER_OF_PROPERTIES; var attributeLocations; @@ -101,10 +100,9 @@ define([ eyeOffset : 5, // 4 bytes free scaleByDistance : 6, pixelOffsetScaleByDistance : 7, - distanceDisplayConditionAndDisableDepth : 8, + compressedAttribute3 : 8, textureCoordinateBounds : 9, - dimensions : 10, - a_batchId : 11 + a_batchId : 10 }; var attributeLocationsInstanced = { @@ -117,10 +115,9 @@ define([ eyeOffset : 6, // texture range in w scaleByDistance : 7, pixelOffsetScaleByDistance : 8, - distanceDisplayConditionAndDisableDepth : 9, + compressedAttribute3 : 9, textureCoordinateBounds : 10, - dimensions : 11, - a_batchId : 12 + a_batchId : 11 }; /** @@ -312,8 +309,7 @@ define([ 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, // TEXTURE_COORDINATE_BOUNDS - BufferUsage.STATIC_DRAW // DIMENSIONS + BufferUsage.STATIC_DRAW // TEXTURE_COORDINATE_BOUNDS ]; this._highlightColor = Color.clone(Color.WHITE); // Only used by Vector3DTilePoints @@ -743,8 +739,8 @@ 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] }, { @@ -752,11 +748,6 @@ define([ componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, usage : buffersUsage[TEXTURE_COORDINATE_BOUNDS] - }, { - index : attributeLocations.dimensions, - componentsPerAttribute : 2, - componentDatatype : ComponentDatatype.FLOAT, - usage : buffersUsage[DIMENSIONS] }]; // Instancing requires one non-instanced attribute. @@ -839,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; @@ -1179,9 +1171,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; @@ -1209,15 +1201,48 @@ 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); + writer(i, near, far, disableDepthTestDistance, dimensions); } 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, 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); } } @@ -1262,55 +1287,6 @@ define([ } } - 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; @@ -1340,9 +1316,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); - writeDimensions(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); writeBatchId(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard); } @@ -1538,18 +1513,14 @@ define([ writers.push(writePixelOffsetScaleByDistance); } - if (properties[DISTANCE_DISPLAY_CONDITION_INDEX] || properties[DISABLE_DEPTH_DISTANCE] || properties[POSITION_INDEX]) { - 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); } - if (properties[IMAGE_INDEX_INDEX] || properties[POSITION_INDEX]) { - writers.push(writeDimensions); - } - var numWriters = writers.length; vafWriters = this._vaf.writers; diff --git a/Source/Shaders/BillboardCollectionFS.glsl b/Source/Shaders/BillboardCollectionFS.glsl index 1c19328e01e2..2aa8c03e6e50 100644 --- a/Source/Shaders/BillboardCollectionFS.glsl +++ b/Source/Shaders/BillboardCollectionFS.glsl @@ -9,29 +9,34 @@ varying vec4 v_pickColor; varying vec4 v_color; #ifdef CLAMP_TO_GROUND -varying vec4 v_textureCoordinateBounds; -varying vec2 v_originTextureCoordinate; -varying vec2 v_leftTextureCoordinate; -varying vec2 v_rightTextureCoordinate; -varying vec2 v_dimensions; -varying vec2 v_imageSize; -varying vec2 v_translate; -varying float v_eyeDepth; -varying float v_disableDepthTestDistance; +varying vec4 v_textureCoordinateBounds; // the min and max x and y values for the texture coordinates +varying vec4 v_originTextureCoordinateAndTranslate; // texture coordinate at the origin, billboard translate (used for label glyphs) +varying vec4 v_leftAndRightTextureCoordinate; // texture coordinates for left and right depth test +varying vec4 v_dimensionsAndImageSize; // dimensions of the bounding rectangle and the size of the image. The values will only be different for label glyphs +varying vec2 v_eyeDepthAndDistance; // The depth of the billboard and the disable depth test distance float getGlobeDepth(vec2 adjustedST, vec2 depthLookupST) { - vec2 a = v_imageSize.xy * (depthLookupST - adjustedST); - vec2 Dd = v_dimensions - v_imageSize; - vec2 px = v_translate.xy + (v_dimensions * v_originTextureCoordinate * vec2(0, -1)); // this is only needed for labels + vec2 dimensions = v_dimensionsAndImageSize.xy; + vec2 imageSize = v_dimensionsAndImageSize.zw; - vec2 st = ((a - px + (depthLookupST * Dd)) + gl_FragCoord.xy) / czm_viewport.zw; + vec2 lookupVector = imageSize * (depthLookupST - adjustedST); + vec2 labelOffset = depthLookupST * (dimensions - imageSize); // aligns label glyph with bounding rectangle. Will be zero for billboards because dimensions and imageSize will be equal + vec2 translation = v_originTextureCoordinateAndTranslate.zw; + if (translation != vec2(0.0)) + { + // this is only needed for labels where the horizontal origin is not LEFT + // it moves the label back to where the "origin" should be since all label glyphs are set to HorizontalOrigin.LEFT + translation += (dimensions * v_originTextureCoordinateAndTranslate.xy * vec2(0, -1)); + } + + vec2 st = ((lookupVector - translation + labelOffset) + gl_FragCoord.xy) / czm_viewport.zw; float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, st)); if (logDepthOrDepth == 0.0) { - return 0.0; + return 0.0; // not on the globe } vec4 eyeCoordinate = czm_windowToEyeCoordinates(gl_FragCoord.xy, logDepthOrDepth); @@ -73,21 +78,21 @@ void main() czm_writeLogDepth(); #ifdef CLAMP_TO_GROUND - if (v_eyeDepth > -v_disableDepthTestDistance) { + if (v_eyeDepthAndDistance.x > -v_eyeDepthAndDistance.y) { vec2 adjustedST = v_textureCoordinates - v_textureCoordinateBounds.xy; adjustedST = adjustedST / vec2(v_textureCoordinateBounds.z - v_textureCoordinateBounds.x, v_textureCoordinateBounds.w - v_textureCoordinateBounds.y); - float epsilonEyeDepth = v_eyeDepth + czm_epsilon5; - float globeDepth1 = getGlobeDepth(adjustedST, v_originTextureCoordinate); + float epsilonEyeDepth = v_eyeDepthAndDistance.x + czm_epsilon5; + float globeDepth1 = getGlobeDepth(adjustedST, v_originTextureCoordinateAndTranslate.xy); // negative values go into the screen - if (globeDepth1 > epsilonEyeDepth) + if (globeDepth1 != 0.0 && globeDepth1 > epsilonEyeDepth) { - float globeDepth2 = getGlobeDepth(adjustedST, v_leftTextureCoordinate); - if (globeDepth2 > epsilonEyeDepth) + float globeDepth2 = getGlobeDepth(adjustedST, v_leftAndRightTextureCoordinate.xy); + if (globeDepth2 != 0.0 && globeDepth2 > epsilonEyeDepth) { - float globeDepth3 = getGlobeDepth(adjustedST, v_rightTextureCoordinate); - if (globeDepth3 > epsilonEyeDepth) + float globeDepth3 = getGlobeDepth(adjustedST, v_leftAndRightTextureCoordinate.zw); + if (globeDepth3 != 0.0 && globeDepth3 > epsilonEyeDepth) { discard; } diff --git a/Source/Shaders/BillboardCollectionVS.glsl b/Source/Shaders/BillboardCollectionVS.glsl index 8c38fd9dc46f..dd5f7c60a19c 100644 --- a/Source/Shaders/BillboardCollectionVS.glsl +++ b/Source/Shaders/BillboardCollectionVS.glsl @@ -9,10 +9,9 @@ attribute vec4 compressedAttribute2; // image height, colo attribute vec4 eyeOffset; // eye offset in meters, 4 bytes free (texture range) attribute vec4 scaleByDistance; // near, nearScale, far, farScale attribute vec4 pixelOffsetScaleByDistance; // near, nearScale, far, farScale -attribute vec3 distanceDisplayConditionAndDisableDepth; // near, far, disableDepthTestDistance +attribute vec4 compressedAttribute3; // distnace display condition near, far, disableDepthTestDistance, dimensions #ifdef CLAMP_TO_GROUND -attribute vec4 textureCoordinateBounds; // the min and max x and y values for the texture coordinates -attribute vec2 dimensions; +attribute vec4 textureCoordinateBounds; // the min and max x and y values for the texture coordinates #endif #ifdef VECTOR_TILE attribute float a_batchId; @@ -21,14 +20,10 @@ attribute float a_batchId; varying vec2 v_textureCoordinates; #ifdef CLAMP_TO_GROUND varying vec4 v_textureCoordinateBounds; -varying vec2 v_originTextureCoordinate; -varying vec2 v_leftTextureCoordinate; -varying vec2 v_rightTextureCoordinate; -varying vec2 v_dimensions; -varying vec2 v_imageSize; -varying vec2 v_translate; -varying float v_eyeDepth; -varying float v_disableDepthTestDistance; +varying vec4 v_originTextureCoordinateAndTranslate; +varying vec4 v_leftAndRightTextureCoordinate; +varying vec4 v_dimensionsAndImageSize; +varying vec2 v_eyeDepthAndDistance; #endif varying vec4 v_pickColor; @@ -37,6 +32,7 @@ varying vec4 v_color; const float UPPER_BOUND = 32768.0; const float SHIFT_LEFT16 = 65536.0; +const float SHIFT_LEFT12 = 4096.0; const float SHIFT_LEFT8 = 256.0; const float SHIFT_LEFT7 = 128.0; const float SHIFT_LEFT5 = 32.0; @@ -44,6 +40,7 @@ const float SHIFT_LEFT3 = 8.0; const float SHIFT_LEFT2 = 4.0; const float SHIFT_LEFT1 = 2.0; +const float SHIFT_RIGHT12 = 1.0 / 4096.0; const float SHIFT_RIGHT8 = 1.0 / 256.0; const float SHIFT_RIGHT7 = 1.0 / 128.0; const float SHIFT_RIGHT5 = 1.0 / 32.0; @@ -163,7 +160,7 @@ void main() translate.y += (temp - floor(temp)) * SHIFT_LEFT8; translate.y -= UPPER_BOUND; - v_translate = translate.xy; + v_originTextureCoordinateAndTranslate.zw = translate.xy; temp = compressedAttribute1.x * SHIFT_RIGHT8; @@ -171,24 +168,26 @@ void main() #ifdef CLAMP_TO_GROUND v_textureCoordinateBounds = textureCoordinateBounds; - v_originTextureCoordinate = vec2(1.0) - depthOrigin; //the origin - if (v_originTextureCoordinate.y == 1.0) //vertical origin is top + v_originTextureCoordinateAndTranslate.xy = vec2(1.0) - depthOrigin; //the origin + if (v_originTextureCoordinateAndTranslate.y == 1.0) //vertical origin is top { - v_leftTextureCoordinate = vec2(0.0); //bottom left - v_rightTextureCoordinate = vec2(1.0, 0.0); //bottom right + v_leftAndRightTextureCoordinate = vec4(0.0, 0.0, 1.0, 0.0); //bottom left, bottom right } else { - if (v_originTextureCoordinate.y == 0.0) + if (v_originTextureCoordinateAndTranslate.y == 0.0) { - v_originTextureCoordinate.y = 0.1; + v_originTextureCoordinateAndTranslate.y = 0.1; } - v_leftTextureCoordinate = vec2(0.0, 1.0); //top left - v_rightTextureCoordinate = vec2(1.0); //top right + v_leftAndRightTextureCoordinate = vec4(0.0, 1.0, 1.0, 1.0); //top left, top right } - v_dimensions = dimensions.xy; - v_imageSize = imageSize.xy; + + temp = compressedAttribute3.w; + temp = temp * SHIFT_RIGHT12; + v_dimensionsAndImageSize.y = (temp - floor(temp)) * SHIFT_LEFT12; + v_dimensionsAndImageSize.x = floor(temp); + v_dimensionsAndImageSize.zw = imageSize.xy; #endif #ifdef EYE_DISTANCE_TRANSLUCENCY @@ -244,7 +243,7 @@ void main() vec4 positionEC = czm_modelViewRelativeToEye * p; #ifdef CLAMP_TO_GROUND - v_eyeDepth = positionEC.z; + v_eyeDepthAndDistance.x = positionEC.z; #endif positionEC = czm_eyeOffset(positionEC, eyeOffset.xyz); @@ -293,8 +292,8 @@ void main() #endif #ifdef DISTANCE_DISPLAY_CONDITION - float nearSq = distanceDisplayConditionAndDisableDepth.x; - float farSq = distanceDisplayConditionAndDisableDepth.y; + float nearSq = compressedAttribute3.x; + float farSq = compressedAttribute3.y; if (lengthSq < nearSq || lengthSq > farSq) { positionEC.xyz = vec3(0.0); @@ -310,10 +309,10 @@ void main() #endif #ifdef DISABLE_DEPTH_DISTANCE - float disableDepthTestDistance = distanceDisplayConditionAndDisableDepth.z; + float disableDepthTestDistance = compressedAttribute3.z; #ifdef CLAMP_TO_GROUND - v_disableDepthTestDistance = disableDepthTestDistance; + v_eyeDepthAndDistance.y = disableDepthTestDistance; #endif if (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0) From 072c0c80ead81f4cd5b7153822974f7f73cd4b80 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Wed, 13 Jun 2018 10:21:14 -0400 Subject: [PATCH 04/12] CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 433cae97418b..2a2e2f79a4e4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,7 @@ Change Log ##### Fixes :wrench: * Fixed a bug causing crashes with custom vertex attributes on `Geometry` crossing the IDL. Attributes will be barycentrically interpolated. [#6644](https://github.com/AnalyticalGraphicsInc/cesium/pull/6644) * 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) +* Improved billboard and label rendering so they no longer sink into terrain when clamped to ground. [#6621](https://github.com/AnalyticalGraphicsInc/cesium/pull/6621) ### 1.46.1 - 2018-06-01 From 493b8ce27e850331bb73900436da90ad3dd3623e Mon Sep 17 00:00:00 2001 From: hpinkos Date: Mon, 18 Jun 2018 16:40:24 -0400 Subject: [PATCH 05/12] cleanup --- Source/Shaders/BillboardCollectionFS.glsl | 5 ++--- Source/Shaders/BillboardCollectionVS.glsl | 19 ++----------------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/Source/Shaders/BillboardCollectionFS.glsl b/Source/Shaders/BillboardCollectionFS.glsl index 2aa8c03e6e50..0e5e99dd8618 100644 --- a/Source/Shaders/BillboardCollectionFS.glsl +++ b/Source/Shaders/BillboardCollectionFS.glsl @@ -11,7 +11,6 @@ varying vec4 v_color; #ifdef CLAMP_TO_GROUND varying vec4 v_textureCoordinateBounds; // the min and max x and y values for the texture coordinates varying vec4 v_originTextureCoordinateAndTranslate; // texture coordinate at the origin, billboard translate (used for label glyphs) -varying vec4 v_leftAndRightTextureCoordinate; // texture coordinates for left and right depth test varying vec4 v_dimensionsAndImageSize; // dimensions of the bounding rectangle and the size of the image. The values will only be different for label glyphs varying vec2 v_eyeDepthAndDistance; // The depth of the billboard and the disable depth test distance @@ -88,10 +87,10 @@ void main() // negative values go into the screen if (globeDepth1 != 0.0 && globeDepth1 > epsilonEyeDepth) { - float globeDepth2 = getGlobeDepth(adjustedST, v_leftAndRightTextureCoordinate.xy); + float globeDepth2 = getGlobeDepth(adjustedST, vec2(0.0, 1.0)); // top left corner if (globeDepth2 != 0.0 && globeDepth2 > epsilonEyeDepth) { - float globeDepth3 = getGlobeDepth(adjustedST, v_leftAndRightTextureCoordinate.zw); + float globeDepth3 = getGlobeDepth(adjustedST, vec2(1.0, 1.0)); // top right corner if (globeDepth3 != 0.0 && globeDepth3 > epsilonEyeDepth) { discard; diff --git a/Source/Shaders/BillboardCollectionVS.glsl b/Source/Shaders/BillboardCollectionVS.glsl index dd5f7c60a19c..e046ac8b9c31 100644 --- a/Source/Shaders/BillboardCollectionVS.glsl +++ b/Source/Shaders/BillboardCollectionVS.glsl @@ -21,7 +21,6 @@ varying vec2 v_textureCoordinates; #ifdef CLAMP_TO_GROUND varying vec4 v_textureCoordinateBounds; varying vec4 v_originTextureCoordinateAndTranslate; -varying vec4 v_leftAndRightTextureCoordinate; varying vec4 v_dimensionsAndImageSize; varying vec2 v_eyeDepthAndDistance; #endif @@ -160,28 +159,14 @@ void main() translate.y += (temp - floor(temp)) * SHIFT_LEFT8; translate.y -= UPPER_BOUND; - v_originTextureCoordinateAndTranslate.zw = translate.xy; - temp = compressedAttribute1.x * SHIFT_RIGHT8; vec2 imageSize = vec2(floor(temp), compressedAttribute2.w); #ifdef CLAMP_TO_GROUND - v_textureCoordinateBounds = textureCoordinateBounds; v_originTextureCoordinateAndTranslate.xy = vec2(1.0) - depthOrigin; //the origin - if (v_originTextureCoordinateAndTranslate.y == 1.0) //vertical origin is top - { - v_leftAndRightTextureCoordinate = vec4(0.0, 0.0, 1.0, 0.0); //bottom left, bottom right - } - else - { - if (v_originTextureCoordinateAndTranslate.y == 0.0) - { - v_originTextureCoordinateAndTranslate.y = 0.1; - } - - v_leftAndRightTextureCoordinate = vec4(0.0, 1.0, 1.0, 1.0); //top left, top right - } + v_originTextureCoordinateAndTranslate.zw = translate.xy; + v_textureCoordinateBounds = textureCoordinateBounds; temp = compressedAttribute3.w; temp = temp * SHIFT_RIGHT12; From 64e0d3a60b3e10358e4bf899f4e69bf4dae123ce Mon Sep 17 00:00:00 2001 From: hpinkos Date: Mon, 18 Jun 2018 16:58:09 -0400 Subject: [PATCH 06/12] adjust epsilon --- Source/Shaders/BillboardCollectionFS.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Shaders/BillboardCollectionFS.glsl b/Source/Shaders/BillboardCollectionFS.glsl index 0e5e99dd8618..a055d4dd617e 100644 --- a/Source/Shaders/BillboardCollectionFS.glsl +++ b/Source/Shaders/BillboardCollectionFS.glsl @@ -81,7 +81,7 @@ void main() vec2 adjustedST = v_textureCoordinates - v_textureCoordinateBounds.xy; adjustedST = adjustedST / vec2(v_textureCoordinateBounds.z - v_textureCoordinateBounds.x, v_textureCoordinateBounds.w - v_textureCoordinateBounds.y); - float epsilonEyeDepth = v_eyeDepthAndDistance.x + czm_epsilon5; + float epsilonEyeDepth = v_eyeDepthAndDistance.x + czm_epsilon1; float globeDepth1 = getGlobeDepth(adjustedST, v_originTextureCoordinateAndTranslate.xy); // negative values go into the screen From 6b0e54fb2a200d3ed7d00c5fd594ca119bcbabfc Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 19 Jun 2018 14:56:46 -0400 Subject: [PATCH 07/12] fix label picks --- Source/Scene/Billboard.js | 1 + Source/Scene/BillboardCollection.js | 13 ++++++---- Source/Scene/LabelCollection.js | 2 ++ Source/Shaders/BillboardCollectionFS.glsl | 14 +++++----- Source/Shaders/BillboardCollectionVS.glsl | 31 +++++++++++++++++------ 5 files changed, 41 insertions(+), 20 deletions(-) diff --git a/Source/Scene/Billboard.js b/Source/Scene/Billboard.js index 52946cd882dc..0baeef037daf 100644 --- a/Source/Scene/Billboard.js +++ b/Source/Scene/Billboard.js @@ -160,6 +160,7 @@ define([ this._imageHeight = undefined; this._labelDimensions = undefined; + this._labelHorizontalOrigin = undefined; var image = options.image; var imageId = options.imageId; diff --git a/Source/Scene/BillboardCollection.js b/Source/Scene/BillboardCollection.js index a0647289f835..9c8cf9f31104 100644 --- a/Source/Scene/BillboardCollection.js +++ b/Source/Scene/BillboardCollection.js @@ -1033,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); @@ -1049,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); } } diff --git a/Source/Scene/LabelCollection.js b/Source/Scene/LabelCollection.js index 049810abdf32..e6ac85dab71a 100644 --- a/Source/Scene/LabelCollection.js +++ b/Source/Scene/LabelCollection.js @@ -347,6 +347,7 @@ define([ if (defined(backgroundBillboard)) { totalLineWidth += (backgroundPadding.x * 2); totalLineHeight += (backgroundPadding.y * 2); + backgroundBillboard._labelHorizontalOrigin = horizontalOrigin; } glyphPixelOffset.x = widthOffset * scale * resolutionScale; @@ -380,6 +381,7 @@ define([ glyph.billboard._setTranslate(glyphPixelOffset); glyph.billboard._labelDimensions.x = totalLineWidth; glyph.billboard._labelDimensions.y = totalLineHeight; + glyph.billboard._labelHorizontalOrigin = horizontalOrigin; } //Compute the next x offset taking into acocunt the kerning performed diff --git a/Source/Shaders/BillboardCollectionFS.glsl b/Source/Shaders/BillboardCollectionFS.glsl index a055d4dd617e..6f3734cd38ee 100644 --- a/Source/Shaders/BillboardCollectionFS.glsl +++ b/Source/Shaders/BillboardCollectionFS.glsl @@ -12,7 +12,7 @@ varying vec4 v_color; varying vec4 v_textureCoordinateBounds; // the min and max x and y values for the texture coordinates varying vec4 v_originTextureCoordinateAndTranslate; // texture coordinate at the origin, billboard translate (used for label glyphs) varying vec4 v_dimensionsAndImageSize; // dimensions of the bounding rectangle and the size of the image. The values will only be different for label glyphs -varying vec2 v_eyeDepthAndDistance; // The depth of the billboard and the disable depth test distance +varying vec3 v_eyeDepthDistanceAndApplyTranslate; // The depth of the billboard and the disable depth test distance float getGlobeDepth(vec2 adjustedST, vec2 depthLookupST) { @@ -20,17 +20,17 @@ float getGlobeDepth(vec2 adjustedST, vec2 depthLookupST) vec2 imageSize = v_dimensionsAndImageSize.zw; vec2 lookupVector = imageSize * (depthLookupST - adjustedST); - vec2 labelOffset = depthLookupST * (dimensions - imageSize); // aligns label glyph with bounding rectangle. Will be zero for billboards because dimensions and imageSize will be equal + vec2 labelOffset = depthLookupST * (dimensions - imageSize) * vec2(1.0, 1.0 - v_originTextureCoordinateAndTranslate.y); // aligns label glyph with bounding rectangle. Will be zero for billboards because dimensions and imageSize will be equal vec2 translation = v_originTextureCoordinateAndTranslate.zw; - if (translation != vec2(0.0)) + + if (v_eyeDepthDistanceAndApplyTranslate.z != 0.0) { // this is only needed for labels where the horizontal origin is not LEFT // it moves the label back to where the "origin" should be since all label glyphs are set to HorizontalOrigin.LEFT - translation += (dimensions * v_originTextureCoordinateAndTranslate.xy * vec2(0, -1)); + translation += (dimensions * v_originTextureCoordinateAndTranslate.xy * vec2(1.0, 0.0)); } vec2 st = ((lookupVector - translation + labelOffset) + gl_FragCoord.xy) / czm_viewport.zw; - float logDepthOrDepth = czm_unpackDepth(texture2D(czm_globeDepthTexture, st)); if (logDepthOrDepth == 0.0) @@ -77,11 +77,11 @@ void main() czm_writeLogDepth(); #ifdef CLAMP_TO_GROUND - if (v_eyeDepthAndDistance.x > -v_eyeDepthAndDistance.y) { + if (v_eyeDepthDistanceAndApplyTranslate.x > -v_eyeDepthDistanceAndApplyTranslate.y) { vec2 adjustedST = v_textureCoordinates - v_textureCoordinateBounds.xy; adjustedST = adjustedST / vec2(v_textureCoordinateBounds.z - v_textureCoordinateBounds.x, v_textureCoordinateBounds.w - v_textureCoordinateBounds.y); - float epsilonEyeDepth = v_eyeDepthAndDistance.x + czm_epsilon1; + float epsilonEyeDepth = v_eyeDepthDistanceAndApplyTranslate.x + czm_epsilon1; float globeDepth1 = getGlobeDepth(adjustedST, v_originTextureCoordinateAndTranslate.xy); // negative values go into the screen diff --git a/Source/Shaders/BillboardCollectionVS.glsl b/Source/Shaders/BillboardCollectionVS.glsl index e046ac8b9c31..5b74712c4e58 100644 --- a/Source/Shaders/BillboardCollectionVS.glsl +++ b/Source/Shaders/BillboardCollectionVS.glsl @@ -5,11 +5,11 @@ attribute vec4 positionHighAndScale; attribute vec4 positionLowAndRotation; attribute vec4 compressedAttribute0; // pixel offset, translate, horizontal origin, vertical origin, show, direction, texture coordinates (texture offset) attribute vec4 compressedAttribute1; // aligned axis, translucency by distance, image width -attribute vec4 compressedAttribute2; // image height, color, pick color, size in meters, valid aligned axis, 13 bits free +attribute vec4 compressedAttribute2; // label horizontal origin, image height, color, pick color, size in meters, valid aligned axis, 13 bits free attribute vec4 eyeOffset; // eye offset in meters, 4 bytes free (texture range) attribute vec4 scaleByDistance; // near, nearScale, far, farScale attribute vec4 pixelOffsetScaleByDistance; // near, nearScale, far, farScale -attribute vec4 compressedAttribute3; // distnace display condition near, far, disableDepthTestDistance, dimensions +attribute vec4 compressedAttribute3; // distance display condition near, far, disableDepthTestDistance, dimensions #ifdef CLAMP_TO_GROUND attribute vec4 textureCoordinateBounds; // the min and max x and y values for the texture coordinates #endif @@ -22,7 +22,7 @@ varying vec2 v_textureCoordinates; varying vec4 v_textureCoordinateBounds; varying vec4 v_originTextureCoordinateAndTranslate; varying vec4 v_dimensionsAndImageSize; -varying vec2 v_eyeDepthAndDistance; +varying vec3 v_eyeDepthDistanceAndApplyTranslate; #endif varying vec4 v_pickColor; @@ -128,7 +128,7 @@ void main() compressed -= origin.y * SHIFT_LEFT3; #ifdef CLAMP_TO_GROUND - vec2 depthOrigin = origin.xy * 0.5; + vec2 depthOrigin = origin.xy; #endif origin -= vec2(1.0); @@ -160,11 +160,25 @@ void main() translate.y -= UPPER_BOUND; temp = compressedAttribute1.x * SHIFT_RIGHT8; + float temp2 = floor(compressedAttribute2.w * SHIFT_RIGHT2); - vec2 imageSize = vec2(floor(temp), compressedAttribute2.w); + vec2 imageSize = vec2(floor(temp), temp2); #ifdef CLAMP_TO_GROUND - v_originTextureCoordinateAndTranslate.xy = vec2(1.0) - depthOrigin; //the origin + float labelHorizontalOrigin = floor(compressedAttribute2.w - (temp2 * SHIFT_LEFT2)); + + if (labelHorizontalOrigin == 0.0) // is a billboard, so set apply translate to false + { + v_eyeDepthDistanceAndApplyTranslate.z = 0.0; + } + else // is a label, so we need to grab the correct horizontal origin texture coordinate + { + labelHorizontalOrigin -= 2.0; + v_eyeDepthDistanceAndApplyTranslate.z = 1.0; + depthOrigin.x = labelHorizontalOrigin + 1.0; + } + + v_originTextureCoordinateAndTranslate.xy = vec2(1.0) - (depthOrigin * 0.5); v_originTextureCoordinateAndTranslate.zw = translate.xy; v_textureCoordinateBounds = textureCoordinateBounds; @@ -172,6 +186,7 @@ void main() temp = temp * SHIFT_RIGHT12; v_dimensionsAndImageSize.y = (temp - floor(temp)) * SHIFT_LEFT12; v_dimensionsAndImageSize.x = floor(temp); + v_dimensionsAndImageSize.zw = imageSize.xy; #endif @@ -228,7 +243,7 @@ void main() vec4 positionEC = czm_modelViewRelativeToEye * p; #ifdef CLAMP_TO_GROUND - v_eyeDepthAndDistance.x = positionEC.z; + v_eyeDepthDistanceAndApplyTranslate.x = positionEC.z; #endif positionEC = czm_eyeOffset(positionEC, eyeOffset.xyz); @@ -297,7 +312,7 @@ void main() float disableDepthTestDistance = compressedAttribute3.z; #ifdef CLAMP_TO_GROUND - v_eyeDepthAndDistance.y = disableDepthTestDistance; + v_eyeDepthDistanceAndApplyTranslate.y = disableDepthTestDistance; #endif if (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0) From be0000c128369b72d18126fd8f2dba0ea9f99dbe Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 19 Jun 2018 16:54:26 -0400 Subject: [PATCH 08/12] fix ie --- Source/Scene/BillboardCollection.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/BillboardCollection.js b/Source/Scene/BillboardCollection.js index 9c8cf9f31104..89bcb04985c7 100644 --- a/Source/Scene/BillboardCollection.js +++ b/Source/Scene/BillboardCollection.js @@ -1192,7 +1192,7 @@ define([ } var disableDepthTestDistance = billboard.disableDepthTestDistance; - if (billboard.heightReference === HeightReference.CLAMP_TO_GROUND && disableDepthTestDistance === 0.0) { + if (billboard.heightReference === HeightReference.CLAMP_TO_GROUND && disableDepthTestDistance === 0.0 && billboardCollection._scene.context.depthTexture) { disableDepthTestDistance = 2000.0; } @@ -1251,7 +1251,7 @@ define([ function writeTextureCoordinateBounds(billboardCollection, context, textureAtlasCoordinates, vafWriters, billboard) { if (billboard.heightReference === HeightReference.CLAMP_TO_GROUND) { - billboardCollection._shaderClampToGround = true; + billboardCollection._shaderClampToGround = billboardCollection._scene.context.depthTexture; } var i; var writer = vafWriters[attributeLocations.textureCoordinateBounds]; From 5883a2b8920f14f2f82dcd4462eea4243c80f77a Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 19 Jun 2018 18:06:24 -0400 Subject: [PATCH 09/12] fix scale --- Source/Shaders/BillboardCollectionVS.glsl | 39 +++++++++++------------ 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/Source/Shaders/BillboardCollectionVS.glsl b/Source/Shaders/BillboardCollectionVS.glsl index 5b74712c4e58..9355caf93108 100644 --- a/Source/Shaders/BillboardCollectionVS.glsl +++ b/Source/Shaders/BillboardCollectionVS.glsl @@ -166,28 +166,21 @@ void main() #ifdef CLAMP_TO_GROUND float labelHorizontalOrigin = floor(compressedAttribute2.w - (temp2 * SHIFT_LEFT2)); - - if (labelHorizontalOrigin == 0.0) // is a billboard, so set apply translate to false - { - v_eyeDepthDistanceAndApplyTranslate.z = 0.0; - } - else // is a label, so we need to grab the correct horizontal origin texture coordinate + float applyTranslate = 0.0; + if (labelHorizontalOrigin != 0.0) // is a billboard, so set apply translate to false { + applyTranslate = 1.0; labelHorizontalOrigin -= 2.0; - v_eyeDepthDistanceAndApplyTranslate.z = 1.0; depthOrigin.x = labelHorizontalOrigin + 1.0; } - v_originTextureCoordinateAndTranslate.xy = vec2(1.0) - (depthOrigin * 0.5); - v_originTextureCoordinateAndTranslate.zw = translate.xy; - v_textureCoordinateBounds = textureCoordinateBounds; + depthOrigin = vec2(1.0) - (depthOrigin * 0.5); temp = compressedAttribute3.w; temp = temp * SHIFT_RIGHT12; - v_dimensionsAndImageSize.y = (temp - floor(temp)) * SHIFT_LEFT12; - v_dimensionsAndImageSize.x = floor(temp); - - v_dimensionsAndImageSize.zw = imageSize.xy; + vec2 dimensions; + dimensions.y = (temp - floor(temp)) * SHIFT_LEFT12; + dimensions.x = floor(temp); #endif #ifdef EYE_DISTANCE_TRANSLUCENCY @@ -243,7 +236,7 @@ void main() vec4 positionEC = czm_modelViewRelativeToEye * p; #ifdef CLAMP_TO_GROUND - v_eyeDepthDistanceAndApplyTranslate.x = positionEC.z; + float eyeDepth = positionEC.z; #endif positionEC = czm_eyeOffset(positionEC, eyeOffset.xyz); @@ -311,10 +304,6 @@ void main() #ifdef DISABLE_DEPTH_DISTANCE float disableDepthTestDistance = compressedAttribute3.z; - #ifdef CLAMP_TO_GROUND - v_eyeDepthDistanceAndApplyTranslate.y = disableDepthTestDistance; - #endif - if (disableDepthTestDistance == 0.0 && czm_minimumDisableDepthTestDistance != 0.0) { disableDepthTestDistance = czm_minimumDisableDepthTestDistance; @@ -336,9 +325,19 @@ void main() } #endif +#ifdef CLAMP_TO_GROUND + v_eyeDepthDistanceAndApplyTranslate.x = eyeDepth; + v_eyeDepthDistanceAndApplyTranslate.y = disableDepthTestDistance; + v_eyeDepthDistanceAndApplyTranslate.z = applyTranslate; + v_originTextureCoordinateAndTranslate.xy = depthOrigin; + v_originTextureCoordinateAndTranslate.zw = translate; + v_textureCoordinateBounds = textureCoordinateBounds; + v_dimensionsAndImageSize.xy = dimensions * scale; + v_dimensionsAndImageSize.zw = imageSize * scale; +#endif + v_pickColor = pickColor; v_color = color; v_color.a *= translucency; - } From 8d905c6a8d8f05858e2bcb031d596902fcaf52fc Mon Sep 17 00:00:00 2001 From: hpinkos Date: Wed, 20 Jun 2018 13:55:21 -0400 Subject: [PATCH 10/12] fix rotation --- Source/Shaders/BillboardCollectionFS.glsl | 2 ++ Source/Shaders/BillboardCollectionVS.glsl | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/Source/Shaders/BillboardCollectionFS.glsl b/Source/Shaders/BillboardCollectionFS.glsl index 6f3734cd38ee..495c484f6d0c 100644 --- a/Source/Shaders/BillboardCollectionFS.glsl +++ b/Source/Shaders/BillboardCollectionFS.glsl @@ -13,6 +13,7 @@ varying vec4 v_textureCoordinateBounds; // the min and max x an varying vec4 v_originTextureCoordinateAndTranslate; // texture coordinate at the origin, billboard translate (used for label glyphs) varying vec4 v_dimensionsAndImageSize; // dimensions of the bounding rectangle and the size of the image. The values will only be different for label glyphs varying vec3 v_eyeDepthDistanceAndApplyTranslate; // The depth of the billboard and the disable depth test distance +varying mat2 v_rotationMatrix; float getGlobeDepth(vec2 adjustedST, vec2 depthLookupST) { @@ -20,6 +21,7 @@ float getGlobeDepth(vec2 adjustedST, vec2 depthLookupST) vec2 imageSize = v_dimensionsAndImageSize.zw; vec2 lookupVector = imageSize * (depthLookupST - adjustedST); + lookupVector = v_rotationMatrix * lookupVector; vec2 labelOffset = depthLookupST * (dimensions - imageSize) * vec2(1.0, 1.0 - v_originTextureCoordinateAndTranslate.y); // aligns label glyph with bounding rectangle. Will be zero for billboards because dimensions and imageSize will be equal vec2 translation = v_originTextureCoordinateAndTranslate.zw; diff --git a/Source/Shaders/BillboardCollectionVS.glsl b/Source/Shaders/BillboardCollectionVS.glsl index 9355caf93108..7ed335d58e03 100644 --- a/Source/Shaders/BillboardCollectionVS.glsl +++ b/Source/Shaders/BillboardCollectionVS.glsl @@ -23,6 +23,7 @@ varying vec4 v_textureCoordinateBounds; varying vec4 v_originTextureCoordinateAndTranslate; varying vec4 v_dimensionsAndImageSize; varying vec3 v_eyeDepthDistanceAndApplyTranslate; +varying mat2 v_rotationMatrix; #endif varying vec4 v_pickColor; @@ -71,6 +72,10 @@ vec4 addScreenSpaceOffset(vec4 positionEC, vec2 imageSize, float scale, vec2 dir float sinTheta = sin(angle); mat2 rotationMatrix = mat2(cosTheta, sinTheta, -sinTheta, cosTheta); halfSize = rotationMatrix * halfSize; + + #ifdef CLAMP_TO_GROUND + v_rotationMatrix = rotationMatrix; + #endif } #endif @@ -237,6 +242,7 @@ void main() #ifdef CLAMP_TO_GROUND float eyeDepth = positionEC.z; + v_rotationMatrix = mat2(1.0, 0.0, 0.0, 1.0); #endif positionEC = czm_eyeOffset(positionEC, eyeOffset.xyz); From 9493e4d41fe8e24b9864a369b8f4b7b4f2aadeac Mon Sep 17 00:00:00 2001 From: hpinkos Date: Wed, 20 Jun 2018 18:08:05 -0400 Subject: [PATCH 11/12] math --- Source/Shaders/BillboardCollectionFS.glsl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Shaders/BillboardCollectionFS.glsl b/Source/Shaders/BillboardCollectionFS.glsl index 495c484f6d0c..e306c2735cf5 100644 --- a/Source/Shaders/BillboardCollectionFS.glsl +++ b/Source/Shaders/BillboardCollectionFS.glsl @@ -22,7 +22,8 @@ float getGlobeDepth(vec2 adjustedST, vec2 depthLookupST) vec2 lookupVector = imageSize * (depthLookupST - adjustedST); lookupVector = v_rotationMatrix * lookupVector; - vec2 labelOffset = depthLookupST * (dimensions - imageSize) * vec2(1.0, 1.0 - v_originTextureCoordinateAndTranslate.y); // aligns label glyph with bounding rectangle. Will be zero for billboards because dimensions and imageSize will be equal + vec2 labelOffset = (dimensions - imageSize) * (depthLookupST - vec2(0.0, v_originTextureCoordinateAndTranslate.y)); // aligns label glyph with bounding rectangle. Will be zero for billboards because dimensions and imageSize will be equal + vec2 translation = v_originTextureCoordinateAndTranslate.zw; if (v_eyeDepthDistanceAndApplyTranslate.z != 0.0) From 4c3da3b2dbeb023d20279e1b24a962f32d450ebd Mon Sep 17 00:00:00 2001 From: hpinkos Date: Thu, 21 Jun 2018 14:40:08 -0400 Subject: [PATCH 12/12] size in meters --- Source/Shaders/BillboardCollectionVS.glsl | 110 +++++++++++----------- 1 file changed, 54 insertions(+), 56 deletions(-) diff --git a/Source/Shaders/BillboardCollectionVS.glsl b/Source/Shaders/BillboardCollectionVS.glsl index 7ed335d58e03..857d7368b59f 100644 --- a/Source/Shaders/BillboardCollectionVS.glsl +++ b/Source/Shaders/BillboardCollectionVS.glsl @@ -48,61 +48,6 @@ const float SHIFT_RIGHT3 = 1.0 / 8.0; const float SHIFT_RIGHT2 = 1.0 / 4.0; const float SHIFT_RIGHT1 = 1.0 / 2.0; -vec4 addScreenSpaceOffset(vec4 positionEC, vec2 imageSize, float scale, vec2 direction, vec2 origin, vec2 translate, vec2 pixelOffset, vec3 alignedAxis, bool validAlignedAxis, float rotation, bool sizeInMeters) -{ - // Note the halfSize cannot be computed in JavaScript because it is sent via - // compressed vertex attributes that coerce it to an integer. - vec2 halfSize = imageSize * scale * czm_resolutionScale * 0.5; - halfSize *= ((direction * 2.0) - 1.0); - - vec2 originTranslate = origin * abs(halfSize); - -#if defined(ROTATION) || defined(ALIGNED_AXIS) - if (validAlignedAxis || rotation != 0.0) - { - float angle = rotation; - if (validAlignedAxis) - { - vec4 projectedAlignedAxis = czm_modelViewProjection * vec4(alignedAxis, 0.0); - angle += sign(-projectedAlignedAxis.x) * acos( sign(projectedAlignedAxis.y) * (projectedAlignedAxis.y * projectedAlignedAxis.y) / - (projectedAlignedAxis.x * projectedAlignedAxis.x + projectedAlignedAxis.y * projectedAlignedAxis.y) ); - } - - float cosTheta = cos(angle); - float sinTheta = sin(angle); - mat2 rotationMatrix = mat2(cosTheta, sinTheta, -sinTheta, cosTheta); - halfSize = rotationMatrix * halfSize; - - #ifdef CLAMP_TO_GROUND - v_rotationMatrix = rotationMatrix; - #endif - } -#endif - - if (sizeInMeters) - { - positionEC.xy += halfSize; - } - - float mpp = czm_metersPerPixel(positionEC); - - if (!sizeInMeters) - { - originTranslate *= mpp; - } - - positionEC.xy += originTranslate; - if (!sizeInMeters) - { - positionEC.xy += halfSize * mpp; - } - - positionEC.xy += translate * mpp; - positionEC.xy += (pixelOffset * czm_resolutionScale) * mpp; - - return positionEC; -} - void main() { // Modifying this shader may also require modifications to Billboard._computeScreenSpacePosition @@ -299,7 +244,55 @@ void main() } #endif - positionEC = addScreenSpaceOffset(positionEC, imageSize, scale, direction, origin, translate, pixelOffset, alignedAxis, validAlignedAxis, rotation, sizeInMeters); + // Note the halfSize cannot be computed in JavaScript because it is sent via + // compressed vertex attributes that coerce it to an integer. + vec2 halfSize = imageSize * scale * czm_resolutionScale * 0.5; + halfSize *= ((direction * 2.0) - 1.0); + + vec2 originTranslate = origin * abs(halfSize); + +#if defined(ROTATION) || defined(ALIGNED_AXIS) + if (validAlignedAxis || rotation != 0.0) + { + float angle = rotation; + if (validAlignedAxis) + { + vec4 projectedAlignedAxis = czm_modelViewProjection * vec4(alignedAxis, 0.0); + angle += sign(-projectedAlignedAxis.x) * acos( sign(projectedAlignedAxis.y) * (projectedAlignedAxis.y * projectedAlignedAxis.y) / + (projectedAlignedAxis.x * projectedAlignedAxis.x + projectedAlignedAxis.y * projectedAlignedAxis.y) ); + } + + float cosTheta = cos(angle); + float sinTheta = sin(angle); + mat2 rotationMatrix = mat2(cosTheta, sinTheta, -sinTheta, cosTheta); + halfSize = rotationMatrix * halfSize; + + #ifdef CLAMP_TO_GROUND + v_rotationMatrix = rotationMatrix; + #endif + } +#endif + + if (sizeInMeters) + { + positionEC.xy += halfSize; + } + + float mpp = czm_metersPerPixel(positionEC); + + if (!sizeInMeters) + { + originTranslate *= mpp; + } + + positionEC.xy += originTranslate; + if (!sizeInMeters) + { + positionEC.xy += halfSize * mpp; + } + + positionEC.xy += translate * mpp; + positionEC.xy += (pixelOffset * czm_resolutionScale) * mpp; gl_Position = czm_projection * positionEC; v_textureCoordinates = textureCoordinates; @@ -332,6 +325,11 @@ void main() #endif #ifdef CLAMP_TO_GROUND + if (sizeInMeters) { + translate /= mpp; + dimensions /= mpp; + imageSize /= mpp; + } v_eyeDepthDistanceAndApplyTranslate.x = eyeDepth; v_eyeDepthDistanceAndApplyTranslate.y = disableDepthTestDistance; v_eyeDepthDistanceAndApplyTranslate.z = applyTranslate;