Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections;
- using System.Collections.Generic;
- using System.Security.Cryptography;
- using Unity.VisualScripting;
- using UnityEngine;
- //Red = 0
- //Blue = 1
- //Yellow = 2
- //Green = 3
- public struct Particle
- {
- public byte type;
- public Vector2 pos;
- public Vector2 vel;
- }
- public enum matrixPreset
- {
- random,
- symmetry,
- chains,
- chains2,
- chains3,
- snakes,
- zero
- }
- public class Main : MonoBehaviour
- {
- public matrixPreset preset;
- public RenderTexture renderTexture;
- public ComputeShader computeShader;
- public int particleCount;
- public float particleSize;
- public float forceFactor;
- public float maxDist;
- public float friction;
- public Material particleMaterial;
- float[,] attractionMatrix;
- Particle[] particles;
- void Start()
- {
- switch (preset)
- {
- case matrixPreset.random:
- attractionMatrix = new float[,]
- {
- {Rand(), Rand(), Rand(), Rand(), Rand(), Rand()},
- {Rand(), Rand(), Rand(), Rand(), Rand(), Rand()},
- {Rand(), Rand(), Rand(), Rand(), Rand(), Rand()},
- {Rand(), Rand(), Rand(), Rand(), Rand(), Rand()},
- {Rand(), Rand(), Rand(), Rand(), Rand(), Rand()},
- {Rand(), Rand(), Rand(), Rand(), Rand(), Rand()},
- };
- break;
- case matrixPreset.symmetry:
- float[] rand = new float[22];
- for (int i = 0; i < rand.Length; i++)
- {
- rand[i] = Rand();
- }
- attractionMatrix = new float[,]
- {
- {rand[0], rand[1], rand[2], rand[3], rand[4], rand[5]},
- {rand[1], rand[7], rand[8], rand[9], rand[10], rand[11]},
- {rand[2], rand[8], rand[12], rand[13], rand[14], rand[15]},
- {rand[3], rand[9], rand[13], rand[16], rand[17], rand[18]},
- {rand[4], rand[1], rand[14], rand[17], rand[19], rand[20]},
- {rand[5], rand[1], rand[15], rand[18], rand[20], rand[21]},
- };
- break;
- case matrixPreset.chains:
- attractionMatrix = new float[,]
- {
- {1, 1, -1, -1, -1, 1},
- {1, 1, 1, -1, -1, -1},
- {-1, 1, 1, 1, -1, -1},
- {-1, -1, 1, 1, 1, -1},
- {-1, -1, -1, 1, 1, 1},
- {1, -1, -1, -1, 1, 1},
- };
- break;
- case matrixPreset.chains2:
- attractionMatrix = new float[,]
- {
- {1, .2f, -1, -1, -1, .2f},
- {.2f, 1, .2f, -1, -1, -1},
- {-1, .2f, 1, .2f, -1, -1},
- {-1, -1, .2f, 1, .2f, -1},
- {-1, -1, -1, .2f, 1, .2f},
- {.2f, -1, -1, -1, .2f, 1},
- };
- break;
- case matrixPreset.chains3:
- attractionMatrix = new float[,]
- {
- {1, .2f, 0, 0, 0, 0},
- {.2f, 1, .2f, 0, 0, 0},
- {0, .2f, 1, .2f, 0, 0},
- {0, 0, .2f, 1, .2f, 0},
- {0, 0, 0, .2f, 1, .2f},
- {.2f, 0, 0, 0, .2f, 1},
- };
- break;
- case matrixPreset.snakes:
- attractionMatrix = new float[,]
- {
- {1, .2f, 0, 0, 0, 0},
- {0, 1, .2f, 0, 0, 0},
- {0, 0, 1, .2f, 0, 0},
- {0, 0, 0, 1, .2f, 0},
- {0, 0, 0, 0, 1, .2f},
- {.2f, 0, 0, 0, 0, 1},
- };
- break;
- case matrixPreset.zero:
- attractionMatrix = new float[,]
- {
- {0, 0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0, 0},
- {0, 0, 0, 0, 0, 0},
- };
- break;
- }
- particles = new Particle[particleCount];
- ParticleRenderer.particleSize = particleSize;
- ParticleRenderer.particleMat = particleMaterial;
- for (int i = 0; i < particleCount; i++)
- {
- Vector2 position = new Vector2(Random.Range(-9f, 9f), Random.Range(-9f, 9f));
- particles[i] = new Particle
- {
- type = (byte)Random.Range(0, 6),
- pos = position,
- vel = Vector2.zero
- };
- }
- renderTexture = new RenderTexture(256, 256, 24);
- renderTexture.enableRandomWrite = true;
- renderTexture.Create();
- }
- private void OnRenderImage(RenderTexture source, RenderTexture destination)
- {
- computeShader.SetTexture(0, "Result", renderTexture);
- Graphics.Blit(renderTexture, destination);
- }
- void Update()
- {
- for (int i = 0; i < particleCount; i++)
- {
- UpdatePosition(i);
- UpdateForce(i);
- }
- // int length = particleCount * particleCount;
- // for (int index = 0; index < length; index++)
- // {
- // int i = index / particleCount;
- // int j = index % particleCount;
- // if (j < particleCount)
- // {
- // UpdatePosition(i);
- // }
- // if (j == i) { continue; }
- // UpdateForce(i, j);
- // }
- ParticleRenderer.Render(particles);
- }
- void UpdatePosition(int i)
- {
- particles[i].pos += particles[i].vel * Time.deltaTime;
- //If particle is outside screen, put it on other side
- if (Mathf.Abs(particles[i].pos.x) > 10f || Mathf.Abs(particles[i].pos.y) > 10f)
- {
- particles[i].pos = -particles[i].pos;
- particles[i].pos += particles[i].vel;
- }
- }
- //Explanation: https://www.youtube.com/watch?v=scvuli-zcRc&t=101s
- void UpdateForce(int i)
- {
- Vector2 totalForce = new();
- byte thisType = particles[i].type;
- for (int j = 0; j < particleCount; j++)
- {
- if (j == i) { continue; }
- byte targetType = particles[j].type;
- Vector2 diff = particles[j].pos - particles[i].pos;
- float dist = diff.magnitude;
- if (dist > 0 && dist < maxDist)
- {
- float force = Force(dist / maxDist, attractionMatrix[thisType, targetType]);
- totalForce += new Vector2(diff.x / dist * force, diff.y / dist * force);
- }
- }
- totalForce *= maxDist * forceFactor;
- particles[i].vel *= friction;
- particles[i].vel += totalForce * Time.deltaTime;
- }
- float Force(float dist, float attraction)
- {
- const float beta = .3f;
- if (dist < beta)
- {
- return dist / beta - 1;
- }
- else if (beta < dist && dist < 1)
- {
- return attraction * (1 - Mathf.Abs(2 * dist - 1 - beta) / (1 - beta));
- }
- else
- {
- return 0;
- }
- }
- float Rand()
- {
- return Random.Range(-1f, 1f);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement