-
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
Conversation
Welcome to the Cesium community @Vineg! Can you please send in a Contributor License Agreement (CLA) so that we can review and merge this pull request? I noticed that CHANGES.md has not been updated. If this change updates the public API in any way, fixes a bug, or makes any non-trivial update, please add a bullet point to I am a bot who helps you make Cesium awesome! Thanks again. |
@cesium-concierge updated CHANGES.md. I am member of geoscan organization. We've already sent CLA |
Very cool, thanks @Vineg! @AnimatedRNG @lilleyse and I have been talking about doing this. I'm pretty sure it will be a win to reduce the total number of frustums requires at the cost of losing early z, but I do not believe it will be robust enough to truly fit all scenes into one frustum without z fighting in the distance. |
@Vineg I'll also add you to our CLA list so you do not get a CLA warning in future pull requests. |
@Vineg if this requires a lot of changes to get into production, do you have the bandwidth to work with us to make the changes or do prefer that we make them? |
@pjcozzi I think I can spend 1-2 more days on this feature. Not sure how much changes it is going to be. I've tested it with 1 frustum in the mountains, with pretty big tile model and didn't see z fighting. |
Sounds great, thanks for your support.
lol, we need to test looking at a soda can on a table in a building and looking through a window to the International Space Station with the moon in the background. 😄 I expect we will enable log depth by default with the multi frustum, and for scenes that then only require one frustum since the frustum can be much longer, it will be a great win, and even for massive distance scenes, probably only two frustums will be required. We'll also need to test this with the upcoming depth-based post-processing framework and depth picking. It's a pretty central change to the rendering pipeline so it needs careful attention. @lilleyse and @bagnell can help support this. |
I'll be away for 4 days. Will return back to this branch on tuesday. |
@Vineg I talked with @lilleyse about this feature, and we think it would be best implemented with a 32-bit depth buffer rather than the 24-bit depth buffers that we've been using throughout the code right now. In particular the texture internal format You might find this blog post useful, as well as this post (for optimizations). |
@AnimatedRNG Why do you want to use floating point values? If I understand it right, logarithmic depth is ought to be used with fixed-point values. |
@AnimatedRNG Do we really need 32bit? I've tried to set far plane to 500000000000000 and still don't see any z-fighting in the mountains. I think we have enough precision even with 24bit. |
@lilleyse, Yes, I just noticed that GroundPrimitives, Primitives, Billboards, Polylines, PointClouds and 3D Tiles requires additional modifications. If I missed something - let me know, I am now working on it. Also it seems to be pretty difficult to make depth writes optional as I did with globe, so I enable it as long as EXT_frag_depth available. |
…into log-depth-buffer
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.
@bagnell please also see the comments I just left in this PR about the Sandcastle examples that are not part of this code review email.
* `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. | ||
|
||
##### Additions :tada: | ||
* 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) |
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
in Scene
?
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.
Source/Scene/OIT.js
Outdated
@@ -554,12 +554,14 @@ define([ | |||
|
|||
for (j = 0; j < length; ++j) { | |||
command = commands[j]; | |||
command = defined(command.derivedCommands.logDepth) ? command.derivedCommands.logDepth.logDepthCommand : command; |
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.
Sorry for the perhaps obvious question here, but is everything based on derived commands? If so, why there is there so much custom code for models, ellipsoid primitives, etc.
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.
The custom code adds the function calls but the function bodies are surrounded by #ifdef
s. The derived commands will add the defines when log depth is supported.
@@ -398,7 +423,10 @@ define([ | |||
} | |||
|
|||
// Recompile shader when material changes | |||
if (materialChanged || lightingChanged || !defined(this._pickSP)) { | |||
if (materialChanged || lightingChanged || !defined(this._pickSP) || useLogDepthChanged) { |
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.
useLogDepthChanged
If it makes things much easier, I don't know that users will want to be able to toggle log depth at runtime.
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.
This wasn't difficult to add since we have to support the fallback anyway.
Source/Scene/Scene.js
Outdated
@@ -287,6 +287,10 @@ define([ | |||
this._primitives = new PrimitiveCollection(); | |||
this._groundPrimitives = new PrimitiveCollection(); | |||
|
|||
this._logDepthBuffer = undefined; | |||
this._logDepthBufferDirty = true; | |||
this.logarithmicDepthBuffer = context.fragmentDepth; |
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.
Should this have the same name as the property get/set below?
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.
Yes, this calls the setter below.
Source/Scene/Scene.js
Outdated
* @type {Number} | ||
* @default 1e9 | ||
*/ | ||
this.logarithmicDepthFarToNearRatio = 1e9; |
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.
Better document the interaction between logarithmicDepthBuffer
, farToNearRatio
, and logarithmicDepthFarToNearRatio
and use @see
/@link
to link them together. If I am following the boolean controls using one or the other ratios.
Source/Scene/Scene.js
Outdated
var vertexlogDepthRegex = /\s+czm_vertexLogDepth\(/; | ||
var extensionRegex = /\s*#extension\s+GL_EXT_frag_depth\s*:\s*enable/; | ||
|
||
function getLogDepthShaderProgram(context, shaderProgram) { |
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.
This is a lot of new code in Scene.js. Perhaps move these two new log depth shader functions to a new private utility class in a separate file?
@@ -870,6 +870,12 @@ define([ | |||
camera.frustum = camera3D.frustum.clone(); | |||
} | |||
|
|||
var frustum = camera.frustum; | |||
if (scene._logDepthBuffer && !(frustum instanceof OrthographicFrustum || frustum instanceof OrthographicOffCenterFrustum)) { | |||
frustum.near = 0.1; |
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.
Same comment here and below.
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.
Same comment as what? That this should be added to CHANGES.md? Done.
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.
Ah, there were some hidden comments.
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.
This has the same problem as in master. When the scene mode switches, we reset to the default near far distances in the frustum constructor. The old ones aren't saved between scene mode changes (should happen, separate PR or open an issue). This just sets to better defaults when log depth is enabled.
Cartesian3.clone(cameraCV.position, camera.position); | ||
Cartesian3.clone(cameraCV.direction, camera.direction); | ||
Cartesian3.clone(cameraCV.up, camera.up); | ||
Cartesian3.cross(camera.direction, camera.up, camera.right); | ||
Cartesian3.normalize(camera.right, camera.right); | ||
} | ||
|
||
var frustum = camera.frustum; | ||
if (scene._logDepthBuffer && !(frustum instanceof OrthographicFrustum || frustum instanceof OrthographicOffCenterFrustum)) { | ||
frustum.near = 0.1; |
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.
Same.
@@ -0,0 +1,49 @@ | |||
#ifdef LOG_DEPTH | |||
varying float v_logZ; |
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.
Here and in writeLogDepth.glsl
, we generally don't add new varyings or uniforms when including a built-in GLSL function (well, I also just noticed writeDepthClampedToFarPlane.glsl
). Instead, we try to make the functions standalone and pass in / return anything needed. Is that reasonable here? Or does that require too much shader patching elsewhere?
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.
I opted to put it here instead of making the shader patching code more complicated.
@@ -251,6 +251,9 @@ defineSuite([ | |||
}); | |||
|
|||
it('debugCommandFilter does not filter commands', function() { | |||
var originalLogDepth = scene.logarithmicDepthBuffer; |
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.
Does this file or MultifrustumSpec.js
need some new tests where it switches between log depth on/off and sees the number of (redundant) commands executed?
In general, how is code coverage? Does anything need more fine-grained tests? Shouldn't the new built-in GLSL functions have new tests?
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.
The multi-frustum tests have been updated to disable log depth. One test has it enabled to show that log depth has less 1 frustum where the other had 3.
Code coverage seems ok, but it's hard to say. I can't add tests for the new GLSL built-ins since they don't return a value. They update gl_Position and gl_FragDepth.
This happens on master as well as #6390. It is an edge case related to back faces and skip-lods. When refining the back faces of the parent are rendered, which kind of falls apart for single-sided geometry like this. I'll open an issue. |
It seems like it's just this branch. |
@bagnell all sounds good. |
Also check the Cesium Inspector sandcastle. Some of the options aren't working for me. |
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.
Cool, 6e9fc3e fixes the billboard problem and the existing demos still seem to work fine.
#ifdef LOG_DEPTH | ||
czm_vertexLogDepth(czm_projection * positionEC); | ||
#endif | ||
|
||
vec4 positionWC = computePositionWindowCoordinates(positionEC, imageSize, scale, direction, origin, translate, pixelOffset, alignedAxis, validAlignedAxis, rotation, sizeInMeters); |
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.
Should positionWC
and computePositionWindowCoordinates
be renamed?
@@ -71,23 +71,23 @@ vec4 computePositionWindowCoordinates(vec4 positionEC, vec2 imageSize, float sca | |||
positionEC.xy += halfSize; | |||
} | |||
|
|||
vec4 positionWC = czm_eyeToWindowCoordinates(positionEC); | |||
float mpp = czm_metersPerPixel(positionEC); |
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.
Is it possible to only compute this if sizeInMeters
is true and still function properly with the new changes? If not, not a big deal.
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.
No, since it's needed regardless of whether sizeInMeters
is true or false;
@lilleyse This should be ready. |
Ok I have nothing else to add here. Ready to go! @bagnell can you open an issue to remove the skinned model workarounds? |
Added option "logDepthBuffer" to Cesium.Viewer. With that option globe is rendered in 1 frustum with logarithmic depth. (fixes #4381)