问题
I'd like to read from the depth buffer. In GL on OS X I could do:
float depth[2][2]; // get 2x2 for bilinear interpolation
glReadPixels(s.x, s.y, /*width*/2, /*height*/2, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
(Note that with OpenGL ES on iOS you can't read from the depth buffer)
What's the equivalent with Metal?
It looks like I need to do:
_renderPassDescriptor.depthAttachment.storeAction = MTLStoreActionStore;
And then somehow read from the buffer via the CPU?
Though perhaps there's a better way since I only need one point (where the touch is). Can the fragment shader store the depth for just that point (or a 2x2 for bilinear interpolation), thus allowing me to leave the storeAction as MTLStoreActionDontCare?
回答1:
I set the depth store action to MTLStoreActionStore
and then did the following in the render method:
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
// We're done! So read from the depth texture.
// Just read the center pixel for now.
MTLRegion region = MTLRegionMake2D(_depthTex.width/2, _depthTex.height/2, 1, 1);
float depth;
[_depthTex getBytes:&depth bytesPerRow:_depthTex.width*4 fromRegion:region mipmapLevel:0];
NSLog(@"read depth: %f", depth);
dispatch_semaphore_signal(block_sema);
}];
This worked and was confirmed as the "right way to do it" by an Apple developer over on the forums.
Note that reading from the depth buffer isn't possible with OpenGL ES on iOS. Metal FTW!
来源:https://stackoverflow.com/questions/28424883/ios-metal-how-to-read-from-the-depth-buffer-at-a-point