【问题标题】:Metal: How to attach image to shader without color/gamma conversion?Metal:如何在没有颜色/伽玛转换的情况下将图像附加到着色器?
【发布时间】:2019-01-18 03:33:37
【问题描述】:

是否可以在不进行任何颜色/伽玛校正的情况下将图像发送到金属着色器(来自 scenekit)?

我有一个数据纹理,其中每个通道对应于我希望能够测试的特定值。这是一张绿色通道映射到国家索引的世界地图。如果该国家/地区处于“活动”状态,则该国家/地区将呈现为红色,否则为灰色。

这是我正在使用的代码示例:

sphereNode = SCNNode(geometry: sphereGeometry)
scene.rootNode.addChildNode(sphereNode)

let program = SCNProgram()
program.vertexFunctionName = "sliceVertex"       
program.fragmentFunctionName = "sliceFragment"
sphereNode.geometry?.firstMaterial?.program = program

let imageProperty = SCNMaterialProperty(contents: UIImage(named: "art.scnassets/Textures/earth-data-map-2k.png")!)
mageProperty.mipFilter = SCNFilterMode.none 
sphereNode.geometry?.firstMaterial?.setValue(imageProperty, forKey: "dataTexture")

片段着色器:

fragment float4 sliceFragment(
    Vertex in [[stage_in]],
    texture2d<float, access::sample> dataTexture [[texture(0)]]
){
    constexpr sampler quadSampler(coord::normalized, filter::linear, address::repeat);
    float4 color = dataTexture.sample(quadSampler, in.texCoords);
    int index = int(color.g * 255.0);
    float active = index == 81 ? 1.0 : 0.0;
    float3 col = mix(float3(color.g,color.g,color.g), float3(1.0,0.0,0.0), active);
    return float4(col.r, col.g, col.b, 1);
}

问题是我用于纹理的 UIImage 似乎被转换为线性空间,但我想在着色器中使用未更改的图像数据。

【问题讨论】:

    标签: shader scenekit metal color-space gamma


    【解决方案1】:

    Metal 始终在着色器中使用线性 RGB 来存储纹理数据。如果纹理是 sRGB 而不是线性纹理,则读取和采样从 sRGB 转换为线性,写入从线性转换为 sRGB。

    纹理像素格式告诉 Metal 支持纹理的数据是线性的还是 sRGB。大多数像素格式是线性的,但有些名称以 _sRGB 结尾并且是 sRGB。

    在幕后(没有双关语),SCNMaterialPropertyUIImage 将解释图像数据并使用源颜色配置文件来选择像素格式。如果 PNG 具有指定线性或 sRGB 以外的颜色配置文件,则它可能正在转换为其中之一。如果它没有颜色配置文件,则可能假定为 SRGB。

    代表非图像数据的 PNG 应该带有一个颜色配置文件,指定它是线性 RGB。如果您无法修改 PNG 并且它被解释为 sRGB,您可能需要通过 CGImage 并使用 copy(colorSpace:) 创建具有相同数据的新图像对象并覆盖其颜色配置文件。您可以使用 CGColorSpace(.genericRGBLinear) 获得所需的色彩空间。

    此外,您应该使用filter::nearest 作为着色器的采样器。合并相邻的国家/地区索引是没有意义的。

    不过,最好的办法是在应用程序的资源中使用数据文件格式,而不是图像文件格式。然后将其传递给缓冲区而不是纹理中的着色器。

    【讨论】:

    • 嗨,肯。我有一个有点相关的问题。我使用 rgba16Float 作为我的 MTKView colorPixelFormat 而不是默认的 bgra8Unorm。现在一切都变得更亮了。纹理。背景清晰的颜色。一切都更亮了,好像我已经校正了伽马一样。您对这里发生的事情有任何见解。链接:stackoverflow.com/questions/54256198/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-28
    • 2022-12-10
    相关资源
    最近更新 更多