Scenekit有一些纹理呈现红色色调

8

我有一个场景,其中有许多不同纹理的物体。由于某些原因,其中两个物体呈现出红色色调,即使它们的纹理没有红色。你仍然可以看到纹理中的图案,只是红色的阴影不同。(在模拟器上,这两个对象有黑白纹理,在设备上则呈现出红色阴影)。有人知道为什么会发生这种情况吗?其他物体都工作正常。

3个回答

11

对于像 metalnessroughness 这样的材料属性,SceneKit 支持使用 1 通道(灰度)图像。为了节省内存,这些图像被保留为灰度纹理,而不是转换为在每个通道中具有相同数据的 RGB 纹理。

当您将此类图像用于“着色”材料属性(例如 diffuse),SceneKit 将请求样本的红、绿和蓝分量,但绿色和蓝色始终为 0,因此该图像将呈现为红色。

不幸的是,一种解决方法是在图像编辑应用程序中重新处理纹理,使其保存为 RGB 而不是灰度。

您也可以尝试使用着色器修改器将灰度转换为 RGB:

_surface.diffuse.rgb = _surface.diffuse.rrr;

编辑

iOS 11起,使用单通道纹理时可以使用textureComponents属性:

material.diffuse.textureComponents = .red

我不认为我理解了。我的纹理已经是RGB的了。我只是像对待每个对象一样将纹理拖到模型中。 - Colddog
说我的纹理是RGB,意思是它有颜色。 - Colddog
我可能误解了你所说的“在模拟器上,这两个对象具有黑白纹理,在设备上则是红色阴影”的意思。你能否发布图像的图片以及它们在场景中的外观? - mnuages
我的意思是,比如场景中有一个1 dae 3d 模型。我还有一个 .png 纹理,上面有蓝色和绿色的图案。在 Xcode 中,我将 .png 纹理拖到对象上,但由于某种原因,在模拟器中查看它的外观时,纹理是黑白的,虽然它本应是绿色和蓝色的。当我在设备上(iPhone)播放它时,纹理具有图案,但颜色都是红色的阴影。 - Colddog
嗨 @mnuages!你能帮忙解决一个与Scenekit/ARKit相关的问题吗? - swiftlearneer

3

我遇到了用 (灰色) .png 图像作为 SCNMaterial 纹理加载的同样问题。

在模拟器上渲染正常。但在设备上,所有只有黑、白或灰色的图像都会呈现红色基色。

let texture = SCNMaterial()
texture.diffuse.contents = UIImage(named: "rgb image with only gray")

我通过从给定的UIImage创建一个新的UIImage来解决了这个问题:

let texture = SCNMaterial()
var newImage: UIImage?
if let textureImage = UIImage(named: "rgb image with only gray") {
    UIGraphicsBeginImageContext(textureImage.size)
    let width = textureImage.size.width
    let height = textureImage.size.height
    textureImage.draw(in: CGRect(x: 0, y: 0, width: width, height: height))
    newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
}
texture.diffuse.contents = newImage

HTH


这个方法有效!我在某些设备上遇到了问题(iPhone X上,我的纯白+alpha纹理显示为红色),而在其他设备上(iPad Pro上)则看起来正确,这个解决方法修复了它。显然,原始图像资产或UIImage的加载存在问题,可能在某个地方将其转换为单通道图像而不是RGB,并导致在某些设备上仅被解释为红色。 - Clafou

0

我遇到了一个与索引颜色PNG纹理相关的问题。
为了解决这个问题,我将索引颜色PNG转换为真彩色PNG。

这可能是一个NSImage的bug。当我使用CGImage加载PNG文件时,它没有引起任何问题。

let url = URL(fileURLWithPath: pngFileName, relativeTo: directoryPath)

// let reddishImage = NSImage(contentsOf: url)

let cgDataProvider = CGDataProvider(url: url as CFURL)!
let cgImage = CGImage(pngDataProviderSource: cgDataProvider, decode: nil, shouldInterpolate: false, intent: CGColorRenderingIntent.defaultIntent)!
let imageSize = CGSize(width: cgImage.width, height: cgImage.height)
let correctImage = NSImage(cgImage: cgImage, size: imageSize)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接