如何使用rgba16Float MTLPixelFormat显示MTKView [英] how to display MTKView with rgba16Float MTLPixelFormat

查看:557
本文介绍了如何使用rgba16Float MTLPixelFormat显示MTKView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将MTKView设置为使用MTLPixelFormat.rgba16Float.我遇到了显示问题,最好用下图来描述:

I have an MTKView set to use MTLPixelFormat.rgba16Float. I'm having display issues which can be best described with the following graphic:

因此,预期的UIColor会被冲洗掉,但仅限于在MTKView中显示时.当我将可绘制纹理转换回图像以通过CIIMage在UIView中显示时,我获得了原始颜色.这是我创建该输出的方法:

So the intended UIColor becomes washed out, but only while it is being displayed in MTKView. When I convert the drawable texture back to an image for display in a UIView via CIIMage, I get back the original color. Here is how I create that output:

let colorSpace = CGColorSpaceCreateDeviceRGB()
let kciOptions = [kCIImageColorSpace: colorSpace,
                  kCIContextOutputPremultiplied: true,
                  kCIContextUseSoftwareRenderer: false] as [String : Any]  
let strokeCIImage = CIImage(mtlTexture: metalTextureComposite, options: kciOptions)!.oriented(CGImagePropertyOrientation.downMirrored)
let imageCropCG = cicontext.createCGImage(strokeCIImage, from: bbox, format: kCIFormatABGR8, colorSpace: colorSpace) 

其他相关设置:

uiColorBrushDefault: UIColor = UIColor(red: 0.92, green: 0.79, blue: 0.18, alpha: 1.0)
self.colorPixelFormat = MTLPixelFormat.rgba16Float
renderPipelineDescriptor.colorAttachments[0].pixelFormat = self.colorPixelFormat

// below is the colorspace for the texture which is tinted with UIColor
let colorSpace = CGColorSpaceCreateDeviceRGB()
let texDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: MTLPixelFormat.rgba8Unorm, width: Int(width), height: Int(height), mipmapped: isMipmaped)
target = texDescriptor.textureType
texture = device.makeTexture(descriptor: texDescriptor)

一些帖子暗示sRGB被假定为某个地方,但是没有具体说明如何禁用它.

Some posts have hinted at sRGB being assumed somewhere, but no specifics as to how I can disable it.

我希望我在MTKView上显示的颜色与输入匹配(无论如何都尽可能接近),并且仍然能够将该纹理转换为可以在ImageView中显示的颜色.我已经在iPad Air和新的iPad Pro上对此进行了测试.行为相同.任何帮助将不胜感激.

I'd like the color that I display on MTKView to match the input (as close to it as possible anyway) and still be able to convert that texture into something I can display in an ImageView. I've tested this on an iPad Air and a new iPad Pro. Same behavior. Any help would be appreciated.

推荐答案

因此,您似乎已经很接近完整的解决方案.但是,你所拥有的并不是很正确.这是一个Metal函数,它将从sRGB转换为线性值,然后您可以将其写入Metal着色器中(我仍然建议您写入sRGB纹理,但也可以写入16位纹理).请注意,sRGB不是简单的2.2伽玛曲线.

So, it looks like you are very close to the complete solution. But what you have is not quite correct. Here is a Metal function that will convert from sRGB to a linear value which you can then write in your Metal shader (I still suggest that you write to a sRGB texture but you can also write to a 16 bit texture). Note that sRGB is not a simple 2.2 gamma curve.

// Convert a non-linear log value to a linear value.
// Note that normV must be normalized in the range [0.0 1.0].

static inline
float sRGB_nonLinearNormToLinear(float normV)
{
  if (normV <= 0.04045f) {
    normV *= (1.0f / 12.92f);
  } else {
    const float a = 0.055f;
    const float gamma = 2.4f;
    //const float gamma = 1.0f / (1.0f / 2.4f);
    normV = (normV + a) * (1.0f / (1.0f + a));
    normV = pow(normV, gamma);
  }

  return normV;
}

这篇关于如何使用rgba16Float MTLPixelFormat显示MTKView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆