2015-02-10 105 views
2

我想读取深度缓冲区。在GL在OS X上我可以这样做:iOS /金属:如何从深度缓冲区读取点?

float depth[2][2]; // get 2x2 for bilinear interpolation 
glReadPixels(s.x, s.y, /*width*/2, /*height*/2, GL_DEPTH_COMPONENT, GL_FLOAT, depth); 

(注:在OpenGL ES的iOS设备上,你不能从深度缓冲区读取)

什么是与金属的相同呢?

它看起来像我需要做的:

_renderPassDescriptor.depthAttachment.storeAction = MTLStoreActionStore; 

然后以某种方式从通过CPU的缓冲区中读取?

虽然也许有更好的方法,因为我只需要一点(触摸的地方)。片段着色器能够存储该点的深度(或者双线性插值为2x2),因此允许我将storeAction作为MTLStoreActionDontCare?

回答

2

我设定的深度店行动MTLStoreActionStore,然后做的渲染方法如下:

[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); 

}]; 

这由Apple开发者在对工作,被确认为“做正确的方式”论坛。

请注意,使用iOS上的OpenGL ES无法读取深度缓冲区。金属FTW!

+0

我不相信你可以使用getBytes:不再。来自Apple的开发者网站:http://apple.co/1IG3jpw“只能使用私有存储模式分配具有深度,模板或深度/模板像素格式的纹理。要加载或保存这些纹理的内容,您必须执行blit操作。“ – datboi 2015-12-10 03:30:24

+0

@datboi有趣。我将重新审视这个,我会更新代码。 – Taylor 2016-01-02 21:34:52

+0

对不起,一个完整的解释:如果你在iOS上,纹理默认为MTLStorageModeShared,它不需要通过blit命令编码器进行同步。但是,深度和模板纹理是一个例外,必须使用MTLStorageModePrivate进行分配。由于这种存储模式的要求,您唯一的选择是从专用深度/模板纹理(在“VRAM”中)到CPU可访问的存储器,因为“具有私有存储模式的纹理不支持this(getBytes)方法”。 - 苹果,http://apple.co/1OGM7h7 – datboi 2016-01-20 22:07:48