Lab 056 – Using Emoji in Particle Emitters
We can render emoji as Texture Resources to be used in our Particle Emitters.
Overview
Building on what we saw in Lab 055, I was wondering if we could render emoji too. We can, but with a notable caveat.
Let’s take a look at generateTextureFromEmoji. We create an attributed string and place it in the center, then render it as an image.
// Adapted from generateTextureFromSystemName in the example project called "Simulating particles in your visionOS app"
// Sources: https://developer.apple.com/documentation/realitykit/simulating-particles-in-your-visionos-app
func generateTextureFromEmoji(_ emoji: String) -> TextureResource? {
// Create aa image from an emoji
let imageSize = CGSize(width: 128, height: 128)
// Start the graphics context
UIGraphicsBeginImageContextWithOptions(imageSize, false, 0)
// Create an attributed string with the emoji
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 96) // Large size to fill the texture
]
let attributedString = NSAttributedString(string: emoji, attributes: attributes)
// Calculate the size of the emoji
let stringSize = attributedString.size()
// Calculate the position to center the emoji
let x = (imageSize.width - stringSize.width) / 2
let y = (imageSize.height - stringSize.height) / 2
// Draw the emoji
attributedString.draw(at: CGPoint(x: x, y: y))
// Get the image from the context
let contextImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
// Convert to texture resource
guard let coreGraphicsImage = contextImage?.cgImage else {
return nil
}
let creationOptions = TextureResource.CreateOptions(semantic: .raw)
return try? TextureResource(image: coreGraphicsImage, options: creationOptions)
}The caveat I mentioned is on ParticleEmitterComponent. So far, I have not found a way to create a particle that does not have a color. Passing in .clear will create transparent particles. It seems like we have to provide at least one color to the particle. The best option I found was to use .white. This will apply a slight tint to the emoji, but they still recognizable. Passing any other color tinted them too much. Let me know if you have any ideas for how to solve this.
I have no idea if Apple will approve an app that uses emoji like this. I know there are been instances of them rejecting apps for using emoji outside of their intended use case.
Full Lab Code
struct Lab056: View {
@State private var selectedEmojo: String = "❤️"
let emoji = ["❤️", "🎉", "🏳️🌈", "🐸", "🚀", "🌸"]
var body: some View {
RealityView { content in
let subject = Entity()
subject.name = "Particles"
content.add(subject)
// Create the particle emitter
var particleSystem = ParticleEmitterComponent()
particleSystem.isEmitting = true
particleSystem.speed = 0.01
particleSystem.emitterShape = .sphere
particleSystem.emitterShapeSize = [0.3, 0.3, 0.3]
// Set the image to the result of generateTextureFromSystemName using a symbol name
particleSystem.mainEmitter.image = generateTextureFromEmoji(selectedEmojo)
particleSystem.mainEmitter.birthRate = 25
particleSystem.mainEmitter.size = 0.1
// Issues: I haven't found a way to specify no color for the particles.
// The best option I found is to provide a white constant color. This will tint the emoji a bit.
particleSystem.mainEmitter.color = .constant(.single(.white))
// Add the component to the entity
subject.components.set(particleSystem)
} update: { content in
if let subject = content.entities.first?.findEntity(named: "Particles") {
if var particleSystem = subject.components[ParticleEmitterComponent.self] {
particleSystem.mainEmitter.image = generateTextureFromEmoji(selectedEmojo)
subject.components.set(particleSystem)
}
}
}
.toolbar {
ToolbarItem(placement: .bottomOrnament, content: {
HStack {
ForEach(emoji, id: \.self) { symbol in
Text(symbol)
.frame(width: 32, height: 32)
.foregroundColor(.white)
.onTapGesture {
selectedEmojo = symbol
}
.padding(6)
.background( selectedEmojo == symbol ? .white : Color.clear)
.clipShape(.circle)
}
}
})
}
}
// Adapted from generateTextureFromSystemName in the example project called "Simulating particles in your visionOS app"
// Sources: https://developer.apple.com/documentation/realitykit/simulating-particles-in-your-visionos-app
func generateTextureFromEmoji(_ emoji: String) -> TextureResource? {
// Create aa image from an emoji
let imageSize = CGSize(width: 128, height: 128)
// Start the graphics context
UIGraphicsBeginImageContextWithOptions(imageSize, false, 0)
// Create an attributed string with the emoji
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 96) // Large size to fill the texture
]
let attributedString = NSAttributedString(string: emoji, attributes: attributes)
// Calculate the size of the emoji
let stringSize = attributedString.size()
// Calculate the position to center the emoji
let x = (imageSize.width - stringSize.width) / 2
let y = (imageSize.height - stringSize.height) / 2
// Draw the emoji
attributedString.draw(at: CGPoint(x: x, y: y))
// Get the image from the context
let contextImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
// Convert to texture resource
guard let coreGraphicsImage = contextImage?.cgImage else {
return nil
}
let creationOptions = TextureResource.CreateOptions(semantic: .raw)
return try? TextureResource(image: coreGraphicsImage, options: creationOptions)
}
}Support our work so we can continue to bring you new examples and articles.
Download the Xcode project with this and many more labs from Step Into Vision.

Follow Step Into Vision