// Each #kernel tells which function to compile; you can have many kernels #pragma kernel CSMain // Create a RenderTexture with enableRandomWrite flag and set it // with cs.SetTexture RWStructuredBuffer oldVegetation; RWStructuredBuffer vegetation; RWStructuredBuffer oldWater; RWStructuredBuffer water; RWStructuredBuffer feedModifier; RWStructuredBuffer killModifier; int sizeX; int sizeY; float DWater; float DVegetation; float feedRate; float killRate; float dT; int index(int x, int y) { return x + sizeX * y; } float get(RWStructuredBuffer array, int x, int y) { int idx = index(x, y); if (idx < 0 || idx >= sizeX * sizeY) { return 0; } return array[idx]; } float laplace(RWStructuredBuffer array, int x, int y) { return 0.2 * (get(array, x + 1, y) + get(array, x - 1, y) + get(array, x, y + 1) + get(array, x, y - 1)) + 0.05 * (get(array, x + 1, y + 1) + get(array, x + 1, y - 1) + get(array, x - 1, y + 1) + get(array, x - 1, y - 1)) - get(array, x, y); } [numthreads(8,8,1)] void CSMain (uint3 id : SV_DispatchThreadID) { int x = id.x; int y = id.y; float w = oldWater[index(x, y)]; float r = oldVegetation[index(x, y)]; float feed = feedRate * feedModifier[index(x, y)]; float kill = killRate * killModifier[index(x, y)]; water[index(x, y)] = clamp(w + dT * DWater * laplace(oldWater, x, y) - w * w * r * r + feed, 1, 0); vegetation[index(x, y)] = clamp(r + dT * (DVegetation * laplace(oldVegetation, x, y) + r * (w * r - kill)), 1, 0); }