1

I'm making a cellular automata based sand simulation in unity, and the way I'm doing it right now (looping through every pixel in the texture, checking it's color, and depending on that color I check what pixels are below and to the side of it, then moving it accordingly), is VERY inefficient and slow. I've heard that I can do something similar but much faster with compute shaders, and I was wondering how do I apply a calculation to every pixel in a texture according to it's color in a compute shader. My previous, non-compute shader code (C#):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SimulateCells : MonoBehaviour
{
    public Texture2D texture;

    // Update is called once per frame
    void Update()
    {
        UpdateCells();
        texture.Apply();
    }

    void UpdateCells()
    {
        for (int y = 0; y < texture.height; y++)
        {
            for (int x = 0; x < texture.width; x++)
            {
                if (CellTypeDatabase.instance.colors.Contains(texture.GetPixel(x, y)) && x != texture.width - 1 && x != 0 && y != texture.height - 1 && y != 0)
                {
                    CellObject cell = CellTypeDatabase.instance.cellObjects[CellTypeDatabase.instance.colors.IndexOf(texture.GetPixel(x, y))];
                    Color pixel = texture.GetPixel(x, y);
                    if (cell.useRigidGravity)
                    {
                        if (texture.GetPixel(x, y - 1) == Color.white || texture.GetPixel(x, y - 1) == CellTypeDatabase.instance.cellObjects[2].color)
                        {
                            texture.SetPixel(x, y, texture.GetPixel(x, y - 1));
                            texture.SetPixel(x, y - 1, pixel);
                        }
                    }
                    else if (cell.usePowderGravity)
                    {
                        if (texture.GetPixel(x, y - 1) == Color.white || texture.GetPixel(x, y - 1) == CellTypeDatabase.instance.cellObjects[2].color)
                        {
                            texture.SetPixel(x, y, texture.GetPixel(x, y - 1));
                            texture.SetPixel(x, y - 1, pixel);
                        }
                        else if (texture.GetPixel(x - 1, y - 1) == Color.white || texture.GetPixel(x - 1, y - 1) == CellTypeDatabase.instance.cellObjects[2].color)
                        {
                            texture.SetPixel(x, y, texture.GetPixel(x - 1, y - 1));
                            texture.SetPixel(x - 1, y - 1, pixel);
                        }
                        else if (texture.GetPixel(x + 1, y - 1) == Color.white || texture.GetPixel(x + 1, y - 1) == CellTypeDatabase.instance.cellObjects[2].color)
                        {
                            texture.SetPixel(x, y, texture.GetPixel(x + 1, y - 1));
                            texture.SetPixel(x + 1, y - 1, pixel);
                        }
                    }
                    else if (cell.useLiquidGravity)
                    {
                        if (texture.GetPixel(x, y - 1) == Color.white)
                        {
                            texture.SetPixel(x, y, Color.white);
                            texture.SetPixel(x, y - 1, pixel);
                        }
                        else if (texture.GetPixel(x + 1, y - 1) == Color.white)
                        {
                            texture.SetPixel(x, y, Color.white);
                            texture.SetPixel(x + 1, y - 1, pixel);
                        }
                        else if (texture.GetPixel(x - 1, y - 1) == Color.white)
                        {
                            texture.SetPixel(x, y, Color.white);
                            texture.SetPixel(x - 1, y - 1, pixel);
                        }
                        else if (texture.GetPixel(x - 1, y) == Color.white)
                        {
                            texture.SetPixel(x, y, Color.white);
                            texture.SetPixel(x - 1, y, pixel);
                        }
                        else if (texture.GetPixel(x + 1, y) == Color.white)
                        {
                            texture.SetPixel(x, y, Color.white);
                            texture.SetPixel(x + 1, y, pixel);
                        }

                    }
                }
                else
                {
                    continue;
                }
            }
        }
    }
}
NivMizzer
  • 38
  • 4
  • I just did a google, [Rendering and Shading](https://learn.unity.com/tutorial/rendering-and-shading) – Jeroen van Langen Apr 07 '21 at 06:41
  • @JeroenvanLangen That's irrelevant to the question I asked. Not only does it not have anything to do with doing a calculation on specific pixels, it also covers shaders, not compute shaders. – NivMizzer Apr 07 '21 at 06:57
  • What Jeroen means is that compute shaders are a complex matter, and you seem to know very little (if any) about them. This site is not a “write code for me” one. You need to study how to code them, and ask us specific questions. – kefren Apr 21 '21 at 17:07

0 Answers0