-
Notifications
You must be signed in to change notification settings - Fork 0
/
PerlinSeaParticleSystem.cs
87 lines (71 loc) · 2.74 KB
/
PerlinSeaParticleSystem.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PerlinSeaParticleSystem : MonoBehaviour
{
[Header("Assign each script")]
[SerializeField] Mesh mesh = default;
[SerializeField] Material material = default;
[SerializeField] ComputeShader computeShader = default;
ComputeBuffer computeBuffer;
ComputeBuffer uvBuffer;
[Header("Custom Pattern Data")]
[Range(10, 200)] public int resolution = 10;
[Range(0.1f, 5f)] public float amplitude = 0.5f;
[Range(0, 1)] public float speed = 0.5f;
int _resolution = 10;
static readonly int
resolutionId = Shader.PropertyToID("_Resolution"),
positionsId = Shader.PropertyToID("_Positions"),
amplitudeId = Shader.PropertyToID("_Amplitude"),
speedId = Shader.PropertyToID("_Speed"),
timeId = Shader.PropertyToID("_Time"),
uvcoordId= Shader.PropertyToID("_UV_coord"),
stepId = Shader.PropertyToID("_Step");
void CreateComputeBuffer(){
computeBuffer = new ComputeBuffer(resolution * resolution, 3 * sizeof(float));
}
void DiscardComputeBuffer(){
computeBuffer.Release();
computeBuffer = null;
}
void UpdateFunctionOnGPU(){
//Update argument of compute shader
int kernelId = computeShader.FindKernel("PerlinSea");
computeShader.SetInt(resolutionId, resolution);
computeShader.SetFloat(amplitudeId, amplitude);
computeShader.SetFloat(speedId, speed);
computeShader.SetFloat(timeId, Time.time);
computeShader.SetFloat(stepId, 2.0f/resolution);
computeShader.SetBuffer(kernelId, positionsId, computeBuffer);
//dipatch commpute shader
int groupNumber = Mathf.CeilToInt(resolution / 8);
computeShader.Dispatch(kernelId, groupNumber, groupNumber, 1);
//update argument of material
material.SetFloat(stepId, 2.0f/resolution);
material.SetBuffer(positionsId, computeBuffer);
//call gpu Instancing to draw the particles
var bounds = new Bounds(Vector3.zero, Vector3.one * (2f + 2f/resolution));
// first argument : mesh
// second argument : sub-mesh index
// third argument : material
Graphics.DrawMeshInstancedProcedural(mesh, 0, material, bounds, computeBuffer.count);
}
void OnValueChange(){
//recreate a compute buffer (because the buffer size is different)
if (_resolution != resolution){
DiscardComputeBuffer();
CreateComputeBuffer();
}
}
void OnEnable(){
CreateComputeBuffer();
}
void OnDisable(){
DiscardComputeBuffer();
}
void Update(){
// OnValueChange();
UpdateFunctionOnGPU();
}
}