Как включить MSAA для приложения iOS для рендеринга в текстуру - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть рабочий рендер для текстуры iOS-приложения.Проблема в том, что у него тонна неровностей, потому что это точечная выборка, а не сглаживание:

enter image description here

Я увеличил количество выборок в моем MTKView подкласс 4 для включения MSAA.

Вот как выглядит соответствующий код.

// render to texture render pass descriptor
renderPassDesc = MTLRenderPassDescriptor()
renderPassDesc.EI_configure(clearColor: MTLClearColorMake(1, 1, 1, 1), clearDepth: 1)

// my MTLRenderPassDescriptor extension convenience method
public func EI_configure(clearColor:MTLClearColor, clearDepth: Double) {

    // color
    colorAttachments[ 0 ] = MTLRenderPassColorAttachmentDescriptor()
    colorAttachments[ 0 ].storeAction = .store
    colorAttachments[ 0 ].loadAction = .clear
    colorAttachments[ 0 ].clearColor = clearColor

    // depth
    depthAttachment = MTLRenderPassDepthAttachmentDescriptor()
    depthAttachment.storeAction = .dontCare
    depthAttachment.loadAction = .clear
    depthAttachment.clearDepth = clearDepth;

}

Я прикрепляю буфер цвета и глубины, настроенный для MSAA, к renderPassDesc:

// color
let colorDesc = MTLTextureDescriptor.texture2DDescriptor(pixelFormat:view.colorPixelFormat, width:Int(view.bounds.size.width), height:Int(view.bounds.size.height), mipmapped:false)
colorDesc.mipmapLevelCount = 1;
colorDesc.textureType = .type2DMultisample
colorDesc.sampleCount = view.sampleCount
colorDesc.usage = [.renderTarget, .shaderRead]
renderPassDesc.colorAttachments[ 0 ].texture = view.device!.makeTexture(descriptor:colorDesc)

// depth
let depthDesc = MTLTextureDescriptor.texture2DDescriptor(pixelFormat:.depth32Float, width:Int(view.bounds.size.width), height:Int(view.bounds.size.height), mipmapped:false)
depthDesc.mipmapLevelCount = 1;
depthDesc.textureType = .type2DMultisample
depthDesc.sampleCount = view.sampleCount
depthDesc.usage = .renderTarget
renderPassDesc.depthAttachment.texture = view.device!.makeTexture(descriptor:depthDesc)

В моемЦикл рисования Я получаю следующую ошибку от моего фрагментного шейдера, который использует текстуру, которая была визуализирована:

Сбой утверждения Функция фрагмента (finalPassOverlayFragmentShader): неверный тип текстуры (MTLTextureType2DMultisample), связанный при привязке текстурыс индексом 0 (ожидайте MTLTextureType2D) для underlay[0]

Это фрагментный шейдер:

fragment float4 finalPassOverlayFragmentShader(InterpolatedVertex vert [[ stage_in ]],
                                               texture2d<float> underlay [[ texture(0) ]],
                                               texture2d<float> overlay [[ texture(1) ]]) {

    constexpr sampler defaultSampler;

    float4 _F = overlay.sample(defaultSampler, vert.st).rgba;

    float4 _B = underlay.sample(defaultSampler, vert.st).rgba;

    float4 rgba = _F + (1.0f - _F.a) * _B;

    return rgba;
}

Я уверен, что где-то пропустил настройку, но не могу ее найти.

Что я здесь пропустил?

ОБНОВЛЕНИЕ 0

У меня теперь MSAA происходит для моей 2-проходной игрушки.Единственная проблема в том, что сглаживания не происходит много.На самом деле трудно сказать, что что-то изменилось.Вот мои последние настройки

// color - multi-sampled texture target
let desc = MTLTextureDescriptor.texture2DDescriptor(pixelFormat:format, width:w, height:h, mipmapped:false)
desc.mipmapLevelCount = 1;
desc.textureType = .type2DMultisample
desc.sampleCount = view.sampleCount
desc.usage = .renderTarget
let tex:MTLTexture? = view.device!.makeTexture(descriptor:desc)

// color - point-sampled resolve-texture
let resolveDesc = MTLTextureDescriptor.texture2DDescriptor(pixelFormat:format, width:w, height:h, mipmapped:true)
let resolveTex:MTLTexture? = view.device!.makeTexture(descriptor:resolveDesc)

// depth texture target
let depthDesc = MTLTextureDescriptor.texture2DDescriptor(pixelFormat:.format, width:w, height:h, mipmapped:false)
depthDesc.mipmapLevelCount = 1;
depthDesc.textureType = .type2DMultisample
depthDesc.sampleCount = view.sampleCount
depthDesc.usage = .renderTarget
let depthTex:MTLTexture? = view.device!.makeTexture(descriptor:depthDesc)

// render pass descriptor
renderPassDesc = MTLRenderPassDescriptor()
// color
renderPassDesc.colorAttachments[ 0 ] = MTLRenderPassColorAttachmentDescriptor()
renderPassDesc.colorAttachments[ 0 ].storeAction = .storeAndMultisampleResolve
renderPassDesc.colorAttachments[ 0 ].loadAction = .clear
renderPassDesc.colorAttachments[ 0 ].clearColor = MTLClearColorMake(0.25, 0.25, 0.25, 1)
renderPassDesc.colorAttachments[ 0 ].texture = tex
renderPassDesc.colorAttachments[ 0 ].resolveTexture = resolveTex
// depth
renderPassDesc.depthAttachment = MTLRenderPassDepthAttachmentDescriptor()
renderPassDesc.depthAttachment.storeAction = .dontCare
renderPassDesc.depthAttachment.loadAction = .clear
renderPassDesc.depthAttachment.clearDepth = 1;
renderPassDesc.depthAttachment.texture = depthTex

ОБНОВЛЕНИЕ 1

Кажется, что неровности от рендеринга до текстуры, а не в активе.Ниже приведено сравнение. top изображение визуализируется с использованием одного прохода с включенным MSAA.Изображение bottom отображается в текстуре.Зубцы четко видны на нижнем изображении

один проход enter image description here

2 прохода enter image description here

1 Ответ

0 голосов
/ 27 ноября 2018

Ошибка не в вашей цели рендеринга (она также называется вложением цвета и глубины).Речь идет о текстуре, которую вы передаете через таблицу текстур фрагментов кодировщика команды рендеринга - то есть, где вы вызываете setFragmentTexture(_:index:).То, что вы передаете для индекса 0, это .type2DMultisample, когда шейдер закодирован, чтобы ожидать .type2D, потому что вы объявили underlay как texture2d<...>.

Ваша настройка для MSAA в порядке дляпромежуточный шаг.В конечном итоге вам потребуется преобразовать текстуру в текстуру, не имеющую нескольких выборок, чтобы нарисовать ее на экране.Для этого шага (который может быть для этого кодировщика команд рендеринга или более позднего, в зависимости от ваших потребностей), вам нужно установить storeAction для цветового вложения либо .multisampleResolve, либо .storeAndMultisampleResolve.И вам нужно установить resolveTexture для 2D текстуры.Это может быть ваша собственная или нарисованная текстура.

...