From 0317622bd94679860c586d85beb09ab893327452 Mon Sep 17 00:00:00 2001 From: Kangning Li Date: Tue, 30 Jan 2018 09:59:09 -0500 Subject: [PATCH 01/32] proof-of-concept oct32 normals and in-shader transform for clipping planes by texture --- Apps/Sandcastle/gallery/clipping circle.html | 167 +++++++++++++++++ Source/Core/ClippingPlaneCollection.js | 169 ++++++++++++++---- Source/Scene/Model.js | 80 ++++++--- .../Builtin/Constants/maxClippingPlanes.glsl | 2 +- .../discardIfClippedWithIntersect.glsl | 10 +- .../Functions/discardIfClippedWithUnion.glsl | 8 +- .../getClippingPlaneFromTexture.glsl | 28 +++ .../Shaders/Builtin/Functions/octDecode.glsl | 10 +- 8 files changed, 401 insertions(+), 73 deletions(-) create mode 100644 Apps/Sandcastle/gallery/clipping circle.html create mode 100644 Source/Shaders/Builtin/Functions/getClippingPlaneFromTexture.glsl diff --git a/Apps/Sandcastle/gallery/clipping circle.html b/Apps/Sandcastle/gallery/clipping circle.html new file mode 100644 index 000000000000..efe777c08ead --- /dev/null +++ b/Apps/Sandcastle/gallery/clipping circle.html @@ -0,0 +1,167 @@ + + + + + + + + + Cesium Demo + + + + + + +
+

Loading...

+
+ + + diff --git a/Source/Core/ClippingPlaneCollection.js b/Source/Core/ClippingPlaneCollection.js index e2d9e44f5837..5d6122e43fb8 100644 --- a/Source/Core/ClippingPlaneCollection.js +++ b/Source/Core/ClippingPlaneCollection.js @@ -1,6 +1,9 @@ define([ + './AttributeCompression', + './Cartesian2', './Cartesian3', './Cartesian4', + './Math', './Check', './Color', './defaultValue', @@ -9,10 +12,20 @@ define([ './DeveloperError', './Intersect', './Matrix4', - './Plane' + './PixelFormat', + './Plane', + '../Renderer/PixelDatatype', + '../Renderer/Sampler', + '../Renderer/Texture', + '../Renderer/TextureMagnificationFilter', + '../Renderer/TextureMinificationFilter', + '../Renderer/TextureWrap' ], function( + AttributeCompression, + Cartesian2, Cartesian3, Cartesian4, + CesiumMath, Check, Color, defaultValue, @@ -21,7 +34,14 @@ define([ DeveloperError, Intersect, Matrix4, - Plane) { + PixelFormat, + Plane, + PixelDatatype, + Sampler, + Texture, + TextureMagnificationFilter, + TextureMinificationFilter, + TextureWrap) { 'use strict'; /** @@ -82,9 +102,18 @@ define([ */ this.edgeWidth = defaultValue(options.edgeWidth, 0.0); + /** + * Range for inflating the normalized distances in the clipping plane texture + * + * @type {Cartesian2} + */ + this.distanceRange = new Cartesian2(); + this._testIntersection = undefined; this._unionClippingRegions = undefined; this.unionClippingRegions = defaultValue(options.unionClippingRegions, false); + + this._rgbaUbytePixels = new Uint8Array(ClippingPlaneCollection.TEXTURE_WIDTH * ClippingPlaneCollection.TEXTURE_WIDTH * 4); } function unionIntersectFunction(value) { @@ -235,50 +264,96 @@ define([ this._planes = []; }; - var scratchPlane = new Plane(Cartesian3.UNIT_X, 0.0); - var scratchMatrix = new Matrix4(); + // See Aras Pranckevičius' post Encoding Floats to RGBA + // http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ + var floatEncode = new Cartesian4(1.0, 255.0, 65025.0, 16581375.0); + function packNormalizedFloat(float, result) { + Cartesian4.multiplyByScalar(floatEncode, float, result); + result.x = result.x - Math.floor(result.x); + result.y = result.y - Math.floor(result.y); + result.z = result.z - Math.floor(result.z); + result.w = result.w - Math.floor(result.w); + + result.x -= result.y / 255.0; + result.y -= result.z / 255.0; + result.z -= result.w / 255.0; + + return result; + } + + var encodingScratch = new Cartesian4(); + function insertFloat(uint8Buffer, float, byteIndex) { + packNormalizedFloat(float, encodingScratch); + uint8Buffer[byteIndex] = encodingScratch.x * 255; + uint8Buffer[byteIndex + 1] = encodingScratch.y * 255; + uint8Buffer[byteIndex + 2] = encodingScratch.z * 255; + uint8Buffer[byteIndex + 3] = encodingScratch.w * 255; + } + + var octEncodeScratch = new Cartesian2(); + var rightShift = 1.0 / 256; /** - * Applies the transformations to each plane and packs it into an array. + * Encodes a normalized vector into 4 SNORM values in the range [0-255] following the 'oct' encoding. + */ + function oct32EncodeNormal(vector, result) { + AttributeCompression.octEncodeInRange(vector, 65535, octEncodeScratch); + result.x = octEncodeScratch.x * rightShift; + result.y = octEncodeScratch.x; + result.z = octEncodeScratch.y * rightShift; + result.w = octEncodeScratch.y; + return result; + } + + var oct32EncodeScratch = new Cartesian4(); + /** + * Applies the transformations to each plane and packs it into a typed array for transfer to a texture. * @private * - * @param {Matrix4} viewMatrix The 4x4 matrix to transform the plane into eyespace. - * @param {Cartesian4[]} [array] The array into which the planes will be packed. - * @returns {Cartesian4[]} The array of packed planes. + * @returns {Uint8Array} Typed Array representing the clipping planes packed to a RGBA Uint8 texture. */ - ClippingPlaneCollection.prototype.transformAndPackPlanes = function(viewMatrix, array) { - //>>includeStart('debug', pragmas.debug); - Check.typeOf.object('viewMatrix', viewMatrix); - //>>includeEnd('debug'); + ClippingPlaneCollection.prototype.transformAndPackPlanes = function() { + var rgbaUbytePixels = this._rgbaUbytePixels; var planes = this._planes; var length = planes.length; + var distances = new Array(length); - var index = 0; - if (!defined(array)) { - array = new Array(length); - } else { - index = array.length; - array.length = length; - } - + // Transform all planes, recording the directions in the typed array and computing the range for the planes + var distanceMin = Number.POSITIVE_INFINITY; + var distanceMax = Number.NEGATIVE_INFINITY; var i; - for (i = index; i < length; ++i) { - array[i] = new Cartesian4(); - } - - var transform = Matrix4.multiply(viewMatrix, this.modelMatrix, scratchMatrix); - for (i = 0; i < length; ++i) { var plane = planes[i]; - var packedPlane = array[i]; - Plane.transform(plane, transform, scratchPlane); + var byteIndex = i * 8; + + var oct32Normal = oct32EncodeNormal(plane.normal, oct32EncodeScratch); + rgbaUbytePixels[byteIndex] = oct32Normal.x; + rgbaUbytePixels[byteIndex + 1] = oct32Normal.y; + rgbaUbytePixels[byteIndex + 2] = oct32Normal.z; + rgbaUbytePixels[byteIndex + 3] = oct32Normal.w; - Cartesian3.clone(scratchPlane.normal, packedPlane); - packedPlane.w = scratchPlane.distance; + var distance = plane.distance; + distanceMin = Math.min(distance, distanceMin); + distanceMax = Math.max(distance, distanceMax); + distances[i] = distance; } - return array; + // expand distance range a little bit to prevent packing 1s + distanceMax += (distanceMax - distanceMin) * CesiumMath.EPSILON3; + + // Normalize all the distances to the range and record them in the typed array. + var distanceRange = this.distanceRange; + distanceRange.x = distanceMin; + distanceRange.y = distanceMax; + var distanceRangeSize = distanceMax - distanceMin; + for (i = 0; i < length; ++i) { + var normalizedDistance = (distances[i] - distanceMin) / distanceRangeSize; + var byteIndex = i * 8 + 4; + insertFloat(rgbaUbytePixels, normalizedDistance, byteIndex); + } + + return rgbaUbytePixels; }; /** @@ -317,6 +392,8 @@ define([ return result; }; + var scratchMatrix = new Matrix4(); + var scratchPlane = new Plane(Cartesian3.UNIT_X, 0.0); /** * Determines the type intersection with the planes of this ClippingPlaneCollection instance and the specified {@link BoundingVolume}. * @private @@ -365,10 +442,38 @@ define([ /** * The maximum number of supported clipping planes. * + * @see maxClippingPlanes.glsl + * @type {number} + * @constant + */ + ClippingPlaneCollection.MAX_CLIPPING_PLANES = 128; + + /** + * The pixel width of a square, power-of-two RGBA UNSIGNED_BYTE texture + * with enough pixels to support MAX_CLIPPING_PLANES. + * + * A plane is a float in [0, 1) packed to RGBA and an Oct32 quantized normal, so 8 bits or 2 pixels in RGBA + * * @type {number} * @constant */ - ClippingPlaneCollection.MAX_CLIPPING_PLANES = 6; + ClippingPlaneCollection.TEXTURE_WIDTH = CesiumMath.nextPowerOfTwo(Math.ceil(Math.sqrt(ClippingPlaneCollection.MAX_CLIPPING_PLANES * 2))); + + ClippingPlaneCollection.getTextureParameters = function(context) { + return { + context : context, + width : ClippingPlaneCollection.TEXTURE_WIDTH, + height : ClippingPlaneCollection.TEXTURE_WIDTH, + pixelFormat : PixelFormat.RGBA, + pixelDatatype : PixelDatatype.UNSIGNED_BYTE, + sampler : new Sampler({ + wrapS : TextureWrap.CLAMP_TO_EDGE, + wrapT : TextureWrap.CLAMP_TO_EDGE, + minificationFilter : TextureMinificationFilter.NEAREST, + magnificationFilter : TextureMagnificationFilter.NEAREST + }) + } + } return ClippingPlaneCollection; }); diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 59678a227458..5a316c97f144 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -5,6 +5,7 @@ define([ '../Core/Cartesian4', '../Core/Cartographic', '../Core/clone', + '../Core/ClippingPlaneCollection', '../Core/Color', '../Core/combine', '../Core/defaultValue', @@ -82,6 +83,7 @@ define([ Cartesian4, Cartographic, clone, + ClippingPlaneCollection, Color, combine, defaultValue, @@ -706,7 +708,7 @@ define([ this._rtcCenter3D = undefined; // in world coordinates this._rtcCenter2D = undefined; // in projected world coordinates - this._packedClippingPlanes = []; + this._packedClippingPlanes = undefined; // texture of clipping planes } defineProperties(Model.prototype, { @@ -3319,31 +3321,49 @@ define([ function createClippingPlanesLengthFunction(model) { return function() { - return model._packedClippingPlanes.length; + var clippingPlanes = model.clippingPlanes; + if (!defined(clippingPlanes)) { + return 0; + } + return clippingPlanes.length; }; } - function createClippingPlanesUnionRegionsFunction(model) { + var scratchClippingPlaneMatrix = new Matrix4(); + function createClippingPlanesMatrixFunction(model) { return function() { var clippingPlanes = model.clippingPlanes; if (!defined(clippingPlanes)) { - return false; + return Matrix4.IDENTITY; } - - return clippingPlanes.unionClippingRegions; + return Matrix4.multiply(model._modelViewMatrix, clippingPlanes.modelMatrix, scratchClippingPlaneMatrix) }; } function createClippingPlanesFunction(model) { + return function() { + return model._packedClippingPlanes; + }; + } + + function createClippingPlanesRangeFunction(model) { return function() { var clippingPlanes = model.clippingPlanes; - var packedPlanes = model._packedClippingPlanes; + if (!defined(clippingPlanes)) { + return Cartesian2.ZERO; + } + return clippingPlanes.distanceRange; + }; + } - if (defined(clippingPlanes) && clippingPlanes.enabled) { - clippingPlanes.transformAndPackPlanes(model._modelViewMatrix, packedPlanes); + function createClippingPlanesUnionRegionsFunction(model) { + return function() { + var clippingPlanes = model.clippingPlanes; + if (!defined(clippingPlanes)) { + return false; } - return packedPlanes; + return clippingPlanes.unionClippingRegions; }; } @@ -3457,8 +3477,10 @@ define([ gltf_colorBlend : createColorBlendFunction(model), gltf_clippingPlanesLength: createClippingPlanesLengthFunction(model), gltf_clippingPlanesUnionRegions: createClippingPlanesUnionRegionsFunction(model), - gltf_clippingPlanes: createClippingPlanesFunction(model, context), - gltf_clippingPlanesEdgeStyle: createClippingPlanesEdgeStyleFunction(model) + gltf_clippingPlanes: createClippingPlanesFunction(model), + gltf_clippingPlanesRange: createClippingPlanesRangeFunction(model), + gltf_clippingPlanesEdgeStyle: createClippingPlanesEdgeStyleFunction(model), + gltf_clippingPlanesMatrix: createClippingPlanesMatrixFunction(model) }); // Allow callback to modify the uniformMap @@ -3751,6 +3773,8 @@ define([ createUniformMaps(model, context); // using glTF materials/techniques createRuntimeNodes(model, context, scene3DOnly); // using glTF scene + + model._packedClippingPlanes = new Texture(ClippingPlaneCollection.getTextureParameters(context)); } /////////////////////////////////////////////////////////////////////////// @@ -4255,10 +4279,13 @@ define([ function modifyShaderForClippingPlanes(shader) { shader = ShaderSource.replaceMain(shader, 'gltf_clip_main'); shader += + '#define PLANES_TEXTURE_WIDTH ' + ClippingPlaneCollection.TEXTURE_WIDTH + '\n' + 'uniform int gltf_clippingPlanesLength; \n' + 'uniform bool gltf_clippingPlanesUnionRegions; \n' + - 'uniform vec4 gltf_clippingPlanes[czm_maxClippingPlanes]; \n' + + 'uniform sampler2D gltf_clippingPlanes; \n' + + 'uniform vec2 gltf_clippingPlanesRange; \n' + 'uniform vec4 gltf_clippingPlanesEdgeStyle; \n' + + 'uniform mat4 gltf_clippingPlanesMatrix; \n' + 'void main() \n' + '{ \n' + ' gltf_clip_main(); \n' + @@ -4267,11 +4294,11 @@ define([ ' float clipDistance; \n' + ' if (gltf_clippingPlanesUnionRegions) \n' + ' { \n' + - ' clipDistance = czm_discardIfClippedWithUnion(gltf_clippingPlanes, gltf_clippingPlanesLength); \n' + + ' clipDistance = czm_discardIfClippedWithUnion(gltf_clippingPlanes, gltf_clippingPlanesLength, gltf_clippingPlanesRange, PLANES_TEXTURE_WIDTH, gltf_clippingPlanesMatrix); \n' + ' } \n' + ' else \n' + ' { \n' + - ' clipDistance = czm_discardIfClippedWithIntersect(gltf_clippingPlanes, gltf_clippingPlanesLength); \n' + + ' clipDistance = czm_discardIfClippedWithIntersect(gltf_clippingPlanes, gltf_clippingPlanesLength, gltf_clippingPlanesRange, PLANES_TEXTURE_WIDTH, gltf_clippingPlanesMatrix); \n' + ' } \n' + ' \n' + ' vec4 clippingPlanesEdgeColor = vec4(1.0); \n' + @@ -4279,7 +4306,7 @@ define([ ' float clippingPlanesEdgeWidth = gltf_clippingPlanesEdgeStyle.a; \n' + ' if (clipDistance > 0.0 && clipDistance < clippingPlanesEdgeWidth) \n' + ' { \n' + - ' gl_FragColor = clippingPlanesEdgeColor; \n' + + ' gl_FragColor = clippingPlanesEdgeColor;\n' + ' } \n' + ' } \n' + '} \n'; @@ -4311,19 +4338,12 @@ define([ function updateClippingPlanes(model) { var clippingPlanes = model.clippingPlanes; - var length = 0; if (defined(clippingPlanes) && clippingPlanes.enabled) { - length = clippingPlanes.length; - } - - var packedPlanes = model._packedClippingPlanes; - var packedLength = packedPlanes.length; - if (packedLength !== length) { - packedPlanes.length = length; - - for (var i = packedLength; i < length; ++i) { - packedPlanes[i] = new Cartesian4(); - } + model._packedClippingPlanes.copyFrom({ + width : ClippingPlaneCollection.TEXTURE_WIDTH, + height : ClippingPlaneCollection.TEXTURE_WIDTH, + arrayBufferView : clippingPlanes.transformAndPackPlanes() + }); } } @@ -4796,7 +4816,7 @@ define([ updateShadows(this); updateColor(this, frameState); updateSilhouette(this, frameState); - updateClippingPlanes(this, frameState); + updateClippingPlanes(this); } if (justLoaded) { @@ -4934,6 +4954,8 @@ define([ releaseCachedGltf(this); + this._packedClippingPlanes.destroy(); + return destroyObject(this); }; diff --git a/Source/Shaders/Builtin/Constants/maxClippingPlanes.glsl b/Source/Shaders/Builtin/Constants/maxClippingPlanes.glsl index 30c377df1668..f09ae838587d 100644 --- a/Source/Shaders/Builtin/Constants/maxClippingPlanes.glsl +++ b/Source/Shaders/Builtin/Constants/maxClippingPlanes.glsl @@ -5,4 +5,4 @@ * @glslConstant * @see czm_clipPlanes */ -const int czm_maxClippingPlanes = 6; +const int czm_maxClippingPlanes = 128; diff --git a/Source/Shaders/Builtin/Functions/discardIfClippedWithIntersect.glsl b/Source/Shaders/Builtin/Functions/discardIfClippedWithIntersect.glsl index 987dd8d354c8..36146573cbec 100644 --- a/Source/Shaders/Builtin/Functions/discardIfClippedWithIntersect.glsl +++ b/Source/Shaders/Builtin/Functions/discardIfClippedWithIntersect.glsl @@ -9,7 +9,7 @@ * @param {int} clippingPlanesLength The number of planes in the array of clipping planes. * @returns {float} The distance away from a clipped fragment, in eyespace */ -float czm_discardIfClippedWithIntersect(vec4 clippingPlanes[czm_maxClippingPlanes], int clippingPlanesLength) +float czm_discardIfClippedWithIntersect(sampler2D clippingPlanes, int clippingPlanesLength, vec2 range, int textureWidth, mat4 clippingPlanesMatrix) { if (clippingPlanesLength > 0) { @@ -27,8 +27,12 @@ float czm_discardIfClippedWithIntersect(vec4 clippingPlanes[czm_maxClippingPlane break; } - clipNormal = clippingPlanes[i].xyz; - clipPosition = -clippingPlanes[i].w * clipNormal; + vec4 clippingPlane = czm_getClippingPlaneFromTexture(clippingPlanes, range, i, textureWidth, clippingPlanesMatrix); + //clipNormal = normalize((czm_modelView * vec4(0.99999999995, 0.000009999999999833334, 0, 0.0)).xyz); + clipNormal = clippingPlane.xyz; + + //clipPosition = -range.x * clipNormal; + clipPosition = -clippingPlane.w * clipNormal; float amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth; clipAmount = max(amount, clipAmount); diff --git a/Source/Shaders/Builtin/Functions/discardIfClippedWithUnion.glsl b/Source/Shaders/Builtin/Functions/discardIfClippedWithUnion.glsl index ae6110f8346f..367d54cb3dd6 100644 --- a/Source/Shaders/Builtin/Functions/discardIfClippedWithUnion.glsl +++ b/Source/Shaders/Builtin/Functions/discardIfClippedWithUnion.glsl @@ -9,7 +9,7 @@ * @param {int} clippingPlanesLength The number of planes in the array of clipping planes. * @returns {float} The distance away from a clipped fragment, in eyespace */ -float czm_discardIfClippedWithUnion(vec4 clippingPlanes[czm_maxClippingPlanes], int clippingPlanesLength) +float czm_discardIfClippedWithUnion(sampler2D clippingPlanes, int clippingPlanesLength, vec2 range, int textureWidth, mat4 clippingPlanesMatrix) { if (clippingPlanesLength > 0) { @@ -26,8 +26,10 @@ float czm_discardIfClippedWithUnion(vec4 clippingPlanes[czm_maxClippingPlanes], break; } - clipNormal = clippingPlanes[i].xyz; - clipPosition = -clippingPlanes[i].w * clipNormal; + vec4 clippingPlane = czm_getClippingPlaneFromTexture(clippingPlanes, range, i, textureWidth, clippingPlanesMatrix); + + clipNormal = clippingPlane.xyz; + clipPosition = -clippingPlane.w * clipNormal; float amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth; clipAmount = max(amount, clipAmount); diff --git a/Source/Shaders/Builtin/Functions/getClippingPlaneFromTexture.glsl b/Source/Shaders/Builtin/Functions/getClippingPlaneFromTexture.glsl new file mode 100644 index 000000000000..54cb1efc32e6 --- /dev/null +++ b/Source/Shaders/Builtin/Functions/getClippingPlaneFromTexture.glsl @@ -0,0 +1,28 @@ +vec4 transformPlane(mat4 transform, vec4 clippingPlane) { + vec3 transformedDirection = normalize((transform * vec4(clippingPlane.xyz, 0.0)).xyz); + vec3 transformedPosition = (transform * vec4(clippingPlane.xyz * -clippingPlane.w, 1.0)).xyz; + vec4 transformedPlane; + transformedPlane.xyz = transformedDirection; + transformedPlane.w = -dot(transformedDirection, transformedPosition); + return transformedPlane; +} + +vec4 czm_getClippingPlaneFromTexture(sampler2D packedClippingPlanes, vec2 range, int clippingPlaneNumber, int textureWidth, mat4 transform) +{ + int clippingPlaneStartIndex = clippingPlaneNumber * 2; // clipping planes are two pixels each + int pixY = clippingPlaneStartIndex / textureWidth; + int pixX = clippingPlaneStartIndex - (pixY * textureWidth); + pixY = textureWidth - pixY; // flipped relative to texture + float pixelWidth = 1.0 / float(textureWidth); + float u = (float(pixX) + 0.5) * pixelWidth; // sample from center of pixel + float v = (float(pixY) - 0.5) * pixelWidth; + + vec4 oct32 = texture2D(packedClippingPlanes, vec2(u, v)) * 255.0; + vec2 oct = vec2(oct32.x * 256.0 + oct32.y, oct32.z * 256.0 + oct32.w); + + vec4 plane; + plane.xyz = czm_octDecode(oct, 65535.0); + plane.w = czm_unpackDepth(texture2D(packedClippingPlanes, vec2(u + pixelWidth, v))) * (range.y - range.x) + range.x; + + return transformPlane(transform, plane); +} diff --git a/Source/Shaders/Builtin/Functions/octDecode.glsl b/Source/Shaders/Builtin/Functions/octDecode.glsl index ce4df362da12..98b2736f706a 100644 --- a/Source/Shaders/Builtin/Functions/octDecode.glsl +++ b/Source/Shaders/Builtin/Functions/octDecode.glsl @@ -28,7 +28,7 @@ * Decodes a unit-length vector in 'oct' encoding to a normalized 3-component Cartesian vector. * The 'oct' encoding is described in "A Survey of Efficient Representations of Independent Unit Vectors", * Cigolle et al 2014: http://jcgt.org/published/0003/02/01/ - * + * * @name czm_octDecode * @param {vec2} encoded The oct-encoded, unit-length vector * @returns {vec3} The decoded and normalized vector @@ -42,7 +42,7 @@ * Decodes a unit-length vector in 'oct' encoding packed into a floating-point number to a normalized 3-component Cartesian vector. * The 'oct' encoding is described in "A Survey of Efficient Representations of Independent Unit Vectors", * Cigolle et al 2014: http://jcgt.org/published/0003/02/01/ - * + * * @name czm_octDecode * @param {float} encoded The oct-encoded, unit-length vector * @returns {vec3} The decoded and normalized vector @@ -54,12 +54,12 @@ float y = (temp - x) * 256.0; return czm_octDecode(vec2(x, y)); } - + /** * Decodes three unit-length vectors in 'oct' encoding packed into two floating-point numbers to normalized 3-component Cartesian vectors. * The 'oct' encoding is described in "A Survey of Efficient Representations of Independent Unit Vectors", * Cigolle et al 2014: http://jcgt.org/published/0003/02/01/ - * + * * @name czm_octDecode * @param {vec2} encoded The packed oct-encoded, unit-length vectors. * @param {vec3} vector1 One decoded and normalized vector. @@ -80,4 +80,4 @@ vector2 = czm_octDecode(encodedFloat2); vector3 = czm_octDecode(vec2(x, y)); } - + From 44a266295134b88c3d3dadf0d1bba3ece61d2136 Mon Sep 17 00:00:00 2001 From: Kangning Li Date: Thu, 1 Feb 2018 16:51:22 -0500 Subject: [PATCH 02/32] proof-of-concept for sharing ClippingPlaneCollections over b3dm tilesets and update-as-needed --- Apps/Sandcastle/gallery/clipping circle.html | 223 ++++++++++-------- Source/Core/ClippingPlaneCollection.js | 179 ++++++++++++-- Source/Scene/Batched3DModel3DTileContent.js | 15 +- Source/Scene/Cesium3DTileset.js | 19 ++ Source/Scene/Model.js | 26 +- .../Builtin/Constants/maxClippingPlanes.glsl | 2 +- 6 files changed, 320 insertions(+), 144 deletions(-) diff --git a/Apps/Sandcastle/gallery/clipping circle.html b/Apps/Sandcastle/gallery/clipping circle.html index efe777c08ead..3f3d2b549048 100644 --- a/Apps/Sandcastle/gallery/clipping circle.html +++ b/Apps/Sandcastle/gallery/clipping circle.html @@ -24,7 +24,18 @@

Loading...

-
+
+ + + + + +
Spiral Size + + +
+ +