在Xcode 12.5.1和iOS 14.6上使用Swift 5和iOS
试图显示点云:我尝试使用8位字节的红/绿/蓝通道,而不是32位浮点数来保存内存( iPhone 8只与2000万点云搏斗;我必须使用比必要更多的瞬态内存),但该函数记录一个非致命的错误消息,不使用所提供的颜色。
它与32位浮标工作良好。在模拟器和iPhone 8上的错误消息是相同的- "SceneKit错误:不支持的转换uchar4 -> float4“。
我注意到,如果我把它改为一个8位的通道,我会得到“警告: C3DBaseTypeFromDescription -签名/无符号歧义”,根据谷歌的一项快速搜索,整个互联网上没有人见过(它有两次堆栈溢出点击,看起来很有希望,但没有一个真正的单词!)Bing认为这个词是在广告中为按摩和水管工(!)雅虎认为这是关于疯人院的。也许这是对苹果文档的评论。
我在互联网上看到了类似的例子,声称这类代码有效(例如https://developer.apple.com/forums/thread/112910),但在我在iOS上编码的几周里,我发现iOS的大多数代码示例编译都不干净或无法工作,因为苹果每年都不推荐使用它的所有API和语言(在那个例子中,数据(字节:)现在已经过时了)。幸运的是,Xcode经常就函数如何被重命名提出建议。
当然,我一定是错过了一些小小的初始化步骤,这将使这一工作?点云着色器一定要支持8位彩色频道吗?
非常感谢您的帮助。
import SceneKit
...
let szChunk = 8 // Number of points: More in real-life
let arrayRGB = Array(repeating:UInt8(255), count: szChunk * 4)
let dataRGB = Data(arrayRGB)
let colorSource = SCNGeometrySource(
data: dataRGB,
semantic: .color,
vectorCount: szChunk,
usesFloatComponents: false,
componentsPerVector: 4,
bytesPerComponent: 1,
dataOffset: 0,
dataStride: 4)
let indicesArray : [Int32] = (0..<szChunk).map{Int32($0)}
let pointCloudElement = SCNGeometryElement(
indices: indicesArray,
primitiveType: .point)
let arrayXYZ = Array(repeating:Float(0.0), count: szChunk * 3)
let dataXYZ = arrayXYZ.withUnsafeBufferPointer { Data(buffer: $0)}
let vertexSource = SCNGeometrySource(
data: dataXYZ,
semantic: .vertex,
vectorCount: szChunk,
usesFloatComponents: true,
componentsPerVector: 3,
bytesPerComponent: 4,
dataOffset: 0,
dataStride: 12)
// This causes [SceneKit] Error: unsupported conversion uchar4 -> float4
let _ = SCNGeometry(
sources: [vertexSource, colorSource],
elements: [pointCloudElement])替代
我注意到,如果我尝试在以下情况下使用金属缓冲区,我会得到相同的错误消息"SceneKit Error:不支持的转换uchar4 -> float4“:
let device = MTLCreateSystemDefaultDevice()
let mtlRGB = device!.makeBuffer(bytes:arrayRGB, length:szChunk * 4)
let colorSource = SCNGeometrySource(
buffer:mtlRGB!,
vertexFormat: .uchar4,
semantic: .color,
vertexCount: szChunk,
dataOffset: 0,
dataStride: 4)解决方案
然而,尽管没有使用.uchar4Normalized .uchar4,但做与和.uchar4Normalized_bgra的工作!现在,如果我们能够找到不使用sceneView.device) (我现在从MTLDevice获得的)如何使它工作起来的方法,那就太好了(我现在从vertexFormat获得了这一点,但似乎使用上面的代码与vertexFormat:.uchar4Normalized在我的硬件上确实有效。)
发布于 2021-07-14 13:00:09
SceneKit基于金属框架,这意味着它使用金属框架所使用的纹理像素格式。有关金属支持的可用纹理格式,请参见这链接。
https://stackoverflow.com/questions/68378216
复制相似问题