Image Drawn With Particles in Unity

By Mark Smith | code, csharp, unity
6 Jun 2013

I figured it’s finally time to learn Unity, especially now that it’s free for Android and iOS development. I wanted to start with something simple, so I first spent some time working through some great text-based tutorials over at Catlike Coding. I decided to expand on what I learned from the graphs tutorial and attempt to use particles to display an image in 3D.

Turns out that it was fairly straightforward to accomplish what I wanted. First I dragged an image into the Assets panel in Unity, and named it “test”. I need access to the image/pixel data, so I checked “Read/Write Enabled” in the “Import Settings” for the texture. Then I created a particle system with Game Object –> Create Other –> Particle System. Then I made a new C# Script with Assets –> Create –> C# Script and called it ParticlesImage.

Here’s the entirety of ParticlesImage.cs:

using UnityEngine;
using System.Collections;

public class ParticlesImage : MonoBehaviour
{
    private ParticleSystem.Particle[] points;

    public Texture2D testTexture;

    void Start ()
    {
        CreatePoints();
    }

    private void CreatePoints()
    {
        int numParticles = testTexture.width * testTexture.height;

        points = new ParticleSystem.Particle[numParticles];

        float incrementX = 1f / (testTexture.width - 1);
        float incrementZ = 1f / (testTexture.height - 1);

        // retrieve the color values of all pixels in the texture
        Color32[] texturePixels = testTexture.GetPixels32();

        int i = 0;
        for (int x = 0; x < testTexture.width; x++)
        {
            for (int z = 0; z < testTexture.height; z++)
            {
                Color32 tempColor = texturePixels[x + z * testTexture.width];
                float grayscale =  ((Color)tempColor).grayscale;
                Vector3 p = new Vector3(x * incrementX, (grayscale / 1.0f) * 0.15f, z * incrementZ);
                points[i].position = p;
                points[i].color = tempColor;
                points[i].size = .01f;
                i++;
            }
        }
    }

    void Update ()
    {
        particleSystem.SetParticles(points, points.Length);
    }
}

It’s pretty straightforward – first we create one particle for each pixel in the source texture. Then we position the particles in a grid to represent the image. Then we simply read in the texture’s pixel data and use that to assign a color to each particle. To make it a bit more interesting, we adjust the depth of the particles a little based on each pixel’s grayscale value, which gives us a 3D effect.

To allow camera movement, I used the maxCamera class. To move around the scene, left-click and drag to pan, alt + left-click to orbit, and ctrl + alt + left-click and move mouse up/down to zoom (or just use the scroll-wheel).

This is about the least efficient way I can think to represent an image, but it was fun and taught me a little bit about Unity, camera control and placement, scripting, and particle systems.

Click on the image to try it out. I used a screenshot from the Game Boy Advance version of one of my favorite games, Super Ghouls ‘N Ghosts.

imageofparticles_0001

Full source for ParticlesImage.cs.

Tags: , ,

Leave a Reply

Your email address will not be published. Required fields are marked *