Мне нужно захватить текстуру всего, что рисуется в буфере кадра, другими словами, все, что появляется ниже эффекта, который я собираюсь нарисовать. Вариант использования - передать эту текстуру шейдеру, который выполняет искажение.
то, что я пробовал до сих пор, используя MTLBlitCommandEncoder.
auto commandQueue = [device newCommandQueue];
auto commandBuffer = [commandQueue commandBuffer];
[commandBuffer enqueue];
id<MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:mtlDescriptor];
// perform encoding
[renderEncoder endEncoding];
// now after several render passes i need to commit all the rendering for behind the effect,
// so that the texture i am grabbing will omit whatever is about to be drawn after this point
[commandBuffer commit];
[commandBuffer waitUntilCompleted];
Далее мне нужно создать новую команду буфер, потому что если я этого не сделаю, я получу ошибку, когда я вызову addCompletedHandler после этой фиксации. Я полагаю, что буфер команд не может фиксировать более одного раза, верно?
auto commandBuffer = [commandQueue commandBuffer];
id<MTLBlitCommandEncoder> blitEncoder = [commandBuffer blitCommandEncoder];
[blitEncoder enqueue];
[blitEncoder copyFromTexture:drawable.texture sourceSlice:0 sourceLevel:level sourceOrigin:region.origin sourceSize:region.size toTexture:_mtlTexture destinationSlice:0 destinationLevel:level destinationOrigin:{xOffset, yOffset, 0}];
[blitEncoder endEncoding];
.
// continue with more other render encoding
Это может выполняться без какой-либо ошибки подтверждения. Но проблема в том, что тест глубины появляется неправильно. Похоже, что эффект отрисовывается за моделями, которые должны быть выше (когда я использую только 1 буфер команд без выполнения блита, он отображается правильно). я использую эти настройки, которые, я полагаю, будут сохранены все записанные в глубину текстуры?
mtlDescritpor.depthAttachment.loadAction = MTLLoadActionLoad;
mtlDescritpor.depthAttachment.storeAction = MTLStoreActionStore;
Может кто-нибудь указать мне, где пошло не так?
РЕДАКТИРОВАТЬ: Я пытался использовать 2 буфера команд, один за другим, без выполнения blit, и глубина также отображается неправильно.
Означает ли это, что проверка глубины просто не может работать, когда это новый командный буфер? Или есть более рекомендуемая реализация для того, чего я пытаюсь достичь? Кажется, я не могу найти никаких примеров ..
EDIT2: после дополнительного тестирования, кажется, что есть очень противоречивое поведение, даже при использовании только 1 буфера команд. Некоторое время эффект отображается ниже (неверно), иногда правильно. (часть этого должна быть выше, как проверено на OpenGL) Когда я закомментирую строку кода или добавлю больше строк кода, результат будет меняться случайным образом. В настоящее время я использую функцию глубины MTLCompareFunctionLessEqual
. Если я изменю на MTLCompareFunctionNotEqual
, все будет всегда нарисовано сверху, что также неправильно.