Hello
As part of my app, I am using Metal shaders on CustomMaterials created and managed using RealityKit. Using the ECS approach, I have a Shader system that iterates through all my materials every frame and passes a SIMD4 of variables (that I can manage on the swift side) that can be interpreted and used every frame on the Metal side to influence elements of the shader.
This does work as intended but is limited to just 4 variables when I need more for my use case. I've experimented with trying multiple simd4 or other approaches for passing these to metal and be useable but I haven't had very much luck. I was hoping for some recommendations on the best scalable approach.
Swift:
class ShaderSystem: System { static let query = EntityQuery(where: .has(ModelComponent.self)) private var startTime: Date
required init(scene: Scene) {
startTime = Date()
}
func update(context: SceneUpdateContext) {
let audioLevel = AudioSessionManager.shared.audioLevel
let elapsedTime = Float(Date().timeIntervalSince(startTime))
guard let sceneType = SceneManager.shared.currentScenes.keys.first else { return }
let sceneTime = SceneComposer.shared.getSceneTime(for: sceneType)
let multiplier = ControlManager.shared.getControlValue(parameterName: "elapsedTimeMultiplier") ?? 1.0
for entity in context.scene.performQuery(Self.query) {
guard var modelComponent = entity.components[ModelComponent.self] as? ModelComponent else { continue }
modelComponent.materials = modelComponent.materials.map { material in
guard var customMaterial = material as? CustomMaterial else { return material }
// Passing audioLevel, elapsedTime, sceneTime, and multiplier
customMaterial.custom.value = SIMD4<Float>(audioLevel, elapsedTime, sceneTime, multiplier)
return customMaterial
}
entity.components[ModelComponent.self] = modelComponent
}
}
}
metal:
struct CustomMaterialUniforms { float4 custom; };
[[visible]] void fractalShader(realitykit::surface_parameters params) { auto uniforms = params.uniforms(); float4 customValues = uniforms.custom_parameter(); float audioLevel = customValues.x;
....
Thank you for the assistance
Hello @BLHimmel,
I believe that withMutableUniforms(ofType:stage:_:) is exactly the method you are looking for.
Take a look over the documentation on that page :)
-g