简体   繁体   English

iOS /金属:如何从深度缓冲区读取一点?

[英]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: 在OS XI的GL中可以做到:

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) (请注意,在iOS上使用OpenGL ES时,您无法从深度缓冲区读取内容)

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? 然后以某种方式通过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? 片段着色器是否可以仅存储该点的深度(对于双线性插值,可以存储2x2的深度),从而允许我将storeAction保留为MTLStoreActionDontCare?

I set the depth store action to MTLStoreActionStore and then did the following in the render method: 我将深度存储操作设置为MTLStoreActionStore ,然后在render方法中执行以下操作:

[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. 请注意,iOS上的OpenGL ES无法从深度缓冲区读取数据。 Metal FTW! 金属FTW!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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