Skip to content

Instantly share code, notes, and snippets.

@Matt54
Created June 30, 2024 12:26
Show Gist options
  • Save Matt54/ed3660c57101d2f9e1b59212abf70ef4 to your computer and use it in GitHub Desktop.
Save Matt54/ed3660c57101d2f9e1b59212abf70ef4 to your computer and use it in GitHub Desktop.
A blend of many spheres with varying opacity and size fading in and out
import RealityKit
import SwiftUI
struct GlowingSphere: View {
@State private var opacity: Float = 1.0
@State private var isForward: Bool = false
var body: some View {
GeometryReader3D { proxy in
RealityView { content in
let size = content.convert(proxy.frame(in: .local), from: .local, to: .scene).extents
let radius = Float(0.5 * size.x)
let entity = glowingSphereEntity(radius: radius)
content.add(entity)
entity.components.set(OpacityComponent(opacity: opacity))
} update: { content in
if let entity = content.entities.first {
entity.components.set(OpacityComponent(opacity: opacity))
}
}
}
.onAppear {
startOpacityTimer()
}
}
private func startOpacityTimer() {
Timer.scheduledTimer(withTimeInterval: 1/120.0, repeats: true) { _ in
if isForward {
opacity += 0.01
if opacity >= 1.0 {
isForward = false
}
} else {
opacity -= 0.01
if opacity <= 0.0 {
isForward = true
}
}
}
}
func glowingSphereEntity(radius: Float) -> Entity {
let sphereEntity = Entity()
let numSpheres = 100
for i in 0..<numSpheres {
let fraction = Float(i) / Float(numSpheres)
let sphereRadius = radius * (1.0 - fraction * 1.0)
let opacity = pow(fraction, 3) // Quadratic exaggerates effect
let sphere = Entity()
sphere.components.set(getModelComponent(radius: sphereRadius, opacity: opacity))
sphereEntity.addChild(sphere)
}
sphereEntity.scale *= scalePreviewFactor
return sphereEntity
}
func getModelComponent(radius: Float, opacity: Float) -> ModelComponent {
var material = UnlitMaterial()
material.color.tint = .yellow
material.blending = .transparent(opacity: .init(floatLiteral: opacity))
material.faceCulling = .front
let sphereMesh = MeshResource.generateSphere(radius: radius)
return ModelComponent(mesh: sphereMesh, materials: [material])
}
}
#Preview {
GlowingSphere()
}
var isPreview: Bool {
return ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1"
}
var scalePreviewFactor: Float = isPreview ? 0.3 : 1.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment