简体   繁体   中英

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

I'd like to read from the depth buffer. In GL on OS XI 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?

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM