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;
}
}
}
}
}