iOS/Metal: how to read from the depth buffer at a point?

允我心安 提交于 2020-06-24 16:47:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!