-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Log depth buffer #5851
Log depth buffer #5851
Changes from 72 commits
80f5976
36264f7
e15adbf
bd5428f
ceedc32
d70db84
87f8415
a79138d
7ee510c
7133aa5
4a79331
50c019c
043ebcc
a65596f
3d5cd2b
451761c
db0630f
8191c36
2fb7ed2
665909c
bcf1504
22bfd34
9f7c4d8
417c3f9
f5ad7c6
23f99c2
33cfca7
caf032a
8d49519
b6db381
c94e5ad
7d716e9
567a110
7c46e11
e331d4c
75bd3ba
e62f28b
d681755
6e07e89
90a089b
462d229
27447fc
0a628db
afcc7ed
9cea995
122ca66
2f710de
bcc2dc4
4ee738d
0d90d98
22ecbe6
e72c849
3c9c92b
1440a9a
27118ee
7fdf9c9
d94aa07
1d5adab
e029f10
f14a2cf
7c06ec8
1635c92
5913ffe
a648dea
b6de470
1525950
6a5a6b0
2f53039
fb3a2b2
530f41d
78dcea9
979b541
4dd219f
b5f83d9
9bc6e32
d546e45
e17dbcc
6e9fc3e
4cf9479
bed9f0e
3419ad5
d7d14a5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -849,6 +849,18 @@ define([ | |
*/ | ||
CesiumMath.cbrt = defined(Math.cbrt) ? Math.cbrt : cbrt; | ||
|
||
function log2(x) { | ||
return Math.log(x) * Math.LOG2E; | ||
} | ||
|
||
/** | ||
* Finds the base 2 logarithm of a number. | ||
* | ||
* @param {Number} number The number. | ||
* @returns {Number} The result. | ||
*/ | ||
CesiumMath.log2 = defined(Math.log2) ? Math.log2 : log2; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add to CHANGES.md. |
||
|
||
/** | ||
* @private | ||
*/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1135,6 +1135,22 @@ define([ | |
} | ||
}), | ||
|
||
/** | ||
* The log of the current frustums far plane. Used for computing the log depth. | ||
* | ||
* @alias czm_logFarDistance | ||
* @glslUniform | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added the private tag instead in case we ever make this class public (likely for post-processing). It only has the one purpose and removes an extra log from the shaders. |
||
* | ||
* @private | ||
*/ | ||
czm_logFarDistance : new AutomaticUniform({ | ||
size : 1, | ||
datatype : WebGLConstants.FLOAT, | ||
getValue : function(uniformState) { | ||
return uniformState.logFarDistance; | ||
} | ||
}), | ||
|
||
/** | ||
* An automatic GLSL uniform representing the sun position in world coordinates. | ||
* | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2574,10 +2574,13 @@ define([ | |
var scratchProj = new Cartesian3(); | ||
|
||
/** | ||
* Return the distance from the camera to the front of the bounding sphere. | ||
* Return the signed distance from the camera to the front of the bounding sphere. | ||
* <p> | ||
* 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. | ||
* </p> | ||
* | ||
* @param {BoundingSphere} boundingSphere The bounding sphere in world coordinates. | ||
* @returns {Number} The distance to the bounding sphere. | ||
* @returns {Number} The signed distance to the bounding sphere. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Warrants an update the CHANGES.md? |
||
*/ | ||
Camera.prototype.distanceToBoundingSphere = function(boundingSphere) { | ||
//>>includeStart('debug', pragmas.debug); | ||
|
@@ -2587,8 +2590,10 @@ define([ | |
//>>includeEnd('debug'); | ||
|
||
var toCenter = Cartesian3.subtract(this.positionWC, boundingSphere.center, scratchToCenter); | ||
var proj = Cartesian3.multiplyByScalar(this.directionWC, Cartesian3.dot(toCenter, this.directionWC), scratchProj); | ||
return Math.max(0.0, Cartesian3.magnitude(proj) - boundingSphere.radius); | ||
var distance = -Cartesian3.dot(toCenter, this.directionWC); | ||
var proj = Cartesian3.multiplyByScalar(this.directionWC, distance, scratchProj); | ||
var unsignedDistance = Math.max(0.0, Cartesian3.magnitude(proj) - boundingSphere.radius); | ||
return distance < 0.0 ? -unsignedDistance : unsignedDistance; | ||
}; | ||
|
||
var scratchPixelSize = new Cartesian2(); | ||
|
@@ -2615,6 +2620,9 @@ define([ | |
//>>includeEnd('debug'); | ||
|
||
var distance = this.distanceToBoundingSphere(boundingSphere); | ||
if (distance < 0.0) { | ||
return 0.0; | ||
} | ||
var pixelSize = this.frustum.getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, scratchPixelSize); | ||
return Math.max(pixelSize.x, pixelSize.y); | ||
}; | ||
|
@@ -3229,6 +3237,7 @@ define([ | |
Cartesian3.clone(camera.right, result.right); | ||
Matrix4.clone(camera._transform, result.transform); | ||
result._transformChanged = true; | ||
result.frustum = camera.frustum.clone(); | ||
|
||
return result; | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1351,7 +1351,7 @@ define([ | |
if (bivariateVisibilityTest) { | ||
if (command.pass !== Pass.TRANSLUCENT && !finalResolution) { | ||
if (!defined(derivedCommands.zback)) { | ||
derivedCommands.zback = deriveZBackfaceCommand(derivedCommands.originalCommand); | ||
derivedCommands.zback = deriveZBackfaceCommand(frameState.context, derivedCommands.originalCommand); | ||
} | ||
tileset._backfaceCommands.push(derivedCommands.zback); | ||
} | ||
|
@@ -1436,7 +1436,24 @@ define([ | |
return derivedCommand; | ||
} | ||
|
||
function deriveZBackfaceCommand(command) { | ||
function getDisableLogDepthFragmentShaderProgram(context, shaderProgram) { | ||
var shader = context.shaderCache.getDerivedShaderProgram(shaderProgram, 'zBackfaceLogDepth'); | ||
if (!defined(shader)) { | ||
var fs = shaderProgram.fragmentShaderSource.clone(); | ||
fs.defines = defined(fs.defines) ? fs.defines.slice(0) : []; | ||
fs.defines.push('DISABLE_LOG_DEPTH_FRAGMENT_WRITE'); | ||
|
||
shader = context.shaderCache.createDerivedShaderProgram(shaderProgram, 'zBackfaceLogDepth', { | ||
vertexShaderSource : shaderProgram.vertexShaderSource, | ||
fragmentShaderSource : fs, | ||
attributeLocations : shaderProgram._attributeLocations | ||
}); | ||
} | ||
|
||
return shader; | ||
} | ||
|
||
function deriveZBackfaceCommand(context, command) { | ||
// Write just backface depth of unresolved tiles so resolved stenciled tiles do not appear in front | ||
var derivedCommand = DrawCommand.shallowClone(command); | ||
var rs = clone(derivedCommand.renderState, true); | ||
|
@@ -1459,6 +1476,9 @@ define([ | |
derivedCommand.renderState = RenderState.fromCache(rs); | ||
derivedCommand.castShadows = false; | ||
derivedCommand.receiveShadows = false; | ||
// Disable the depth writes in the fragment shader. The back face commands were causing the higher resolution | ||
// tiles to disappear. | ||
derivedCommand.shaderProgram = getDisableLogDepthFragmentShaderProgram(context, command.shaderProgram); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tested that skip lods still works with this change, but I'm confused why. Wouldn't the regular commands write log depth while the back face commands write normal depth? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The back face commands still write log depth in the vertex shader. The depth is correct at the vertices but interpolated linearly which is incorrect, but only noticeable for long triangles close to the camera. The fix is to output a linear value from the vertex shader and compute the log in the fragment shader. |
||
return derivedCommand; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ define([ | |
'../Renderer/Pass', | ||
'../Renderer/RenderState', | ||
'../Renderer/ShaderProgram', | ||
'../Renderer/ShaderSource', | ||
'../Renderer/VertexArray', | ||
'../Shaders/DepthPlaneFS', | ||
'../Shaders/DepthPlaneVS', | ||
|
@@ -30,6 +31,7 @@ define([ | |
Pass, | ||
RenderState, | ||
ShaderProgram, | ||
ShaderSource, | ||
VertexArray, | ||
DepthPlaneFS, | ||
DepthPlaneVS, | ||
|
@@ -45,6 +47,7 @@ define([ | |
this._va = undefined; | ||
this._command = undefined; | ||
this._mode = undefined; | ||
this._useLogDepth = false; | ||
} | ||
|
||
var depthQuadScratch = FeatureDetection.supportsTypedArrays() ? new Float32Array(12) : []; | ||
|
@@ -100,7 +103,7 @@ define([ | |
return depthQuadScratch; | ||
} | ||
|
||
DepthPlane.prototype.update = function(frameState) { | ||
DepthPlane.prototype.update = function(frameState, useLogDepth) { | ||
this._mode = frameState.mode; | ||
if (frameState.mode !== SceneMode.SCENE3D) { | ||
return; | ||
|
@@ -125,24 +128,48 @@ define([ | |
} | ||
}); | ||
|
||
this._sp = ShaderProgram.fromCache({ | ||
context : context, | ||
vertexShaderSource : DepthPlaneVS, | ||
fragmentShaderSource : DepthPlaneFS, | ||
attributeLocations : { | ||
position : 0 | ||
} | ||
}); | ||
|
||
this._command = new DrawCommand({ | ||
renderState : this._rs, | ||
shaderProgram : this._sp, | ||
boundingVolume : new BoundingSphere(Cartesian3.ZERO, ellipsoid.maximumRadius), | ||
pass : Pass.OPAQUE, | ||
owner : this | ||
}); | ||
} | ||
|
||
if (!defined(this._sp) || this._useLogDepth !== useLogDepth) { | ||
this._useLogDepth = useLogDepth; | ||
|
||
var vs = new ShaderSource({ | ||
sources : [DepthPlaneVS] | ||
}); | ||
var fs = new ShaderSource({ | ||
sources : [DepthPlaneFS] | ||
}); | ||
if (useLogDepth) { | ||
var extension = | ||
'#ifdef GL_EXT_frag_depth \n' + | ||
'#extension GL_EXT_frag_depth : enable \n' + | ||
'#endif \n\n'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of adding this code manually could it be included in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately, no. When the shader is built, it searches the sources for extensions not the built-in functions. |
||
|
||
fs.sources.push(extension); | ||
fs.defines.push('LOG_DEPTH'); | ||
vs.defines.push('LOG_DEPTH'); | ||
vs.defines.push('DISABLE_GL_POSITION_LOG_DEPTH'); | ||
} | ||
|
||
this._sp = ShaderProgram.replaceCache({ | ||
shaderProgram : this._sp, | ||
context : context, | ||
vertexShaderSource : vs, | ||
fragmentShaderSource : fs, | ||
attributeLocations : { | ||
position : 0 | ||
} | ||
}); | ||
|
||
this._command.shaderProgram = this._sp; | ||
} | ||
|
||
// update depth plane | ||
var depthQuad = computeDepthQuad(ellipsoid, frameState); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did we also change the default near value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Late to the party, but should this be
logarithmicDepthBuffer
inScene
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#6465