praeclarum / ShaderGraphCoder

Write RealityKit shaders using Swift
144 stars 2 forks source link

More examples please! #2

Open mgrider opened 8 months ago

mgrider commented 8 months ago

I love the idea of this, and really want to convert my shader graph materials to use it, but I'm stuck on an issue that I'm not sure how to solve.

All I want is to create a multi-color material. (Ideally with the colors moving, but I'm okay adding that in the next step.) Here's what I have so far:

    func cubeMaterial() async throws -> ShaderGraphMaterial {
        let color1: SGColor = .color3f([1, 0, 0])
        let color2: SGColor = .color3f([0, 1, 0])

        let color: SGColor = SGValue.modelPosition.x > 0 ? color1 : color2
//  ^^^^ error here ^^^^
// "Referencing operator function '>' on 'BinaryInteger' requires that 'SGScalar' conform to 'BinaryInteger'"

        let surface = SGPBRSurface(baseColor: color)
        return try await ShaderGraphMaterial(surface: surface, geometryModifier: nil)
    }

Incidentally, I think something like this could go in (or get linked from) the readme to help get folks started:

import SwiftUI
import RealityKit
import RealityKitContent
import ShaderGraphCoder

struct ImmersiveView: View {

    var cubeMesh: MeshResource = .generateBox(size: 0.5, cornerRadius: 0.01)
    var cubeResource: ShapeResource = .generateBox(size: .init(x: 0.5, y: 0.5, z: 0.5))

    func cubeMaterial() async throws -> ShaderGraphMaterial {
        // pulsing blue example
        let frequency = SGValue.floatParameter(name: "Frequency", defaultValue: 2)
        let color: SGColor = .color3f([0, 0, 1]) * sin(SGValue.time * frequency * (2*Float.pi))
        let surface = SGPBRSurface(baseColor: color)
        return try await ShaderGraphMaterial(surface: surface, geometryModifier: nil)
    }

    var body: some View {
        RealityView { content in
            let entity = ModelEntity(mesh: cubeMesh)
            entity.position.y = 2
            entity.position.z = -2

            if let material = try? await cubeMaterial() {
                entity.model?.materials = [material]
            }

            content.add(entity)
        }
    }
}

#Preview(immersionStyle: .mixed) {
    ImmersiveView()
}
praeclarum commented 8 months ago

Ahh, I need to add support for >. Thanks for the report!

Good news there is the .ifGreaterOrEqual operator that can be used in your case. https://github.com/praeclarum/ShaderGraphCoder/blob/2fa82c55244668585939ec119c920846dd1b3206/Sources/ShaderGraphCoder/Operations.swift#L89