Скопируйте буфер металлического каркаса в MTLTexture с другим форматом пикселей

Мне нужно захватить пиксели экрана в текстуру для выполнения постобработки. Раньше я использовал BlitCommandEncoder для копирования из текстуры в текстуру. Исходная текстура, являющаяся текстурой MTLDrawable, на мою целевую текстуру. У них обоих одинаковый MTLPixelFormatBGRA8Unorm, поэтому все работает нормально.

Однако теперь мне нужно использовать текстуру прикрепления цвета буфера кадра MTLPixelFormatRGBA16Float для рендеринга HDR. Итак, когда я захватываю пиксели экрана, я на самом деле беру из этой текстуры прикрепления цвета вместо текстуры Drawable. И я получаю эту ошибку:

[MTLDebugBlitCommandEncoder internalValidateCopyFromTexture: sourceSlice: sourceLevel: sourceOrigin: sourceSize: toTexture: destinationSlice: destinationLevel: destinationOrigin: options:]: 447: неудачное утверждение [sourceTexture pixelFormat] (MTLPixelFormatRGBA16Float) must [pixelFormat pixelFormat] (MTLPixelFormatRGBA16Float) должен

Не думаю, что мне нужно менять целевую текстуру на формат RGBA16Float? Потому что это займет вдвое больше памяти. Одной полноэкранной текстуры (цветное приложение) в этом формате должно хватить для работы HDR, верно?

Есть ли другой способ успешно выполнить такое копирование? В openGL нет ошибки при копировании с помощью glCopyTexImage2D


person Darren    schedule 23.03.2020    source источник
comment
Что ж, если вы не хотите использовать 16-битное число с плавающей запятой, вам нужно будет добавить проход рендеринга для преобразования в любой формат пикселей, который вы хотите использовать. Я не уверен, что понимаю, что вы имеете в виду под одной полноэкранной текстурой ... должно быть достаточно для HDR. HDR выражается в разных форматах пикселей и битовой глубине, но я думаю, что обычно вам нужно не менее 10 бит на цветовой канал, поэтому вы можете рассмотреть что-то вроде MTLPixelFormatRGB10A2Unorm.   -  person ldoogy    schedule 23.03.2020
comment
@ldoogy ok попробует добавить проход рендеринга. Я использую MTLPixelFormatRGBA16Float для рендеринга цветового диапазона, превышающего 1.0. Unorm ограничен от 0 до 1.   -  person Darren    schedule 23.03.2020
comment
Я предлагаю вам использовать sRGB для всех ваших текстур рендеринга, это позволяет избежать необходимости удваивать объем памяти для 16-битных половинных пикселей, и вы не потеряете точность при рендеринге в линейный RGB. Плюс блит работать будет.   -  person MoDJ    schedule 24.03.2020
comment
@MoDJ будет ли это работать для рендеринга цветового диапазона ›1.0? в настоящее время у меня проблема с тем, что GL_RGBA16F является необъявленным идентификатором при использовании GLES 2. (для Android, потому что это кроссплатформенное приложение)   -  person Darren    schedule 24.03.2020


Ответы (1)


Metal автоматически преобразует исходный формат в целевой во время рендеринга. Таким образом, вы можете просто выполнить проход рендеринга без операции, чтобы выполнить преобразование.

В качестве альтернативы, если вы хотите избежать стандартного кода без операций рендеринга, вы можете использовать _1 _ шейдер производительности, который в основном делает то же самое.

person Frank Schlegel    schedule 23.03.2020
comment
Спасибо за предложенные методы. Попробую пройти рендеринг. - person Darren; 23.03.2020