-
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
Pick translucent geometry #4979
Changes from 3 commits
e4d1557
832b36c
002e2d9
e43dc2e
e4ed730
e522ffe
6d94f35
963e631
0e2fb9c
be613f9
d3cba1c
3bb0a9e
a49219b
eb56783
47efc79
547216f
94c3053
ab65c94
864433d
e0c769b
fe01bc0
4686c2f
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 |
---|---|---|
|
@@ -28,17 +28,21 @@ define([ | |
'../Core/Matrix4', | ||
'../Core/mergeSort', | ||
'../Core/Occluder', | ||
'../Core/PixelFormat', | ||
'../Core/ShowGeometryInstanceAttribute', | ||
'../Core/Transforms', | ||
'../Renderer/ClearCommand', | ||
'../Renderer/ComputeEngine', | ||
'../Renderer/Context', | ||
'../Renderer/ContextLimits', | ||
'../Renderer/DrawCommand', | ||
'../Renderer/Framebuffer', | ||
'../Renderer/Pass', | ||
'../Renderer/PassState', | ||
'../Renderer/PixelDatatype', | ||
'../Renderer/ShaderProgram', | ||
'../Renderer/ShaderSource', | ||
'../Renderer/Texture', | ||
'./Camera', | ||
'./CreditDisplay', | ||
'./CullingVolume', | ||
|
@@ -96,17 +100,21 @@ define([ | |
Matrix4, | ||
mergeSort, | ||
Occluder, | ||
PixelFormat, | ||
ShowGeometryInstanceAttribute, | ||
Transforms, | ||
ClearCommand, | ||
ComputeEngine, | ||
Context, | ||
ContextLimits, | ||
DrawCommand, | ||
Framebuffer, | ||
Pass, | ||
PassState, | ||
PixelDatatype, | ||
ShaderProgram, | ||
ShaderSource, | ||
Texture, | ||
Camera, | ||
CreditDisplay, | ||
CullingVolume, | ||
|
@@ -548,6 +556,8 @@ define([ | |
*/ | ||
this.useDepthPicking = true; | ||
|
||
this.pickTranslucentDepth = true; | ||
|
||
/** | ||
* The time in milliseconds to wait before checking if the camera has not moved and fire the cameraMoveEnd event. | ||
* @type {Number} | ||
|
@@ -2696,6 +2706,68 @@ define([ | |
return object; | ||
}; | ||
|
||
var scratchPickDepthPassState; | ||
|
||
function renderForPickDepth(scene, drawingBufferPosition) { | ||
var context = scene._context; | ||
var us = context.uniformState; | ||
var frameState = scene._frameState; | ||
|
||
// Update with previous frame's number and time, assuming that render is called before picking. | ||
updateFrameState(scene, frameState.frameNumber, frameState.time); | ||
frameState.cullingVolume = getPickCullingVolume(scene, drawingBufferPosition, 1, 1); | ||
frameState.passes.render = true; | ||
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. Is it better for this to be frameState.passes.pick = true; Or to do whatever the shadow map pass does since they only writes depth. If doc, please add a comment. 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. Another thing to consider here is that we do not want a pick to cause 3D Tiles to make new requests or process new tiles (which could happen because the cull volume is different) so this needs to be pick/depth or we need to signal to pause requests. 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 shadow map pass happens during the render pass. It uses derived commands that disables color writes and enables depth writes. Also, the framebuffer only has a depth attachment. I could change it to pick, but the depth copies for each frustum only happen during the render pass. Another option is to add a new depth pass. 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'm not following. What depth copies?
Could work, but what about this: could we just derive commands from the previous frame's commands? Instead of calling all the 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.
We copy the frustum depth to a texture after each frustum is rendered here. 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've updated this in e522ffe. There wasn't a need for derived commands. Everything is updated for the pick and depth pass which essentially queues pick commands for each command that was used in the previous render pass. Do 3D Tiles work this way or does it select new tiles on pick? |
||
|
||
us.update(frameState); | ||
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. Offline we discussed using the commands from the previous frame. Why didn't you take that approach? Because some primitives will want to generate different commands here? Which precisely since pick ids won't matter. If we stick with this approach, let's add a I've been thinking about this in three levels of reuse/efficiency:
|
||
|
||
var passState = scratchPickDepthPassState; | ||
if (!defined(passState)) { | ||
passState = scratchPickDepthPassState = new PassState(context); | ||
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. What if the app has more than one context? Should |
||
passState.scissorTest = { | ||
enabled : true, | ||
rectangle : new BoundingRectangle() | ||
}; | ||
passState.viewport = new BoundingRectangle(); | ||
passState.depthMask = true; | ||
} | ||
|
||
var width = context.drawingBufferWidth; | ||
var height = context.drawingBufferHeight; | ||
|
||
var framebuffer = scene._pickDepthFramebuffer; | ||
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.
|
||
var pickDepthFBWidth = scene._pickDepthFramebufferWidth; | ||
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. Is this and height below declared in the constructor function? |
||
var pickDepthFBHeight = scene._pickDepthFramebufferHeight; | ||
if (!defined(framebuffer) || pickDepthFBWidth !== width || pickDepthFBHeight !== height) { | ||
scene._pickDepthFramebuffer = scene._pickDepthFramebuffer && scene._pickDepthFramebuffer.destroy(); | ||
framebuffer = scene._pickDepthFramebuffer = new Framebuffer({ | ||
context : context, | ||
depthStencilTexture : new Texture({ | ||
context : context, | ||
width : width, | ||
height : height, | ||
pixelFormat : PixelFormat.DEPTH_STENCIL, | ||
pixelDatatype : PixelDatatype.UNSIGNED_INT_24_8 | ||
}) | ||
}); | ||
|
||
scene._pickDepthFramebufferWidth = width; | ||
scene._pickDepthFramebufferHeight = height; | ||
} | ||
|
||
passState.framebuffer = framebuffer; | ||
passState.viewport.width = width; | ||
passState.viewport.height = height; | ||
passState.scissorTest.rectangle.x = drawingBufferPosition.x; | ||
passState.scissorTest.rectangle.y = height - drawingBufferPosition.y; | ||
passState.scissorTest.rectangle.width = 1; | ||
passState.scissorTest.rectangle.height = 1; | ||
|
||
updateAndExecuteCommands(scene, passState, scratchColorZero); | ||
resolveFramebuffers(scene, passState); | ||
|
||
context.endFrame(); | ||
} | ||
|
||
var scratchPackedDepth = new Cartesian4(); | ||
var packedDepthScale = new Cartesian4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0); | ||
|
||
|
@@ -2727,6 +2799,9 @@ define([ | |
var uniformState = context.uniformState; | ||
|
||
var drawingBufferPosition = SceneTransforms.transformWindowToDrawingBuffer(this, windowPosition, scratchPosition); | ||
if (this.pickTranslucentDepth) { | ||
renderForPickDepth(this, drawingBufferPosition); | ||
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. Perhaps rename to 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. Are you sure 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.
Yes, unless you have a better suggestion. We call |
||
} | ||
drawingBufferPosition.y = this.drawingBufferHeight - drawingBufferPosition.y; | ||
|
||
var camera = this._camera; | ||
|
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.
Perhaps add a
PERFORMANCE_IDEA
about rendering translucent only and merging with the previous frame; I still think it could work if it checks the state is in sync.