Skip to content

Commit 50b1d5d

Browse files
authored
Merge pull request #5851 from geoscan/log-depth-buffer
Log depth buffer
2 parents bb5306a + d7d14a5 commit 50b1d5d

File tree

71 files changed

+1143
-385
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+1143
-385
lines changed

CHANGES.md

+8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ Change Log
33

44
### 1.45 - 2018-05-01
55

6+
##### Breaking Changes :mega:
7+
* `Camera.distanceToBoundingSphere` now returns the signed distance to the bounding sphere. Positive values indicate that the bounding sphere is in the positive half-plane of the camera position and view direction while a negative value indicates it is in the negative half-plane.
8+
9+
##### Additions :tada:
10+
* Added option `logDepthBuffer` to `Viewer`. With this option there is typically a single frustum using logarithmic depth rendered. This increases performance by issuing less draw calls to the GPU and helps to avoid artifacts on the connection of two frustums. [#5851](https://github.com/AnalyticalGraphicsInc/cesium/pull/5851)
11+
* When a log depth buffer is supported, the frustum near and far planes default to `0.1` and `1e10` respectively.
12+
* Added `Math.log2` to compute the base 2 logarithm of a number.
13+
614
##### Fixes :wrench:
715
* Fixed bugs in `TimeIntervalCollection.removeInterval`. [#6418](https://github.com/AnalyticalGraphicsInc/cesium/pull/6418).
816
* Fixed glTF support to handle meshes with and without tangent vectors, and with/without morph targets, sharing one material. [#6421](https://github.com/AnalyticalGraphicsInc/cesium/pull/6421)

CONTRIBUTORS.md

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu
7373
* [Dave Whipps](https://github.com/dwhipps)
7474
* [Geoscan](https://www.geoscan.aero)
7575
* [Andrey Orlov](https://github.com/AndreyOrlov)
76+
* [George Vinokhodov](https://github.com/Vineg)
7677
* [The Imagineers](https://www.theimagineers.com/)
7778
* [Heerco Grond](https://github.com/HeercoGrond)
7879
* [Camptocamp SA](https://www.camptocamp.com/)

Source/Core/Math.js

+12
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,18 @@ define([
849849
*/
850850
CesiumMath.cbrt = defined(Math.cbrt) ? Math.cbrt : cbrt;
851851

852+
function log2(x) {
853+
return Math.log(x) * Math.LOG2E;
854+
}
855+
856+
/**
857+
* Finds the base 2 logarithm of a number.
858+
*
859+
* @param {Number} number The number.
860+
* @returns {Number} The result.
861+
*/
862+
CesiumMath.log2 = defined(Math.log2) ? Math.log2 : log2;
863+
852864
/**
853865
* @private
854866
*/

Source/Core/OrthographicFrustum.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ define([
259259
* @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise.
260260
*/
261261
OrthographicFrustum.prototype.equals = function(other) {
262-
if (!defined(other)) {
262+
if (!defined(other) || !(other instanceof OrthographicFrustum)) {
263263
return false;
264264
}
265265

Source/Core/OrthographicOffCenterFrustum.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ define([
361361
* @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise.
362362
*/
363363
OrthographicOffCenterFrustum.prototype.equals = function(other) {
364-
return (defined(other) &&
364+
return (defined(other) && other instanceof OrthographicOffCenterFrustum &&
365365
this.right === other.right &&
366366
this.left === other.left &&
367367
this.top === other.top &&

Source/Core/PerspectiveFrustum.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ define([
354354
* @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise.
355355
*/
356356
PerspectiveFrustum.prototype.equals = function(other) {
357-
if (!defined(other)) {
357+
if (!defined(other) || !(other instanceof PerspectiveFrustum)) {
358358
return false;
359359
}
360360

Source/Core/PerspectiveOffCenterFrustum.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ define([
412412
* @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise.
413413
*/
414414
PerspectiveOffCenterFrustum.prototype.equals = function(other) {
415-
return (defined(other) &&
415+
return (defined(other) && other instanceof PerspectiveOffCenterFrustum &&
416416
this.right === other.right &&
417417
this.left === other.left &&
418418
this.top === other.top &&

Source/Core/barycentricCoordinates.js

+52-23
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ define([
22
'./Cartesian2',
33
'./Cartesian3',
44
'./Check',
5-
'./defined'
5+
'./defined',
6+
'./Math'
67
], function(
78
Cartesian2,
89
Cartesian3,
910
Check,
10-
defined) {
11+
defined,
12+
CesiumMath) {
1113
'use strict';
1214

1315
var scratchCartesian1 = new Cartesian3();
@@ -47,34 +49,61 @@ define([
4749
}
4850

4951
// Implementation based on http://www.blackpawn.com/texts/pointinpoly/default.html.
50-
var v0, v1, v2;
51-
var dot00, dot01, dot02, dot11, dot12;
52+
var v0;
53+
var v1;
54+
var v2;
55+
var dot00;
56+
var dot01;
57+
var dot02;
58+
var dot11;
59+
var dot12;
5260

5361
if(!defined(p0.z)) {
54-
v0 = Cartesian2.subtract(p1, p0, scratchCartesian1);
55-
v1 = Cartesian2.subtract(p2, p0, scratchCartesian2);
56-
v2 = Cartesian2.subtract(point, p0, scratchCartesian3);
62+
if (Cartesian2.equalsEpsilon(point, p0, CesiumMath.EPSILON14)) {
63+
return Cartesian3.clone(Cartesian3.UNIT_X, result);
64+
}
65+
if (Cartesian2.equalsEpsilon(point, p1, CesiumMath.EPSILON14)) {
66+
return Cartesian3.clone(Cartesian3.UNIT_Y, result);
67+
}
68+
if (Cartesian2.equalsEpsilon(point, p2, CesiumMath.EPSILON14)) {
69+
return Cartesian3.clone(Cartesian3.UNIT_Z, result);
70+
}
5771

58-
dot00 = Cartesian2.dot(v0, v0);
59-
dot01 = Cartesian2.dot(v0, v1);
60-
dot02 = Cartesian2.dot(v0, v2);
61-
dot11 = Cartesian2.dot(v1, v1);
62-
dot12 = Cartesian2.dot(v1, v2);
72+
v0 = Cartesian2.subtract(p1, p0, scratchCartesian1);
73+
v1 = Cartesian2.subtract(p2, p0, scratchCartesian2);
74+
v2 = Cartesian2.subtract(point, p0, scratchCartesian3);
75+
76+
dot00 = Cartesian2.dot(v0, v0);
77+
dot01 = Cartesian2.dot(v0, v1);
78+
dot02 = Cartesian2.dot(v0, v2);
79+
dot11 = Cartesian2.dot(v1, v1);
80+
dot12 = Cartesian2.dot(v1, v2);
6381
} else {
64-
v0 = Cartesian3.subtract(p1, p0, scratchCartesian1);
65-
v1 = Cartesian3.subtract(p2, p0, scratchCartesian2);
66-
v2 = Cartesian3.subtract(point, p0, scratchCartesian3);
82+
if (Cartesian3.equalsEpsilon(point, p0, CesiumMath.EPSILON14)) {
83+
return Cartesian3.clone(Cartesian3.UNIT_X, result);
84+
}
85+
if (Cartesian3.equalsEpsilon(point, p1, CesiumMath.EPSILON14)) {
86+
return Cartesian3.clone(Cartesian3.UNIT_Y, result);
87+
}
88+
if (Cartesian3.equalsEpsilon(point, p2, CesiumMath.EPSILON14)) {
89+
return Cartesian3.clone(Cartesian3.UNIT_Z, result);
90+
}
91+
92+
v0 = Cartesian3.subtract(p1, p0, scratchCartesian1);
93+
v1 = Cartesian3.subtract(p2, p0, scratchCartesian2);
94+
v2 = Cartesian3.subtract(point, p0, scratchCartesian3);
6795

68-
dot00 = Cartesian3.dot(v0, v0);
69-
dot01 = Cartesian3.dot(v0, v1);
70-
dot02 = Cartesian3.dot(v0, v2);
71-
dot11 = Cartesian3.dot(v1, v1);
72-
dot12 = Cartesian3.dot(v1, v2);
96+
dot00 = Cartesian3.dot(v0, v0);
97+
dot01 = Cartesian3.dot(v0, v1);
98+
dot02 = Cartesian3.dot(v0, v2);
99+
dot11 = Cartesian3.dot(v1, v1);
100+
dot12 = Cartesian3.dot(v1, v2);
73101
}
74102

75-
var q = 1.0 / (dot00 * dot11 - dot01 * dot01);
76-
result.y = (dot11 * dot02 - dot01 * dot12) * q;
77-
result.z = (dot00 * dot12 - dot01 * dot02) * q;
103+
var q = dot00 * dot11 - dot01 * dot01;
104+
var invQ = 1.0 / q;
105+
result.y = (dot11 * dot02 - dot01 * dot12) * invQ;
106+
result.z = (dot00 * dot12 - dot01 * dot02) * invQ;
78107
result.x = 1.0 - result.y - result.z;
79108
return result;
80109
}

Source/Renderer/AutomaticUniforms.js

+16
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,22 @@ define([
11351135
}
11361136
}),
11371137

1138+
/**
1139+
* The log of the current frustums far plane. Used for computing the log depth.
1140+
*
1141+
* @alias czm_logFarDistance
1142+
* @glslUniform
1143+
*
1144+
* @private
1145+
*/
1146+
czm_logFarDistance : new AutomaticUniform({
1147+
size : 1,
1148+
datatype : WebGLConstants.FLOAT,
1149+
getValue : function(uniformState) {
1150+
return uniformState.logFarDistance;
1151+
}
1152+
}),
1153+
11381154
/**
11391155
* An automatic GLSL uniform representing the sun position in world coordinates.
11401156
*

Source/Renderer/UniformState.js

+14
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ define([
6161
this._entireFrustum = new Cartesian2();
6262
this._currentFrustum = new Cartesian2();
6363
this._frustumPlanes = new Cartesian4();
64+
this._logFarDistance = undefined;
6465

6566
this._frameState = undefined;
6667
this._temeToPseudoFixed = Matrix3.clone(Matrix4.IDENTITY);
@@ -641,6 +642,17 @@ define([
641642
}
642643
},
643644

645+
/**
646+
* The log of the current frustum's far distance. Used to compute the log depth.
647+
* @memberof UniformState.prototype
648+
* @type {Number}
649+
*/
650+
logFarDistance : {
651+
get : function() {
652+
return this._logFarDistance;
653+
}
654+
},
655+
644656
/**
645657
* The the height (<code>x</code>) and the height squared (<code>y</code>)
646658
* in meters of the camera above the 2D world plane. This uniform is only valid
@@ -987,6 +999,8 @@ define([
987999
this._currentFrustum.x = frustum.near;
9881000
this._currentFrustum.y = frustum.far;
9891001

1002+
this._logFarDistance = 2.0 / CesiumMath.log2(frustum.far + 1.0);
1003+
9901004
if (defined(frustum._offCenterFrustum)) {
9911005
frustum = frustum._offCenterFrustum;
9921006
}

Source/Scene/Camera.js

+13-4
Original file line numberDiff line numberDiff line change
@@ -2574,10 +2574,13 @@ define([
25742574
var scratchProj = new Cartesian3();
25752575

25762576
/**
2577-
* Return the distance from the camera to the front of the bounding sphere.
2577+
* Return the signed distance from the camera to the front of the bounding sphere.
2578+
* <p>
2579+
* Positive values indicate that the bounding sphere is in the positive half-plane of the camera position and view direction while a negative value indicates it is in the negative half-plane.
2580+
* </p>
25782581
*
25792582
* @param {BoundingSphere} boundingSphere The bounding sphere in world coordinates.
2580-
* @returns {Number} The distance to the bounding sphere.
2583+
* @returns {Number} The signed distance to the bounding sphere.
25812584
*/
25822585
Camera.prototype.distanceToBoundingSphere = function(boundingSphere) {
25832586
//>>includeStart('debug', pragmas.debug);
@@ -2587,8 +2590,10 @@ define([
25872590
//>>includeEnd('debug');
25882591

25892592
var toCenter = Cartesian3.subtract(this.positionWC, boundingSphere.center, scratchToCenter);
2590-
var proj = Cartesian3.multiplyByScalar(this.directionWC, Cartesian3.dot(toCenter, this.directionWC), scratchProj);
2591-
return Math.max(0.0, Cartesian3.magnitude(proj) - boundingSphere.radius);
2593+
var distance = -Cartesian3.dot(toCenter, this.directionWC);
2594+
var proj = Cartesian3.multiplyByScalar(this.directionWC, distance, scratchProj);
2595+
var unsignedDistance = Math.max(0.0, Cartesian3.magnitude(proj) - boundingSphere.radius);
2596+
return distance < 0.0 ? -unsignedDistance : unsignedDistance;
25922597
};
25932598

25942599
var scratchPixelSize = new Cartesian2();
@@ -2615,6 +2620,9 @@ define([
26152620
//>>includeEnd('debug');
26162621

26172622
var distance = this.distanceToBoundingSphere(boundingSphere);
2623+
if (distance < 0.0) {
2624+
return 0.0;
2625+
}
26182626
var pixelSize = this.frustum.getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, scratchPixelSize);
26192627
return Math.max(pixelSize.x, pixelSize.y);
26202628
};
@@ -3229,6 +3237,7 @@ define([
32293237
Cartesian3.clone(camera.right, result.right);
32303238
Matrix4.clone(camera._transform, result.transform);
32313239
result._transformChanged = true;
3240+
result.frustum = camera.frustum.clone();
32323241

32333242
return result;
32343243
};

Source/Scene/Cesium3DTileBatchTable.js

+22-2
Original file line numberDiff line numberDiff line change
@@ -1351,7 +1351,7 @@ define([
13511351
if (bivariateVisibilityTest) {
13521352
if (command.pass !== Pass.TRANSLUCENT && !finalResolution) {
13531353
if (!defined(derivedCommands.zback)) {
1354-
derivedCommands.zback = deriveZBackfaceCommand(derivedCommands.originalCommand);
1354+
derivedCommands.zback = deriveZBackfaceCommand(frameState.context, derivedCommands.originalCommand);
13551355
}
13561356
tileset._backfaceCommands.push(derivedCommands.zback);
13571357
}
@@ -1436,7 +1436,24 @@ define([
14361436
return derivedCommand;
14371437
}
14381438

1439-
function deriveZBackfaceCommand(command) {
1439+
function getDisableLogDepthFragmentShaderProgram(context, shaderProgram) {
1440+
var shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, 'zBackfaceLogDepth');
1441+
if (!defined(shader)) {
1442+
var fs = shaderProgram.fragmentShaderSource.clone();
1443+
fs.defines = defined(fs.defines) ? fs.defines.slice(0) : [];
1444+
fs.defines.push('DISABLE_LOG_DEPTH_FRAGMENT_WRITE');
1445+
1446+
shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, 'zBackfaceLogDepth', {
1447+
vertexShaderSource : shaderProgram.vertexShaderSource,
1448+
fragmentShaderSource : fs,
1449+
attributeLocations : shaderProgram._attributeLocations
1450+
});
1451+
}
1452+
1453+
return shader;
1454+
}
1455+
1456+
function deriveZBackfaceCommand(context, command) {
14401457
// Write just backface depth of unresolved tiles so resolved stenciled tiles do not appear in front
14411458
var derivedCommand = DrawCommand.shallowClone(command);
14421459
var rs = clone(derivedCommand.renderState, true);
@@ -1459,6 +1476,9 @@ define([
14591476
derivedCommand.renderState = RenderState.fromCache(rs);
14601477
derivedCommand.castShadows = false;
14611478
derivedCommand.receiveShadows = false;
1479+
// Disable the depth writes in the fragment shader. The back face commands were causing the higher resolution
1480+
// tiles to disappear.
1481+
derivedCommand.shaderProgram = getDisableLogDepthFragmentShaderProgram(context, command.shaderProgram);
14621482
return derivedCommand;
14631483
}
14641484

Source/Scene/ClassificationModel.js

+19-9
Original file line numberDiff line numberDiff line change
@@ -663,34 +663,38 @@ define([
663663
}
664664

665665
function createProgram(model) {
666-
var positionName = ModelUtility.getAttributeOrUniformBySemantic(model.gltf, 'POSITION');
667-
var batchIdName = ModelUtility.getAttributeOrUniformBySemantic(model.gltf, '_BATCHID');
666+
var gltf = model.gltf;
667+
668+
var positionName = ModelUtility.getAttributeOrUniformBySemantic(gltf, 'POSITION');
669+
var batchIdName = ModelUtility.getAttributeOrUniformBySemantic(gltf, '_BATCHID');
668670

669671
var attributeLocations = {};
670672
attributeLocations[positionName] = 0;
671673
attributeLocations[batchIdName] = 1;
672674

673-
var modelViewProjectionName = ModelUtility.getAttributeOrUniformBySemantic(model.gltf, 'MODELVIEWPROJECTION');
675+
var modelViewProjectionName = ModelUtility.getAttributeOrUniformBySemantic(gltf, 'MODELVIEWPROJECTION');
674676

675677
var uniformDecl;
676-
var computePosition;
678+
var toClip;
677679

678680
if (!defined(modelViewProjectionName)) {
679-
var projectionName = ModelUtility.getAttributeOrUniformBySemantic(model.gltf, 'PROJECTION');
680-
var modelViewName = ModelUtility.getAttributeOrUniformBySemantic(model.gltf, 'MODELVIEW');
681+
var projectionName = ModelUtility.getAttributeOrUniformBySemantic(gltf, 'PROJECTION');
682+
var modelViewName = ModelUtility.getAttributeOrUniformBySemantic(gltf, 'MODELVIEW');
681683
if (!defined(modelViewName)) {
682-
modelViewName = ModelUtility.getAttributeOrUniformBySemantic(model.gltf, 'CESIUM_RTC_MODELVIEW');
684+
modelViewName = ModelUtility.getAttributeOrUniformBySemantic(gltf, 'CESIUM_RTC_MODELVIEW');
683685
}
684686

685687
uniformDecl =
686688
'uniform mat4 ' + modelViewName + ';\n' +
687689
'uniform mat4 ' + projectionName + ';\n';
688-
computePosition = ' vec4 positionInClipCoords = ' + projectionName + ' * ' + modelViewName + ' * vec4(' + positionName + ', 1.0);\n';
690+
toClip = projectionName + ' * ' + modelViewName + ' * vec4(' + positionName + ', 1.0)';
689691
} else {
690692
uniformDecl = 'uniform mat4 ' + modelViewProjectionName + ';\n';
691-
computePosition = ' vec4 positionInClipCoords = ' + modelViewProjectionName + ' * vec4(' + positionName + ', 1.0);\n';
693+
toClip = modelViewProjectionName + ' * vec4(' + positionName + ', 1.0)';
692694
}
693695

696+
var computePosition = ' vec4 positionInClipCoords = ' + toClip + ';\n';
697+
694698
var vs =
695699
'attribute vec3 ' + positionName + ';\n' +
696700
'attribute float ' + batchIdName + ';\n' +
@@ -716,6 +720,9 @@ define([
716720
var drawVS = modifyShader(vs, model._vertexShaderLoaded);
717721
var drawFS = modifyShader(fs, model._classificationShaderLoaded);
718722

723+
drawVS = ModelUtility.modifyVertexShaderForLogDepth(drawVS, toClip);
724+
drawFS = ModelUtility.modifyFragmentShaderForLogDepth(drawFS);
725+
719726
model._shaderProgram = {
720727
vertexShaderSource : drawVS,
721728
fragmentShaderSource : drawFS,
@@ -726,6 +733,9 @@ define([
726733
var pickVS = modifyShader(vs, model._pickVertexShaderLoaded);
727734
var pickFS = modifyShader(fs, model._pickFragmentShaderLoaded);
728735

736+
pickVS = ModelUtility.modifyVertexShaderForLogDepth(pickVS, toClip);
737+
pickFS = ModelUtility.modifyFragmentShaderForLogDepth(pickFS);
738+
729739
model._pickShaderProgram = {
730740
vertexShaderSource : pickVS,
731741
fragmentShaderSource : pickFS,

0 commit comments

Comments
 (0)