├── .gitignore ├── Assets ├── GPUInstancingParticles.meta ├── GPUInstancingParticles │ ├── Editor.meta │ ├── Editor │ │ ├── MeshRendererEditor.cs │ │ └── MeshRendererEditor.cs.meta │ ├── Material.meta │ ├── Material │ │ ├── matGPUParticles.mat │ │ ├── matGPUParticles.mat.meta │ │ ├── matParticleRT.mat │ │ ├── matParticleRT.mat.meta │ │ ├── sprRect.png │ │ └── sprRect.png.meta │ ├── Script.meta │ ├── Script │ │ ├── GpuInstancingParticles.cs │ │ ├── GpuInstancingParticles.cs.meta │ │ ├── TestMove.cs │ │ └── TestMove.cs.meta │ ├── Shader.meta │ ├── Shader │ │ ├── particleComputeShader.compute │ │ ├── particleComputeShader.compute.meta │ │ ├── shaderParticles.shader │ │ ├── shaderParticles.shader.meta │ │ ├── shaderParticlesRT.shader │ │ └── shaderParticlesRT.shader.meta │ ├── scene.unity │ └── scene.unity.meta ├── TestMove.cs └── TestMove.cs.meta ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset └── UnityConnectSettings.asset ├── README.md └── gpuparticle.gif /.gitignore: -------------------------------------------------------------------------------- 1 | /Library/ 2 | /obj/ 3 | /.vs/ 4 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a3758a525923f74399db6f50a905631 3 | folderAsset: yes 4 | timeCreated: 1509461564 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 346e6b1b5a234064db84826342c99e61 3 | folderAsset: yes 4 | timeCreated: 1509463273 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Editor/MeshRendererEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | using UnityEditorInternal; 5 | using System.Reflection; 6 | using System; 7 | [CanEditMultipleObjects] 8 | [CustomEditor(typeof(MeshRenderer))] 9 | public class MeshRendererEditor : Editor 10 | { 11 | public override void OnInspectorGUI() 12 | { 13 | base.OnInspectorGUI(); 14 | serializedObject.Update(); 15 | SerializedProperty sortingLayerID = serializedObject.FindProperty("m_SortingLayerID"); 16 | SerializedProperty sortingOrder = serializedObject.FindProperty("m_SortingOrder"); 17 | //MeshRenderer renderer = target as MeshRenderer; 18 | Rect firstHoriz = EditorGUILayout.BeginHorizontal(); 19 | EditorGUI.BeginChangeCheck(); 20 | EditorGUI.BeginProperty(firstHoriz, GUIContent.none, sortingLayerID); 21 | string[] layerNames = GetSortingLayerNames(); 22 | int[] layerID = GetSortingLayerUniqueIDs(); 23 | int selected = -1; 24 | int sID = sortingLayerID.intValue; 25 | for (int i = 0; i < layerID.Length; i++) 26 | if (sID == layerID[i]) 27 | selected = i; 28 | if (selected == -1) 29 | for (int i = 0; i < layerID.Length; i++) 30 | if (layerID[i] == 0) 31 | selected = i; 32 | selected = EditorGUILayout.Popup("Sorting Layer", selected, layerNames); 33 | sortingLayerID.intValue = layerID[selected]; 34 | EditorGUI.EndProperty(); 35 | EditorGUILayout.EndHorizontal(); 36 | EditorGUILayout.BeginHorizontal(); 37 | EditorGUI.BeginChangeCheck(); 38 | EditorGUILayout.PropertyField(sortingOrder, new GUIContent("Order in Layer")); 39 | EditorGUILayout.EndHorizontal(); 40 | serializedObject.ApplyModifiedProperties(); 41 | } 42 | public string[] GetSortingLayerNames() 43 | { 44 | Type internalEditorUtilityType = typeof(InternalEditorUtility); 45 | PropertyInfo sortingLayersProperty = internalEditorUtilityType.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic); 46 | return (string[])sortingLayersProperty.GetValue(null, new object[0]); 47 | } 48 | public int[] GetSortingLayerUniqueIDs() 49 | { 50 | Type internalEditorUtilityType = typeof(InternalEditorUtility); 51 | PropertyInfo sortingLayerUniqueIDsProperty = internalEditorUtilityType.GetProperty("sortingLayerUniqueIDs", BindingFlags.Static | BindingFlags.NonPublic); 52 | return (int[])sortingLayerUniqueIDsProperty.GetValue(null, new object[0]); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Editor/MeshRendererEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 00949c95a069dc744965be3e9865e167 3 | timeCreated: 1509463279 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Material.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 55225386258054545ab8199a2b4ce548 3 | folderAsset: yes 4 | timeCreated: 1509461600 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Material/matGPUParticles.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/Assets/GPUInstancingParticles/Material/matGPUParticles.mat -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Material/matGPUParticles.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 47b02a6637c6b0f4786c79a48f66f5c2 3 | timeCreated: 1509462623 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 2100000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Material/matParticleRT.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/Assets/GPUInstancingParticles/Material/matParticleRT.mat -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Material/matParticleRT.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1745d8f6d46b85945b2425076280b7a0 3 | timeCreated: 1509463103 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 2100000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Material/sprRect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/Assets/GPUInstancingParticles/Material/sprRect.png -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Material/sprRect.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9ccd268bcd3637a4b8e7d99f76be3eb2 3 | timeCreated: 1509462568 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 4 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | sRGBTexture: 1 12 | linearTexture: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapsPreserveCoverage: 0 16 | alphaTestReferenceValue: 0.5 17 | mipMapFadeDistanceStart: 1 18 | mipMapFadeDistanceEnd: 3 19 | bumpmap: 20 | convertToNormalMap: 0 21 | externalNormalMap: 0 22 | heightScale: 0.25 23 | normalMapFilter: 0 24 | isReadable: 0 25 | grayScaleToAlpha: 0 26 | generateCubemap: 6 27 | cubemapConvolution: 0 28 | seamlessCubemap: 0 29 | textureFormat: 1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | serializedVersion: 2 33 | filterMode: 0 34 | aniso: 16 35 | mipBias: 0 36 | wrapU: 0 37 | wrapV: 0 38 | wrapW: 0 39 | nPOTScale: 0 40 | lightmap: 0 41 | compressionQuality: 50 42 | spriteMode: 3 43 | spriteExtrude: 1 44 | spriteMeshType: 1 45 | alignment: 0 46 | spritePivot: {x: 0.5, y: 0.5} 47 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 48 | spritePixelsToUnits: 4 49 | alphaUsage: 1 50 | alphaIsTransparency: 0 51 | spriteTessellationDetail: -1 52 | textureType: 8 53 | textureShape: 1 54 | maxTextureSizeSet: 0 55 | compressionQualitySet: 0 56 | textureFormatSet: 0 57 | platformSettings: 58 | - buildTarget: DefaultTexturePlatform 59 | maxTextureSize: 2048 60 | textureFormat: 4 61 | textureCompression: 1 62 | compressionQuality: 50 63 | crunchedCompression: 0 64 | allowsAlphaSplitting: 0 65 | overridden: 0 66 | spriteSheet: 67 | serializedVersion: 2 68 | sprites: [] 69 | outline: 70 | - - {x: -2, y: -2} 71 | - {x: -2, y: 2} 72 | - {x: 2, y: 2} 73 | - {x: 2, y: -2} 74 | physicsShape: 75 | - - {x: -2, y: -2} 76 | - {x: -2, y: 2} 77 | - {x: 2, y: 2} 78 | - {x: 2, y: -2} 79 | spritePackingTag: 80 | userData: 81 | assetBundleName: 82 | assetBundleVariant: 83 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Script.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a4eb04f772b2ac74bafba2f13975206b 3 | folderAsset: yes 4 | timeCreated: 1509461786 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Script/GpuInstancingParticles.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | 6 | 7 | 8 | public class GpuInstancingParticles : MonoBehaviour 9 | { 10 | private const int count = 1024; 11 | 12 | public Mesh mesh; 13 | public Material mat; 14 | public Camera m_targetCamera; 15 | public MeshRenderer m_maskrender; 16 | 17 | [Header("Colider")] 18 | public BoxCollider2D m_Collider; 19 | public Vector3 m_CollidersData; 20 | 21 | 22 | 23 | 24 | [Range(1, 20)] 25 | public int m_physicalUpdate = 10; 26 | private float m_timedelta = 0; 27 | private Vector4 m_generatePosOri = Vector4.zero; 28 | 29 | [Header("RT")] 30 | [Range(0.25f, 1.0f)] 31 | public float m_rtSize = 1.0f; 32 | private RenderTexture m_particleRT; 33 | 34 | public bool m_drawGizmos = false; 35 | public Rect m_generateRect = new Rect(0, 1080, 1920, 1080); 36 | [Range(100f, -100f)] 37 | public float m_bottomOffset = -10f; 38 | 39 | 40 | 41 | 42 | private CommandBuffer m_commandBuffer; 43 | private uint[] m_bufferArgs; 44 | private ComputeBuffer m_bufferWithArgs; 45 | private Vector4[] m_bufferPosition; 46 | private Vector4[] m_bufferParams; 47 | 48 | private ComputeBuffer m_cbufferPosition; 49 | private ComputeBuffer m_cbufferParams; 50 | public ComputeShader m_particleComputeShader; 51 | private int m_particleKernelId; 52 | 53 | 54 | void Start() 55 | { 56 | m_bufferArgs = new uint[5] { mesh.GetIndexCount(0), count, 0, 0, 0 }; 57 | m_bufferWithArgs = new ComputeBuffer(1, sizeof(uint) * 5, ComputeBufferType.IndirectArguments); 58 | m_bufferWithArgs.SetData(m_bufferArgs); 59 | 60 | m_particleRT = new RenderTexture((int)(Screen.width * m_rtSize), (int)(Screen.height * m_rtSize), 0, RenderTextureFormat.ARGB32); 61 | 62 | if (m_maskrender != null) 63 | { 64 | m_maskrender.material.SetTexture("_ParticleRT", m_particleRT); 65 | } 66 | 67 | m_cbufferParams = new ComputeBuffer(count, sizeof(float) * 4); 68 | m_cbufferPosition = new ComputeBuffer(count, sizeof(float) * 4); 69 | 70 | m_bufferParams = new Vector4[count]; 71 | m_bufferPosition = new Vector4[count]; 72 | 73 | 74 | for (int i = 0; i < count; i++) 75 | { 76 | Vector3 startpos = GeneratePos(); 77 | m_bufferPosition[i].x = startpos.x; //posx 78 | m_bufferPosition[i].y = startpos.y; //posy 79 | m_bufferPosition[i].z = startpos.z; //posz 80 | m_bufferPosition[i].w = m_targetCamera.transform.position.y - m_bottomOffset; //bottom pos 81 | 82 | m_bufferParams[i].x = 0.01f; //size x 83 | m_bufferParams[i].y = Random.Range(0.4f, 0.7f); //size y 84 | m_bufferParams[i].z = Random.Range(4f, 6f); //speed 85 | m_bufferParams[i].w = Time.time; //starttime 86 | } 87 | 88 | m_cbufferPosition.SetData(m_bufferPosition); 89 | m_cbufferParams.SetData(m_bufferParams); 90 | 91 | mat.SetBuffer("_cbufferPosition", m_cbufferPosition); 92 | mat.SetBuffer("_cbufferParams", m_cbufferParams); 93 | 94 | m_timedelta = Time.time; 95 | 96 | m_particleKernelId = m_particleComputeShader.FindKernel("CSParticleKernel"); 97 | m_particleComputeShader.SetBuffer(m_particleKernelId, "_cbufferPosition", m_cbufferPosition); 98 | m_particleComputeShader.SetBuffer(m_particleKernelId, "_cbufferParams", m_cbufferParams); 99 | 100 | m_particleComputeShader.SetVector("_GenRect", new Vector4(m_generateRect.x, m_generateRect.y, m_generateRect.width, m_generateRect.height)); 101 | 102 | ProcessCollider(); 103 | } 104 | 105 | private void ProcessCollider() 106 | { 107 | m_CollidersData = m_Collider.transform.position; 108 | m_CollidersData.z = m_Collider.transform.lossyScale.x * 0.5f; 109 | m_CollidersData.y += m_Collider.transform.lossyScale.y * 0.5f; 110 | 111 | m_particleComputeShader.SetVector("_collider", m_CollidersData); 112 | } 113 | 114 | 115 | private void Update() 116 | { 117 | float t = 1.0f / m_physicalUpdate; 118 | float curtime = Time.time; 119 | 120 | if (curtime - m_timedelta > t) 121 | { 122 | m_timedelta = curtime; 123 | 124 | ProcessCollider(); 125 | 126 | m_particleComputeShader.SetFloat("_Time", curtime); 127 | Vector4 cpos = m_targetCamera.transform.position; 128 | cpos.w = m_targetCamera.transform.position.y - m_bottomOffset; 129 | m_particleComputeShader.SetVector("_CameraPos", cpos); 130 | m_particleComputeShader.Dispatch(m_particleKernelId, count / 64, 1, 1); 131 | 132 | if (m_commandBuffer == null) 133 | { 134 | Debug.Log("Generate Command Buffer"); 135 | 136 | m_commandBuffer = new CommandBuffer(); 137 | m_commandBuffer.name = "GPUInstancingParticles"; 138 | 139 | 140 | var cameraevent = CameraEvent.BeforeForwardOpaque; 141 | 142 | m_commandBuffer.Clear(); 143 | 144 | m_commandBuffer.ClearRenderTarget(true, true,new Color32(0,0,0,0)); 145 | m_commandBuffer.DrawMeshInstancedIndirect(mesh, 0, mat, 0, m_bufferWithArgs); 146 | 147 | m_commandBuffer.Blit(new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget), m_particleRT); 148 | m_targetCamera.RemoveCommandBuffers(cameraevent); 149 | m_targetCamera.AddCommandBuffer(cameraevent, m_commandBuffer); 150 | } 151 | } 152 | } 153 | 154 | private void OnDisable() 155 | { 156 | if (m_particleRT != null) 157 | m_particleRT.Release(); 158 | 159 | if (m_cbufferParams != null) m_cbufferParams.Release(); 160 | if (m_cbufferPosition != null) m_cbufferPosition.Release(); 161 | 162 | if (m_bufferWithArgs != null) m_bufferWithArgs.Release(); 163 | } 164 | 165 | private void ReGenPos(ref Vector4 vec) 166 | { 167 | vec.x = m_generatePosOri.x + m_generateRect.width * (Random.value - 0.5f); 168 | vec.y = m_generatePosOri.y + m_generateRect.height * Random.value; 169 | 170 | vec.w = m_generatePosOri.z; 171 | } 172 | 173 | 174 | private Vector3 GeneratePos() 175 | { 176 | Vector3 vec = m_targetCamera.transform.position; 177 | vec.x += m_generateRect.x + m_generateRect.width * (Random.value - 0.5f); 178 | vec.y += m_generateRect.y + m_generateRect.height * Random.value; 179 | vec.z = 0; 180 | 181 | return vec; 182 | } 183 | 184 | 185 | private void OnDrawGizmos() 186 | { 187 | if (m_targetCamera == null) return; 188 | 189 | Vector2 tarpos = m_targetCamera.transform.position; 190 | float x1 = tarpos.x - m_generateRect.width * 0.5f + m_generateRect.x; 191 | float x2 = tarpos.x + m_generateRect.width * 0.5f + m_generateRect.x; 192 | 193 | float y1 = tarpos.y + m_generateRect.y; 194 | float y2 = tarpos.y + m_generateRect.height + m_generateRect.y; 195 | 196 | Gizmos.DrawLine(new Vector3(x1, y1, 0), new Vector3(x2, y1, 0)); 197 | Gizmos.DrawLine(new Vector3(x1, y2, 0), new Vector3(x2, y2, 0)); 198 | Gizmos.DrawLine(new Vector3(x1, y1, 0), new Vector3(x1, y2, 0)); 199 | Gizmos.DrawLine(new Vector3(x2, y1, 0), new Vector3(x2, y2, 0)); 200 | 201 | 202 | Vector3 bline = m_targetCamera.transform.position; 203 | bline.z = 0; 204 | bline.y -= m_bottomOffset; 205 | 206 | Gizmos.DrawLine(bline - new Vector3(m_generateRect.width * 0.5f, 0, 0), bline + new Vector3(m_generateRect.width * 0.5f, 0, 0)); 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Script/GpuInstancingParticles.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: be942d1801763b341bb26588d30e7c6f 3 | timeCreated: 1509461797 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Script/TestMove.cs: -------------------------------------------------------------------------------- 1 | using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestMove111 : MonoBehaviour {

 // Use this for initialization
 void Start () {

 }
 
 // Update is called once per frame
 void Update () {
 transform.Translate(Mathf.Sin(Time.deltaTime) * 0.01f, 0, 0);
 }
}
 -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Script/TestMove.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 92892ca58f5230244a72d4c80302bfe9 3 | timeCreated: 1509466070 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3cc15f0a2f53e99438ef3fdd9e5094af 3 | folderAsset: yes 4 | timeCreated: 1509461594 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Shader/particleComputeShader.compute: -------------------------------------------------------------------------------- 1 | // Each #kernel tells which function to compile; you can have many kernels 2 | #pragma kernel CSParticleKernel 3 | 4 | #define thread_group_size_x 64 5 | #define thread_group_size_y 1 6 | 7 | //#define COLLISION_ON 8 | 9 | 10 | 11 | // Create a RenderTexture with enableRandomWrite flag and set it 12 | // with cs.SetTexture 13 | RWStructuredBuffer _cbufferPosition; 14 | RWStructuredBuffer _cbufferParams; 15 | 16 | float _Time; 17 | float4 _CameraPos; 18 | float4 _GenRect; 19 | 20 | float4 _collider; 21 | 22 | float hash(float v){ 23 | return frac(v + 52.178*sin(v)); 24 | 25 | } 26 | 27 | float Collision(float bottom,float x,float y,float4 collider){ 28 | 29 | float b = step(x, collider.z+ collider.x) * step(collider.x - collider.z,x) *step(y,collider.y); 30 | return lerp(bottom,max(bottom,collider.y),b); 31 | } 32 | 33 | [numthreads(thread_group_size_x, thread_group_size_y, 1)] 34 | void CSParticleKernel(uint3 id: SV_DispatchThreadID){ 35 | 36 | float4 position = _cbufferPosition[id.x]; 37 | float4 params = _cbufferParams[id.x]; 38 | 39 | float timet = _Time - params.w; 40 | float newp = position.y - params.z * timet; 41 | 42 | position.w = Collision(position.w,position.x,newp, _collider); 43 | 44 | if(newp < position.w){ 45 | 46 | //regenerate 47 | position.x = _CameraPos.x + _GenRect.x + _GenRect.z* (hash(position.x + position.y) - 0.5); 48 | position.y = _CameraPos.y + _GenRect.y + _GenRect.w* (hash(position.x +position.y *94.3461)); 49 | 50 | position.w = _CameraPos.w; 51 | 52 | _cbufferPosition[id.x] = position; 53 | _cbufferParams[id.x].w = _Time; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Shader/particleComputeShader.compute.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e5f7ee49ae023c54eb7a2abf9d347359 3 | timeCreated: 1509461624 4 | licenseType: Free 5 | ComputeShaderImporter: 6 | currentAPIMask: 4 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Shader/shaderParticles.shader: -------------------------------------------------------------------------------- 1 | // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' 2 | 3 | Shader "Unlit/shaderParticles" 4 | { 5 | Properties 6 | { 7 | _MainTex ("Texture", 2D) = "white" {} 8 | _tcol("Color",Color) = (1,0,0,1) 9 | } 10 | SubShader 11 | { 12 | Tags { "RenderType"="Transparent" "Queue"="Transparent+500" } 13 | LOD 100 14 | ZWrite Off 15 | 16 | Pass 17 | { 18 | CGPROGRAM 19 | #pragma vertex vert 20 | #pragma fragment frag 21 | #pragma multi_compile_instancing 22 | #include "UnityCG.cginc" 23 | 24 | struct appdata 25 | { 26 | float4 vertex : POSITION; 27 | UNITY_VERTEX_INPUT_INSTANCE_ID 28 | }; 29 | 30 | struct v2f 31 | { 32 | float4 vertex : SV_POSITION; 33 | }; 34 | 35 | StructuredBuffer _cbufferPosition; 36 | StructuredBuffer _cbufferParams; 37 | 38 | 39 | 40 | sampler2D _MainTex; 41 | float4 _MainTex_ST; 42 | 43 | fixed4 _tcol; 44 | 45 | 46 | StructuredBuffer _CBuffer; 47 | 48 | v2f vert (appdata v,uint instanceID : SV_InstanceID) 49 | { 50 | v2f o; 51 | float4 position = _cbufferPosition[instanceID]; 52 | float4 params = _cbufferParams[instanceID]; 53 | 54 | float3 localpos = v.vertex.xyz * float3(params.xy,1); 55 | 56 | 57 | 58 | float4 pos = float4(localpos + position.xyz,1.0); 59 | float dist = (_Time.y - params.w) * params.z; 60 | 61 | float newp = pos.y - dist; 62 | 63 | if(newp < position.w){ 64 | pos.y += 2000; 65 | } 66 | else{ 67 | pos.y -=dist; 68 | } 69 | 70 | 71 | o.vertex = mul(UNITY_MATRIX_VP,pos); 72 | 73 | 74 | return o; 75 | } 76 | 77 | fixed4 frag (v2f i) : SV_Target 78 | { 79 | 80 | return _tcol; 81 | return 1; 82 | } 83 | ENDCG 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Shader/shaderParticles.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 33a6afa316f555a45a6e85a5ae01dba5 3 | timeCreated: 1509461735 4 | licenseType: Free 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Shader/shaderParticlesRT.shader: -------------------------------------------------------------------------------- 1 | Shader "Unlit/shaderParticlesRT" 2 | { 3 | Properties 4 | { 5 | _ParticleRT ("ParticleRT", 2D) = "black" {} 6 | } 7 | SubShader 8 | { 9 | Tags { "RenderType"="Transparent" "Queue"="Transparent"} 10 | LOD 100 11 | ZWrite Off 12 | Cull Back 13 | Blend SrcAlpha OneMinusSrcAlpha 14 | 15 | Pass 16 | { 17 | CGPROGRAM 18 | #pragma vertex vert 19 | #pragma fragment frag 20 | 21 | #include "UnityCG.cginc" 22 | 23 | struct appdata 24 | { 25 | float4 vertex : POSITION; 26 | float2 uv : TEXCOORD0; 27 | }; 28 | 29 | struct v2f 30 | { 31 | float2 uv : TEXCOORD0; 32 | UNITY_FOG_COORDS(1) 33 | float4 vertex : SV_POSITION; 34 | }; 35 | 36 | sampler2D _ParticleRT; 37 | float4 _ParticleRT_ST; 38 | 39 | v2f vert (appdata v) 40 | { 41 | v2f o; 42 | o.vertex = UnityObjectToClipPos(v.vertex); 43 | o.uv = TRANSFORM_TEX(v.uv, _ParticleRT); 44 | return o; 45 | } 46 | 47 | fixed4 frag (v2f i) : SV_Target 48 | { 49 | fixed4 col = tex2D(_ParticleRT, i.uv); 50 | return col; 51 | } 52 | ENDCG 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/Shader/shaderParticlesRT.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d412abecd8c6cd64982c19bbde2cb582 3 | timeCreated: 1509461741 4 | licenseType: Free 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/scene.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/Assets/GPUInstancingParticles/scene.unity -------------------------------------------------------------------------------- /Assets/GPUInstancingParticles/scene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2110c5eccf2746441b01e2e6cfa86be5 3 | timeCreated: 1509462511 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/TestMove.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class TestMove : MonoBehaviour { 6 | 7 | // Use this for initialization 8 | void Start () { 9 | 10 | } 11 | 12 | // Update is called once per frame 13 | void Update () { 14 | transform.Translate(Mathf.Sin(Time.time*2.0f)*0.015f, Mathf.Sin(Time.time * 1.5f) * 0.01f, 0); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Assets/TestMove.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c45a2ee48ef635d4e874a40941b23ab9 3 | timeCreated: 1509466171 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/ClusterInputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2017.1.0f3 2 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/ProjectSettings/UnityConnectSettings.asset -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnityGPUParticles 2 | simple gpu instancing particles with collision calculation 3 | 4 | 5 | ![img](gpuparticle.gif) 6 | 7 | 8 | - Particles draw using `CommandBuffer.DrawMeshInstancedIndirect`. 9 | - Render to fullscreen RenderTexture for 2D sprite layering. 10 | - Collision calculation implements on compute shader 10 times per second. 11 | 12 | 13 | ## LICENSE 14 | You can use this software in a commercial game, but you cannot sell this software on the Unity Asset Store or any other platform that sells software tools for developers. -------------------------------------------------------------------------------- /gpuparticle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcyemi/UnityGPUParticles/3def11845cf660fecdfcd92ea9426ce7f1641029/gpuparticle.gif --------------------------------------------------------------------------------