RealityKit iOS Metal Shader 渲染颜色不正确
因此,我使用 Metal 为 RealityKit 中的实体编写自定义着色器,以便我可以创建渐变,但是一旦应用渐变,颜色就会奇怪地呈现。颜色在完整 RGB 值(例如 (1,0,0)、(1,1,1)、(1,1,0) 等)下正确渲染,但使用十进制值时渲染不正确。这是显示这些值的屏幕截图。前面的方块应用了简单的单色着色器,后面的方块则使用 RealityKit 中材质上的 UIColor 进行着色。在所有这些中,我使用 UnlitMaterial 和基本 MeshResource.generatePlane() 函数。
这些是在后面用作 UIColors 并在前面用作 Metal half3s 的颜色值。
let color1 = UIColor(red: 1, green: 0, blue: 0, alpha: 1)
let color2 = UIColor(red: 1, green: 0.25, blue: 0.25, alpha: 1)
let color3 = UIColor(red: 1, green: 0.5, blue: 0.5, alpha: 1)
let color4 = UIColor(red: 1, green: 0.75, blue: 0.75, alpha: 1)
let color5 = UIColor(red: 1, green: 0.875, blue: 0.875, alpha: 1)
let color6 = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
这是金属着色器之一
[[visible]]
void colorShader2(realitykit::surface_parameters params) {
// Gets surface parameters
auto surface = params.surface();
half value = 0.25;
// set color to RGB Values
half3 color = half3(1,value,value);
// Set the base color to the color
surface.set_emissive_color(color);
surface.set_base_color(color);
surface.set_opacity(half(1.0));
}
这是应用着色器的 Swift 代码,大部分来自 Apple 的文档。这些函数是实体类型的扩展。
func loadCustomSurfaceShader(mySurfaceShader: String) -> CustomMaterial.SurfaceShader {
// Get the Metal Device.
guard let device = MTLCreateSystemDefaultDevice() else {
fatalError("Error creating default metal device.")
}
// Get a reference to the Metal library.
guard let library = device.makeDefaultLibrary() else {
fatalError("Error creating default Metal library")
}
// Load a surface shader function named mySurfaceShader.
let surfaceShader = CustomMaterial.SurfaceShader(named: mySurfaceShader,
in: library)
return surfaceShader
}
func replaceMaterialWithCustomMaterial(entity: Entity, surfaceShader: CustomMaterial.SurfaceShader) {
// Make sure the entity has a ModelComponent.
guard var modelComponent = entity.components[ModelComponent.self] as? ModelComponent else {
return
}
// Loop through the entity's materials and replace the existing material with
// one based on the original material.
guard let customMaterials = try? modelComponent.materials.map({ material -> CustomMaterial in
let customMaterial = try CustomMaterial(from: material, surfaceShader: surfaceShader)
return customMaterial
}) else { return}
modelComponent.materials = customMaterials
entity.components[ModelComponent.self] = modelComponent
}
func applyShader(_ shader: LookShaders) {
let shader = self.loadCustomSurfaceShader(mySurfaceShader: shader.rawValue)
self.replaceMaterialWithCustomMaterial(entity: self, surfaceShader: shader)
}
我很困惑为什么会发生这种情况,但我确信可能有一些足够简单的事情我错过了。
So I'm using Metal to write custom shaders for my entities in RealityKit so that I can create gradients, but the colors are rendering strangely once I apply the gradient. The color renders correctly at full RGB values, e.g. (1,0,0), (1,1,1), (1,1,0), etc. but when using decimal values the render is incorrect. Here's a screenshot showing the values. The squares in front have simple single color shaders applied and the ones in the back are colored with a UIColor on the Material in RealityKit. In all of these, I'm using UnlitMaterial and the base MeshResource.generatePlane() function.
These are the color values used as UIColors in the back, and as Metal half3s in the front.
let color1 = UIColor(red: 1, green: 0, blue: 0, alpha: 1)
let color2 = UIColor(red: 1, green: 0.25, blue: 0.25, alpha: 1)
let color3 = UIColor(red: 1, green: 0.5, blue: 0.5, alpha: 1)
let color4 = UIColor(red: 1, green: 0.75, blue: 0.75, alpha: 1)
let color5 = UIColor(red: 1, green: 0.875, blue: 0.875, alpha: 1)
let color6 = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
Here's one of the Metal Shaders
[[visible]]
void colorShader2(realitykit::surface_parameters params) {
// Gets surface parameters
auto surface = params.surface();
half value = 0.25;
// set color to RGB Values
half3 color = half3(1,value,value);
// Set the base color to the color
surface.set_emissive_color(color);
surface.set_base_color(color);
surface.set_opacity(half(1.0));
}
Here's the Swift code to apply the shader, largely pulled from Apple's documentation. These functions are in an extension of the Entity type.
func loadCustomSurfaceShader(mySurfaceShader: String) -> CustomMaterial.SurfaceShader {
// Get the Metal Device.
guard let device = MTLCreateSystemDefaultDevice() else {
fatalError("Error creating default metal device.")
}
// Get a reference to the Metal library.
guard let library = device.makeDefaultLibrary() else {
fatalError("Error creating default Metal library")
}
// Load a surface shader function named mySurfaceShader.
let surfaceShader = CustomMaterial.SurfaceShader(named: mySurfaceShader,
in: library)
return surfaceShader
}
func replaceMaterialWithCustomMaterial(entity: Entity, surfaceShader: CustomMaterial.SurfaceShader) {
// Make sure the entity has a ModelComponent.
guard var modelComponent = entity.components[ModelComponent.self] as? ModelComponent else {
return
}
// Loop through the entity's materials and replace the existing material with
// one based on the original material.
guard let customMaterials = try? modelComponent.materials.map({ material -> CustomMaterial in
let customMaterial = try CustomMaterial(from: material, surfaceShader: surfaceShader)
return customMaterial
}) else { return}
modelComponent.materials = customMaterials
entity.components[ModelComponent.self] = modelComponent
}
func applyShader(_ shader: LookShaders) {
let shader = self.loadCustomSurfaceShader(mySurfaceShader: shader.rawValue)
self.replaceMaterialWithCustomMaterial(entity: self, surfaceShader: shader)
}
I'm pretty stumped as to why this is happening, but I'm sure there might be something simple enough I'm missing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论