Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- public class ConwayCompute : MonoBehaviour
- {
- public ComputeShader computeShader;
- public int width = 300;
- public int height = 300;
- public RenderTexture renderTexture1;
- public RenderTexture renderTexture2;
- private bool useRenderTexture1 = true;
- void Start()
- {
- InitializeTextures();
- RandomInitialize();
- }
- void InitializeTextures()
- {
- renderTexture1 = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat);
- renderTexture1.enableRandomWrite = true;
- renderTexture1.Create();
- renderTexture2 = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat);
- renderTexture2.enableRandomWrite = true;
- renderTexture2.Create();
- }
- void RandomInitialize()
- {
- computeShader.SetTexture(1, "currentBuffer", useRenderTexture1 ? renderTexture1 : renderTexture2);
- computeShader.SetTexture(1, "nextBuffer", useRenderTexture1 ? renderTexture2 : renderTexture1);
- computeShader.Dispatch(1, width / 16, height / 16, 1);
- }
- private void OnRenderImage(RenderTexture src, RenderTexture dest)
- {
- computeShader.SetTexture(0, "currentBuffer", useRenderTexture1 ? renderTexture1 : renderTexture2);
- computeShader.SetTexture(0, "nextBuffer", useRenderTexture1 ? renderTexture2 : renderTexture1);
- computeShader.Dispatch(0, width / 16, height / 16, 1);
- // Swap render textures for the next frame
- useRenderTexture1 = !useRenderTexture1;
- // Display the result using Graphics.Blit
- Graphics.Blit(useRenderTexture1 ? renderTexture1 : renderTexture2, dest);
- }
- void OnDestroy()
- {
- renderTexture1.Release();
- renderTexture2.Release();
- }
- }
- #pragma kernel CSMain
- #pragma kernel CSRandomInit
- RWTexture2D<float> currentBuffer;
- RWTexture2D<float> nextBuffer;
- [numthreads(16, 16, 1)]
- void CSMain (uint3 id : SV_DispatchThreadID) {
- uint2 texDim;
- currentBuffer.GetDimensions(texDim.x, texDim.y);
- uint2 cellPos = id.xy;
- float current = currentBuffer[cellPos];
- // Count live neighbors
- int count = 0;
- for (int x = -1; x <= 1; x++) {
- for (int y = -1; y <= 1; y++) {
- if (x == 0 && y == 0) continue;
- float neighbor = currentBuffer[clamp(cellPos + uint2(x, y), uint2(0, 0), texDim - uint2(1, 1))];
- count += (int)neighbor;
- }
- }
- // Apply Game of Life rules
- float next = 0.0;
- if (current > 0.5) { // Cell is alive
- if (count < 2 || count > 3) next = 0.0; // Loneliness or overcrowding
- else next = 1.0; // Survival
- } else { // Cell is dead
- if (count == 3) next = 1.0; // Reproduction
- else next = 0.0; // Stay dead
- }
- nextBuffer[cellPos] = next;
- }
- [numthreads(16, 16, 1)]
- void CSRandomInit (uint3 id : SV_DispatchThreadID) {
- // Seed the pseudo-random number generator with thread ID
- uint seed = ((id.x & 0xFF) << 24) | ((id.y & 0xFF) << 16) | (id.z & 0xFFFF);
- // Use a simple pseudo-random algorithm (XORSHIFT) to generate a value between 0 and 1
- uint randState = seed;
- randState ^= randState << 13;
- randState ^= randState >> 17;
- randState ^= randState << 5;
- float randomValue = float(randState & 0xFFFFFF) / float(0xFFFFFF);
- // Set the cell state based on the random value
- currentBuffer[id.xy] = (randomValue > 0.5) ? 1.0 : 0.0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement