├── .gitignore ├── Assets ├── Editor.meta ├── Editor │ └── CrossPlatformInput.meta ├── Main Scene.meta ├── Main Scene │ ├── AABBForParticles.cs │ ├── AABBForParticles.cs.meta │ ├── CubeMotion.cs │ ├── CubeMotion.cs.meta │ ├── MathUtil.cs │ ├── MathUtil.cs.meta │ ├── Movement.cs │ ├── Movement.cs.meta │ ├── UI.meta │ ├── UI │ │ ├── Fps.cs │ │ ├── Fps.cs.meta │ │ ├── ToggleMenuVisibility.cs │ │ ├── ToggleMenuVisibility.cs.meta │ │ ├── UpdateSliderText.cs │ │ └── UpdateSliderText.cs.meta │ ├── VolumetricParticleRenderer.cs │ └── VolumetricParticleRenderer.cs.meta ├── Materials.meta ├── Materials │ ├── Metavoxel.meta │ ├── Metavoxel │ │ ├── CompositeParticles.mat │ │ ├── CompositeParticles.mat.meta │ │ ├── FillVolume.mat │ │ ├── FillVolume.mat.meta │ │ ├── RayMarch.mat │ │ └── RayMarch.mat.meta │ ├── Sampling.meta │ ├── Sampling │ │ ├── Sample2DTexture.mat │ │ ├── Sample2DTexture.mat.meta │ │ ├── Sample3DTexture.mat │ │ └── Sample3DTexture.mat.meta │ ├── Scene.meta │ ├── Scene │ │ ├── Cubes.mat │ │ ├── Cubes.mat.meta │ │ ├── Cylinders.mat │ │ ├── Cylinders.mat.meta │ │ ├── Ground.mat │ │ ├── Ground.mat.meta │ │ ├── matGridLines.mat │ │ └── matGridLines.mat.meta │ ├── matFill2D3DTexture.mat │ └── matFill2D3DTexture.mat.meta ├── Prefabs.meta ├── Shaders.meta ├── Shaders │ ├── Metavoxel.meta │ ├── Metavoxel │ │ ├── CompositeParticles.shader │ │ ├── CompositeParticles.shader.meta │ │ ├── FillVolume.shader │ │ ├── FillVolume.shader.meta │ │ ├── GenerateLightDepthMap.shader │ │ ├── GenerateLightDepthMap.shader.meta │ │ ├── RayMarchVoxel.shader │ │ └── RayMarchVoxel.shader.meta │ ├── Sampling.meta │ ├── Sampling │ │ ├── Sample2DTexture.shader │ │ ├── Sample2DTexture.shader.meta │ │ ├── Sample3DTexture.shader │ │ └── Sample3DTexture.shader.meta │ └── UAV Write.meta ├── Standard Assets.meta ├── Standard Assets │ ├── CrossPlatformInput.meta │ ├── CrossPlatformInput │ │ ├── Scripts.meta │ │ └── Scripts │ │ │ └── PlatformSpecific.meta │ ├── ParticleSystems.meta │ ├── ParticleSystems │ │ ├── Scripts.meta │ │ └── Shaders.meta │ └── Utility.meta ├── Textures.meta ├── Textures │ ├── DisplacementTexture.cubemap │ ├── DisplacementTexture.cubemap.meta │ ├── cm_c00.png │ ├── cm_c00.png.meta │ ├── cm_c01.png │ ├── cm_c01.png.meta │ ├── cm_c02.png │ ├── cm_c02.png.meta │ ├── cm_c03.png │ ├── cm_c03.png.meta │ ├── cm_c04.png │ ├── cm_c04.png.meta │ ├── cm_c05.png │ ├── cm_c05.png.meta │ ├── explosionramp.png │ └── explosionramp.png.meta ├── UnityVS.meta ├── UnityVS │ ├── Editor.meta │ └── Editor │ │ ├── SyntaxTree.VisualStudio.Unity.Bridge.dll │ │ ├── SyntaxTree.VisualStudio.Unity.Bridge.dll.meta │ │ ├── SyntaxTree.VisualStudio.Unity.Messaging.dll │ │ ├── SyntaxTree.VisualStudio.Unity.Messaging.dll.meta │ │ ├── UnityVS.VersionSpecific.dll │ │ └── UnityVS.VersionSpecific.dll.meta ├── Volumetric_Particle_System.unity └── Volumetric_Particle_System.unity.meta ├── ProjectSettings ├── AudioManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NavMeshLayers.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset └── TimeManager.asset ├── README ├── UnityPlayer_Symbols.pdb ├── UnityVS.Sparse Volumetric Particle System.sln.DotSettings ├── UnityVS.Sparse-Volumetric-Particle-System.sln.DotSettings └── gc.log /.gitignore: -------------------------------------------------------------------------------- 1 | [Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | [Bb]uild/ 5 | exe/ 6 | **_Data 7 | 8 | # Autogenerated VS/MD solution and project files 9 | /*.csproj 10 | /*.unityproj 11 | /*.sln 12 | /*.suo 13 | /*.user 14 | /*.userprefs 15 | /*.pidb 16 | /*.booproj 17 | /*.exe 18 | 19 | #Unity3D Generated File On Crash Reports 20 | sysinfo.txt 21 | Assets/UnityVS/Editor/UnityVS.VersionSpecific.dll 22 | Assets/Main Scene/AABBForParticles.cs -------------------------------------------------------------------------------- /Assets/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c93c5e700a82bad47959bb1b0cb8951a 3 | folderAsset: yes 4 | timeCreated: 1426784462 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Editor/CrossPlatformInput.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8ffca09251a6ca749b82709b100d8393 3 | folderAsset: yes 4 | timeCreated: 1426784462 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Main Scene.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ea6e1d64914e6094b909796796c8c364 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Main Scene/AABBForParticles.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | 6 | [RequireComponent(typeof(ParticleSystem))] 7 | 8 | public class AABBForParticles : MonoBehaviour { 9 | public Bounds aabb; // box is aligned to main camera's axes 10 | private ParticleSystem ps; 11 | private ParticleSystem.Particle[] particles; 12 | // Use this for initialization 13 | void Start() 14 | { 15 | ps = gameObject.GetComponent(); 16 | particles = new ParticleSystem.Particle[ps.maxParticles]; 17 | } 18 | 19 | // Update is called once per frame 20 | void Update() 21 | { 22 | // [todo] check if any of the bodies have moved to update the aabb 23 | FindAABB(); 24 | } 25 | 26 | void FindAABB() 27 | { 28 | int numParticles = ps.GetParticles(particles); 29 | 30 | Matrix4x4 worldToCamera = Camera.main.worldToCameraMatrix; 31 | 32 | Vector3 max = new Vector3(), min = new Vector3(); 33 | bool firstTime = true; 34 | 35 | for (int ii = 0; ii < numParticles; ii++) 36 | { 37 | Vector3 pWorldPos = transform.localToWorldMatrix.MultiplyPoint3x4(particles[ii].position); 38 | 39 | // xform to camera space 40 | Vector3 csPos = worldToCamera.MultiplyPoint3x4(pWorldPos); 41 | //Debug.Log("particle " + ii + "is at " + particles[ii].position); 42 | float radius = particles[ii].size * 0.5f; 43 | Vector3 csMaxPos = csPos + new Vector3(radius, radius, -radius); // camera space looks down -Z 44 | Vector3 csMinPos = csPos - new Vector3(radius, radius, -radius); 45 | 46 | if (firstTime) 47 | { 48 | max = csMaxPos; 49 | min = csMinPos; 50 | firstTime = false; 51 | } 52 | else 53 | { 54 | max = new Vector3(Mathf.Max(csMaxPos.x, max.x), Mathf.Max(csMaxPos.y, max.y), Mathf.Min(csMaxPos.z, max.z)); 55 | min = new Vector3(Mathf.Min(csMinPos.x, min.x), Mathf.Min(csMinPos.y, min.y), Mathf.Max(csMinPos.z, min.z)); 56 | 57 | } 58 | } 59 | 60 | aabb = new Bounds((max + min) / 2.0f, 61 | max - min); 62 | } 63 | 64 | #if UNITY_EDITOR 65 | void OnDrawGizmos() 66 | { 67 | Gizmos.color = Color.red; 68 | Gizmos.matrix = Camera.main.cameraToWorldMatrix; 69 | 70 | Gizmos.DrawWireCube(aabb.center, 71 | aabb.size); 72 | 73 | Gizmos.matrix = Matrix4x4.identity; 74 | } 75 | #endif 76 | } 77 | -------------------------------------------------------------------------------- /Assets/Main Scene/AABBForParticles.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a799f4799f55c6d4ea67202bde9cb457 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Main Scene/CubeMotion.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class CubeMotion : MonoBehaviour { 5 | public float halfT = 5.0f; //seconds 6 | public float speed = 5.0f; 7 | private float timeSinceStart = 0f; 8 | // Use this for initialization 9 | void Start () { 10 | } 11 | 12 | // Update is called once per frame 13 | void Update () { 14 | timeSinceStart += Time.deltaTime; 15 | Vector3 delta = transform.right * Time.deltaTime * speed; 16 | 17 | if (timeSinceStart > halfT) 18 | { 19 | transform.position += delta; 20 | 21 | if (timeSinceStart > 2*halfT) 22 | timeSinceStart = 0f; 23 | } 24 | else 25 | { 26 | transform.position -= delta; 27 | } 28 | 29 | 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Assets/Main Scene/CubeMotion.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7ecca60d54c248e4dbaf18f357afef0b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Main Scene/MathUtil.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | public static class MathUtil { 4 | /* 5 | * Intersection test b/w an axis-aligned box and a sphere 6 | * [!! Ensure that the sphere's position is in the space as the AAB 7 | * c1, c2 -- opposite corners of the box 8 | * s -- center of the sphere 9 | * r -- radius of the sphere 10 | */ 11 | public static bool DoesBoxIntersectSphere(Vector3 c1, Vector3 c2, Vector3 s, float r) 12 | { 13 | float r2 = r * r; 14 | 15 | if (s.x < c1.x) r2 -= squared(s.x - c1.x); 16 | else if (s.x > c2.x) r2 -= squared(s.x - c2.x); 17 | 18 | if (s.y < c1.y) r2 -= squared(s.y - c1.y); 19 | else if (s.y > c2.y) r2 -= squared(s.y - c2.y); 20 | 21 | if (s.z < c1.z) r2 -= squared(s.z - c1.z); 22 | else if (s.z > c2.z) r2 -= squared(s.z - c2.z); 23 | 24 | return r2 > 0; 25 | } 26 | 27 | public static float squared(float d) { return d * d; } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Assets/Main Scene/MathUtil.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 621aa987e1b07654daf6108378c276ea 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Main Scene/Movement.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | using System.Collections; 4 | 5 | // Attach this script to the main camera to move around 6 | public class Movement : MonoBehaviour { 7 | public Light dirLight; 8 | public float lookSpeed, moveSpeed; 9 | public Text instructions, beingMovedText; 10 | 11 | private bool moveCamera, moveLight; 12 | private float camRotationX, camRotationY, lightRotationX, lightRotationY; 13 | private Vector3 startPos; private Quaternion startRot; 14 | 15 | // Use this for initialization 16 | void Start () { 17 | startPos = transform.position; 18 | startRot = transform.rotation; 19 | } 20 | 21 | // Update is called once per frame 22 | void Update () { 23 | ProcessInput(); 24 | } 25 | 26 | 27 | void ProcessInput() 28 | { 29 | if (moveCamera) 30 | { 31 | // fps'ish free cam 32 | camRotationX += Input.GetAxis("Mouse X") * lookSpeed; 33 | camRotationY += Input.GetAxis("Mouse Y") * lookSpeed; 34 | camRotationY = Mathf.Clamp(camRotationY, -90, 90); // can't do a backflip of course. 35 | 36 | // Unity's screen space coordinate convention has the origin on the bottom left 37 | // Using the camera's up and right vector can lose one degree of freedom and cause the gimbal lock! 38 | transform.localRotation = Quaternion.AngleAxis(camRotationX, Vector3.up); 39 | transform.localRotation *= Quaternion.AngleAxis(camRotationY, -Vector3.right); 40 | 41 | transform.position += transform.forward * Input.GetAxis("Vertical") * moveSpeed; 42 | transform.position += transform.right * Input.GetAxis("Horizontal") * moveSpeed; 43 | 44 | if (Input.GetKeyDown(KeyCode.Space)) 45 | { 46 | if (Input.GetKey(KeyCode.LeftShift)) 47 | { 48 | // move in -X in local camera space 49 | transform.position -= moveSpeed * transform.up; 50 | } 51 | else 52 | transform.position += moveSpeed * transform.up; 53 | } 54 | } 55 | else if (moveLight) 56 | { 57 | // fps'ish free cam 58 | lightRotationX += Input.GetAxis("Mouse X") * lookSpeed; 59 | lightRotationY += Input.GetAxis("Mouse Y") * lookSpeed; 60 | 61 | // Unity's screen space coordinate convention has the origin on the bottom left 62 | // Using the camera's up and right vector can lose one degree of freedom and cause the gimbal lock! 63 | dirLight.transform.localRotation = Quaternion.AngleAxis(lightRotationX, Vector3.up); 64 | dirLight.transform.localRotation *= Quaternion.AngleAxis(lightRotationY, -Vector3.right); 65 | } 66 | 67 | 68 | if (Input.GetKeyDown(KeyCode.R)) 69 | { 70 | transform.position = startPos; 71 | transform.rotation = startRot; 72 | camRotationX = camRotationY = 0.0f; 73 | } 74 | 75 | if (Input.GetKeyDown(KeyCode.C)) 76 | { 77 | moveCamera = !moveCamera; 78 | if (moveCamera) 79 | { 80 | moveLight = false; 81 | beingMovedText.text = "Moving camera.."; 82 | } 83 | } 84 | 85 | if (Input.GetKeyDown(KeyCode.L)) 86 | { 87 | moveLight = !moveLight; 88 | if (moveLight) 89 | { 90 | moveCamera = false; 91 | beingMovedText.text = "Moving light.."; 92 | } 93 | } 94 | 95 | if (!moveCamera && !moveLight) 96 | beingMovedText.text = ""; 97 | 98 | if (Input.GetKeyDown(KeyCode.H)) 99 | { 100 | instructions.gameObject.SetActive(!instructions.gameObject.activeSelf); 101 | } 102 | 103 | 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Assets/Main Scene/Movement.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 700fa4ff1f96a5c4b8400054cdb934b7 3 | timeCreated: 1426752213 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/Main Scene/UI.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4c522591e5dc3674e8e262a92f534ecd 3 | folderAsset: yes 4 | timeCreated: 1427103273 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Main Scene/UI/Fps.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | using System.Collections; 4 | 5 | // A simple script that updates the text field of a UI.Text element 6 | // Based on Aras's JS script in http://wiki.unity3d.com/index.php?title=FramesPerSecond 7 | // His approach accumlates fps and averages it over an interval (rather than just track number of net frames by time taken, which isn't accurate) 8 | [RequireComponent(typeof(Text))] 9 | public class Fps : MonoBehaviour 10 | { 11 | public const float updateInterval = 0.5f; // secs 12 | private float accumFps; 13 | private int framesDrawn; 14 | private float timeLeft; 15 | private Text t; 16 | 17 | // Use this for initialization 18 | void Start() 19 | { 20 | framesDrawn = 0; 21 | accumFps = 0; 22 | timeLeft = updateInterval; 23 | t = this.GetComponent(); 24 | } 25 | 26 | // Update is called once per frame 27 | void Update() 28 | { 29 | timeLeft -= Time.deltaTime; 30 | accumFps += Time.timeScale / Time.deltaTime; 31 | framesDrawn++; 32 | 33 | if (timeLeft <= 0.0f) 34 | { 35 | // calculate fps 36 | float fps = accumFps / (float) framesDrawn; 37 | 38 | t.text = "FPS: " + fps.ToString("f2"); // display two decimal digits 39 | 40 | if (fps < 10) 41 | t.color = Color.red; 42 | else if (fps < 25) 43 | t.color = Color.yellow; 44 | else 45 | t.color = Color.green; 46 | 47 | timeLeft = updateInterval; 48 | framesDrawn = 0; 49 | accumFps = 0.0f; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Assets/Main Scene/UI/Fps.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b9d2378d0e96f4e48b8167938e6b16b0 3 | timeCreated: 1427154763 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/Main Scene/UI/ToggleMenuVisibility.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class ToggleMenuVisibility : MonoBehaviour { 5 | public GameObject options; 6 | 7 | public void ToggleMenu() 8 | { 9 | if (options) 10 | { 11 | options.SetActive(!options.activeSelf); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Assets/Main Scene/UI/ToggleMenuVisibility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c4f5fe729113c934896bac7a3b5c3f0b 3 | timeCreated: 1427102705 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/Main Scene/UI/UpdateSliderText.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | using System.Collections; 4 | 5 | [RequireComponent(typeof(Slider))] 6 | public class UpdateSliderText : MonoBehaviour { 7 | public Text textValue; 8 | 9 | void Start() 10 | { 11 | UpdateText(this.GetComponent().value); 12 | } 13 | 14 | public void UpdateText(float value) 15 | { 16 | textValue.text = "(" + value.ToString("f2") + ")"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Assets/Main Scene/UI/UpdateSliderText.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 20b12dc174397d54fb763e5d16072929 3 | timeCreated: 1427103293 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/Main Scene/VolumetricParticleRenderer.cs: -------------------------------------------------------------------------------- 1 | /****************************************************** 2 | * Attach this script to the main camera in the scene 3 | ******************************************************/ 4 | 5 | using UnityEngine; 6 | #if UNITY_EDITOR 7 | using UnityEditor; 8 | #endif 9 | using System; 10 | using System.Collections; 11 | using System.Collections.Generic; 12 | using System.Runtime.InteropServices; 13 | 14 | using MetavoxelEngine; 15 | 16 | namespace MetavoxelEngine 17 | { 18 | /* 19 | * Type definitions for metavoxel & particle data 20 | */ 21 | 22 | // The world is divided into metavoxels, each of which is made up of voxels. 23 | // This metavoxel grid is oriented to face the light and each metavoxel has a list of 24 | // the particles it covers 25 | struct MetaVoxel 26 | { 27 | public Vector3 mPos; 28 | public List mParticlesCovered; 29 | public bool mCleared; 30 | } 31 | 32 | // When "filling a metavoxel" using the "Fill Volume" shader, we send per-particle-info 33 | // for use in the voxel-particle coverage test 34 | struct DisplacedParticle 35 | { 36 | public Matrix4x4 mWorldToLocal; 37 | public Vector3 mWorldPos; 38 | public float mRadius; // world units 39 | public float mOpacity; 40 | } 41 | 42 | // Helps sort metavoxels of a Z-Slice from the eye 43 | public struct MetavoxelSortData : IComparable 44 | { 45 | public int x, y; 46 | public float distance; 47 | 48 | public MetavoxelSortData(int xx, int yy, float dd) 49 | { 50 | x = xx; y = yy; distance = dd; 51 | } 52 | 53 | public void Print(int index) 54 | { 55 | Debug.Log("At index " + index + "(" + x + "," + y + ") at disance " + distance); 56 | } 57 | 58 | public int CompareTo(MetavoxelSortData other) 59 | { 60 | return this.distance.CompareTo(other.distance); 61 | } 62 | } 63 | 64 | 65 | [RequireComponent(typeof(Camera))] 66 | public class VolumetricParticleRenderer : MonoBehaviour 67 | { 68 | /* 69 | * public variables to be edited in the inspector window 70 | */ 71 | /********************* game objects/components that need to be set *************************/ 72 | public Light dirLight; 73 | public ParticleSystem particleSys; 74 | public Material matFillVolume; 75 | public Material matRayMarch; 76 | public Material matBlendParticles; // material to blend the raymarched volume with the camera's RT 77 | public Material mvLineColor; 78 | public Shader generateLightDepthMapShader; 79 | public GameObject gridCenter; 80 | 81 | /********************** metavoxel layout/size **********************************************/ 82 | public int numMetavoxelsX, numMetavoxelsY, numMetavoxelsZ; // # metavoxels in the grid along x, y & z 83 | public Vector3 mvScale;// size of a metavoxel in world units 84 | public int numVoxelsInMetavoxel; // affects the size of the 3D texture used to fill a metavoxel 85 | public int numBorderVoxels; // per end (i.e. a value of 1 means 2 voxels per dimension are border voxels) 86 | 87 | /********************** rendering vars **********************************************/ 88 | public int updateInterval; 89 | public int rayMarchSteps; 90 | public Vector3 ambientColor; 91 | public int volumeTextureAnisoLevel; 92 | 93 | /*** gui controls ****/ 94 | public float fDisplacementScale; 95 | public bool fadeOutParticles; 96 | private bool bShowMetavoxelGrid; 97 | private bool bShowRayMarchSamplesPerPixel; 98 | private bool bShowMetavoxelDrawOrder; 99 | private bool bShowRayMarchBlendFunc; 100 | public float opacityFactor; 101 | public int softParticleStepDistance; 102 | 103 | /* 104 | * private members 105 | */ 106 | // Metavoxel grid state 107 | private MetaVoxel[, ,] mvGrid; 108 | private Vector3 wsGridCenter; 109 | private Vector3 mvScaleWithBorder; 110 | 111 | // Render target resources 112 | private RenderTexture mainSceneRT; // camera draws all the objects in the scene but for the particles into this 113 | private RenderTexture particlesRT; // result of raymarching the metavoxels is stored in this 114 | private RenderTexture fillMetavoxelRT, fillMetavoxelRT1; // bind this as RT when filling a metavoxel. we don't sample/use it though.. 115 | private RenderTexture[, ,] mvFillTextures; // 3D textures that hold metavoxel fill data 116 | public RenderTexture lightPropogationUAV; // Light propogation texture used while filling metavoxels 117 | public RenderTexture lightDepthMap; 118 | 119 | // scripted camera for mini-shadow map generation 120 | private GameObject lightCamera; 121 | 122 | // misc state 123 | //private AABBForParticles pBounds; 124 | private int numParticlesEmitted; 125 | private int numMetavoxelsCovered; 126 | private Quaternion lightOrientation; // Light movement detection 127 | private Mesh cubeMesh; 128 | private Mesh quadMesh; 129 | 130 | 131 | //------------------------------- Unity callbacks ---------------------------------------- 132 | void Start() 133 | { 134 | fadeOutParticles = false; 135 | volumeTextureAnisoLevel = 1; // The value range of this variable goes from 1 to 9, where 1 equals no filtering applied and 9 equals full filtering applied 136 | lightOrientation = dirLight.transform.rotation; 137 | numMetavoxelsCovered = 0; 138 | wsGridCenter = Vector3.zero; 139 | mvScaleWithBorder = mvScale * numVoxelsInMetavoxel / (numVoxelsInMetavoxel - 2 * numBorderVoxels); 140 | 141 | CreateResources(); 142 | CreateMeshes(); 143 | InitCameraAtLight(); 144 | 145 | // [perf threat] Unity is going to do a Z-prepass simply because of the line below 146 | this.GetComponent().depthTextureMode = DepthTextureMode.Depth; // this makes the depth buffer available for all the shaders as _CameraDepthTexture 147 | 148 | //pBounds = particleSys.GetComponent(); 149 | } 150 | 151 | 152 | void Update() 153 | { 154 | } 155 | 156 | 157 | //Order of event calls in unity: file:///C:/Program%20Files%20(x86)/Unity/Editor/Data/Documentation/html/en/Manual/ExecutionOrder.html 158 | //[Render objects in scene] -> [OnRenderObject] -> [OnPostRender] -> [OnRenderImage] 159 | 160 | //OnRenderObject is called after camera has rendered the scene. 161 | //This can be used to render your own objects using Graphics.DrawMeshNow or other functions. 162 | //This function is similar to OnPostRender, except OnRenderObject is called on any object that has a script with the function; no matter if it's attached to a Camera or not. 163 | //void OnRenderObject() 164 | //{ 165 | 166 | //} 167 | 168 | void OnPreRender() 169 | { 170 | // Since we don't directly render to the back buffer, we need to clear the render targets used every frame. 171 | RenderTexture.active = particlesRT; 172 | GL.Clear(false, true, new Color(0f, 0f, 0f, 0f)); 173 | 174 | RenderTexture.active = mainSceneRT; 175 | GL.Clear(true, true, Color.black); 176 | GetComponent().targetTexture = mainSceneRT; 177 | } 178 | 179 | 180 | //// OnPostRender is called after a camera has finished rendering the scene. 181 | void OnPostRender() 182 | { 183 | // Generate the depth map from the light's pov 184 | lightCamera.GetComponent().RenderWithShader(generateLightDepthMapShader, null as string); 185 | 186 | if (Time.frameCount % updateInterval == 0) 187 | { 188 | if (dirLight.transform.rotation != lightOrientation /* light direction has changed*/ || 189 | wsGridCenter != gridCenter.transform.position) 190 | { 191 | lightOrientation = dirLight.transform.rotation; 192 | wsGridCenter = gridCenter.transform.position; 193 | UpdateMetavoxelPositions(); 194 | UpdatePositionOfCameraAtLight(); 195 | } 196 | 197 | BinParticlesToMetavoxels(); 198 | FillMetavoxels(); 199 | } 200 | 201 | // Use the camera's existing depth buffer to depth-test the particles, while 202 | // writing the ray marched volume into a separate color buffer that's blended 203 | // with the main scene in OnRenderImage(..) 204 | Graphics.SetRenderTarget(particlesRT.colorBuffer, mainSceneRT.depthBuffer); 205 | 206 | // fill particlesRT with the ray marched volume (the loop is per directional light source) 207 | RenderMetavoxels(); 208 | 209 | // blend the particles onto the main (opaque) scene. [todo] what happens to billboarded particles on the main scene? when're they rendered? 210 | Graphics.Blit(particlesRT, mainSceneRT, matBlendParticles); 211 | 212 | if (bShowMetavoxelGrid) 213 | { 214 | DrawMetavoxelGrid(); 215 | } 216 | 217 | // need to set the targetTexture to null, else the Blit doesn't work 218 | GetComponent().targetTexture = null; 219 | Graphics.Blit(mainSceneRT, null as RenderTexture); // copy to back buffer 220 | } 221 | 222 | 223 | //------------------------------- private fns -------------------------------------------- 224 | void CreateResources() 225 | { 226 | if (!particlesRT) 227 | { 228 | particlesRT = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.ARGB32); 229 | particlesRT.useMipMap = false; 230 | particlesRT.isVolume = false; 231 | particlesRT.enableRandomWrite = false; 232 | particlesRT.Create(); 233 | } 234 | 235 | if (!mainSceneRT) 236 | { 237 | mainSceneRT = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGB32); 238 | mainSceneRT.useMipMap = false; 239 | mainSceneRT.isVolume = false; 240 | mainSceneRT.enableRandomWrite = false; 241 | mainSceneRT.Create(); 242 | GetComponent().targetTexture = mainSceneRT; 243 | } 244 | 245 | if (!fillMetavoxelRT) 246 | { 247 | fillMetavoxelRT = new RenderTexture(numVoxelsInMetavoxel, numVoxelsInMetavoxel, 0, RenderTextureFormat.R8); 248 | fillMetavoxelRT.useMipMap = false; 249 | fillMetavoxelRT.isVolume = false; 250 | fillMetavoxelRT.enableRandomWrite = false; 251 | fillMetavoxelRT.Create(); 252 | } 253 | 254 | if (!fillMetavoxelRT1) 255 | { 256 | fillMetavoxelRT1 = new RenderTexture(numVoxelsInMetavoxel, numVoxelsInMetavoxel, 0, RenderTextureFormat.R8); 257 | fillMetavoxelRT1.useMipMap = false; 258 | fillMetavoxelRT1.isVolume = false; 259 | fillMetavoxelRT1.enableRandomWrite = false; 260 | fillMetavoxelRT1.Create(); 261 | } 262 | 263 | 264 | if (!lightPropogationUAV) 265 | { 266 | lightPropogationUAV = new RenderTexture(numMetavoxelsX * numVoxelsInMetavoxel, numMetavoxelsY * numVoxelsInMetavoxel, 0 /* no need depth surface, just color*/, RenderTextureFormat.RFloat); 267 | lightPropogationUAV.generateMips = false; 268 | lightPropogationUAV.enableRandomWrite = true; // use as UAV 269 | lightPropogationUAV.Create(); 270 | } 271 | 272 | if (!lightDepthMap) 273 | { 274 | lightDepthMap = new RenderTexture(numMetavoxelsX * numVoxelsInMetavoxel, numMetavoxelsY * numVoxelsInMetavoxel, 24, RenderTextureFormat.Depth); 275 | lightDepthMap.generateMips = false; 276 | lightDepthMap.enableRandomWrite = false; 277 | lightDepthMap.Create(); 278 | } 279 | 280 | CreateMetavoxelGrid(); // creates the fill texture per metavoxel 281 | } 282 | 283 | 284 | // Create mv info & associated fill texture for every mv in the grid 285 | void CreateMetavoxelGrid() 286 | { 287 | mvGrid = new MetaVoxel[numMetavoxelsZ, numMetavoxelsY, numMetavoxelsX]; // note index order -- prefer locality in X,Y 288 | mvFillTextures = new RenderTexture[numMetavoxelsZ, numMetavoxelsY, numMetavoxelsX]; 289 | 290 | // Init fill texture and particle list per metavoxel 291 | for (int zz = 0; zz < numMetavoxelsZ; zz++) 292 | { 293 | for (int yy = 0; yy < numMetavoxelsY; yy++) 294 | { 295 | for (int xx = 0; xx < numMetavoxelsX; xx++) 296 | { 297 | mvGrid[zz, yy, xx].mParticlesCovered = new List(); 298 | CreateFillTexture(xx, yy, zz); 299 | } 300 | } 301 | } 302 | 303 | // Find metavoxel position & orientation 304 | UpdateMetavoxelPositions(); 305 | } 306 | 307 | 308 | void CreateFillTexture(int xx, int yy, int zz) 309 | { 310 | // Note that constructing a RenderTexture object does not create the hardware representation immediately. The actual render texture is created upon first use or when Create is called manually 311 | // file:///C:/Program%20Files%20(x86)/Unity/Editor/Data/Documentation/html/en/ScriptReference/RenderTexture-ctor.html 312 | mvFillTextures[zz, yy, xx] = new RenderTexture(numVoxelsInMetavoxel, numVoxelsInMetavoxel, 0 /* no need depth surface, just color*/, RenderTextureFormat.ARGBHalf); 313 | mvFillTextures[zz, yy, xx].isVolume = true; 314 | mvFillTextures[zz, yy, xx].volumeDepth = numVoxelsInMetavoxel; 315 | mvFillTextures[zz, yy, xx].generateMips = false; 316 | mvFillTextures[zz, yy, xx].enableRandomWrite = true; // use as UAV 317 | } 318 | 319 | 320 | void InitCameraAtLight() 321 | { 322 | lightCamera = new GameObject(); 323 | lightCamera.name = "LightCamera"; 324 | lightCamera.transform.parent = dirLight.transform; 325 | // make the shadow map camera look at the center of the metavoxel grid 326 | UpdatePositionOfCameraAtLight(); 327 | 328 | lightCamera.gameObject.SetActive(false); 329 | 330 | Camera c = lightCamera.AddComponent() as Camera; 331 | if (c != null) 332 | { 333 | c.orthographic = true; 334 | 335 | // Set the camera extents to that of the metavoxel grid (vertically.. horizontal part is taken care of by aspect ratio) 336 | // setting ortho size below wont work, since l,r are t,b scaled by aspect ratio. we need a tight fit to the metavoxel grid 337 | // so we need to explicitly generate the projection matrix as we need it 338 | //c.orthographicSize = numMetavoxelsY * mvScale.y * 0.5f; // Camera's half-vertical-size when in orthographic mode. 339 | 340 | float r = numMetavoxelsX * mvScale.x * 0.5f, t = numMetavoxelsY * mvScale.y * 0.5f; 341 | 342 | Matrix4x4 orthoProjectionMatrix = Matrix4x4.Ortho(-r, r, -t, t, 0.3f, 1000f); 343 | c.projectionMatrix = orthoProjectionMatrix; // todo: is this pixel correct? check http://docs.unity3d.com/ScriptReference/GL.LoadPixelMatrix.html 344 | 345 | c.targetTexture = lightDepthMap; 346 | c.cullingMask = 1 << LayerMask.NameToLayer("Default"); 347 | c.clearFlags = CameraClearFlags.Depth | CameraClearFlags.Color; 348 | c.useOcclusionCulling = false; 349 | } 350 | else 351 | { 352 | Debug.LogError("Could not create camera at light"); 353 | } 354 | // Setting the ortho projection matrix as below doesn't give the expected matrix 355 | //c.projectionMatrix = Matrix4x4.Ortho(-wsMetavoxelDimensions.x, wsMetavoxelDimensions.x, 356 | // -wsMetavoxelDimensions.y, wsMetavoxelDimensions.y, 357 | // 0.3f, 1000); 358 | } 359 | 360 | 361 | void UpdatePositionOfCameraAtLight() 362 | { 363 | // ideally we want to set the near plane based on the bounding box of the scene. 364 | // for now, keep it at 200 units from the metavoxel center 365 | lightCamera.transform.position = wsGridCenter - dirLight.transform.forward * 200f; 366 | lightCamera.transform.localRotation = Quaternion.identity; 367 | } 368 | 369 | 370 | void UpdateMetavoxelPositions() 371 | { 372 | /* assumptions: 373 | i) grid is centered at the world origin 374 | * ii) effort isn't made to ensure the grid covers the frustum visible from the camera. 375 | * 376 | * the grid layout follows the light (xx=0,yy=0,zz=0) is the left-bottom-front of the grid. that takes care of the position of each metavoxel in the grid. 377 | * the orientation of each metavoxel however faces the light (X and Z are reversed). this is just confusing. please fix [todo] 378 | */ 379 | 380 | Vector3 lsWorldOrigin = dirLight.transform.worldToLocalMatrix.MultiplyPoint3x4(wsGridCenter); // xform origin to light space 381 | 382 | for (int zz = 0; zz < numMetavoxelsZ; zz++) 383 | { 384 | for (int yy = 0; yy < numMetavoxelsY; yy++) 385 | { 386 | for (int xx = 0; xx < numMetavoxelsX; xx++) 387 | { 388 | Vector3 lsOffset = Vector3.Scale(new Vector3(numMetavoxelsX / 2 - xx, numMetavoxelsY / 2 - yy, numMetavoxelsZ / 2 - zz), mvScale); 389 | Vector3 wsMetavoxelPos = dirLight.transform.localToWorldMatrix.MultiplyPoint3x4(lsWorldOrigin - lsOffset); // using - lsOffset means that zz = 0 is closer to the light 390 | mvGrid[zz, yy, xx].mPos = wsMetavoxelPos; 391 | } 392 | } 393 | } 394 | } 395 | 396 | 397 | void BinParticlesToMetavoxels() 398 | { 399 | // Clear previous particle lists 400 | for (int zz = 0; zz < numMetavoxelsZ; zz++) 401 | { 402 | for (int yy = 0; yy < numMetavoxelsY; yy++) 403 | { 404 | for (int xx = 0; xx < numMetavoxelsX; xx++) 405 | { 406 | mvGrid[zz, yy, xx].mParticlesCovered.Clear(); 407 | } 408 | } 409 | } 410 | 411 | 412 | ParticleSystem.Particle[] parts = new ParticleSystem.Particle[particleSys.maxParticles]; 413 | numParticlesEmitted = particleSys.GetParticles(parts); 414 | 415 | for (int pp = 0; pp < numParticlesEmitted; pp++) 416 | { 417 | // xform particle to mv space to make it a sphere-aabb intersection test 418 | Vector3 wsParticlePos = particleSys.transform.localToWorldMatrix.MultiplyPoint3x4(parts[pp].position); 419 | Vector3 lsParticlePos = dirLight.transform.worldToLocalMatrix.MultiplyPoint3x4(wsParticlePos); 420 | Vector3 lsMVGridCenter = dirLight.transform.worldToLocalMatrix.MultiplyPoint3x4(wsGridCenter); 421 | 422 | Vector3 pIndexOffset = (lsParticlePos - lsMVGridCenter) / mvScale.x; 423 | Vector3 pIndex = pIndexOffset + new Vector3(numMetavoxelsX, numMetavoxelsY, numMetavoxelsZ) * 0.5f; 424 | 425 | int pExtents = Mathf.RoundToInt( (parts[pp].size / 2f) / mvScale.x ); 426 | Vector3 minIndex = pIndex - Vector3.one * pExtents, 427 | maxIndex = pIndex + Vector3.one * pExtents; 428 | 429 | Vector3 mvGridIndexLimit = new Vector3(numMetavoxelsX - 1, numMetavoxelsY - 1, numMetavoxelsZ - 1); 430 | 431 | minIndex = Vector3.Max(Vector3.zero, minIndex); 432 | maxIndex = Vector3.Min(mvGridIndexLimit, maxIndex); 433 | 434 | for (int zz = (int)minIndex.z; zz <= (int)maxIndex.z; zz++) 435 | { 436 | for (int yy = (int)minIndex.y; yy <= (int)maxIndex.y; yy++) 437 | { 438 | for (int xx = (int)minIndex.x; xx <= (int)maxIndex.x; xx++) 439 | { 440 | Matrix4x4 worldToMetavoxelMatrix = Matrix4x4.TRS(mvGrid[zz, yy, xx].mPos, 441 | lightOrientation, 442 | mvScaleWithBorder).inverse; // Account for the border of the metavoxel while binning 443 | 444 | Vector3 mvParticlePos = worldToMetavoxelMatrix.MultiplyPoint3x4(wsParticlePos); 445 | float mvParticleRadius = (parts[pp].size / 2f) / mvScaleWithBorder.x; // Intersection test is with the enlarged metavoxel (i.e. with the border), so 446 | 447 | bool particle_intersects_metavoxel = MathUtil.DoesBoxIntersectSphere(new Vector3(-0.5f, -0.5f, -0.5f), 448 | new Vector3(0.5f, 0.5f, 0.5f), 449 | mvParticlePos, 450 | mvParticleRadius); 451 | 452 | if (particle_intersects_metavoxel) 453 | mvGrid[zz, yy, xx].mParticlesCovered.Add(parts[pp]); 454 | } 455 | } 456 | } 457 | } // pp 458 | 459 | 460 | 461 | //for (int zz = 0; zz < numMetavoxelsZ; zz++) 462 | //{ 463 | // for (int yy = 0; yy < numMetavoxelsY; yy++) 464 | // { 465 | // for (int xx = 0; xx < numMetavoxelsX; xx++) 466 | // { 467 | // mvGrid[zz, yy, xx].mParticlesCovered.Clear(); 468 | 469 | // Matrix4x4 worldToMetavoxelMatrix = Matrix4x4.TRS(mvGrid[zz, yy, xx].mPos, 470 | // lightOrientation, 471 | // mvScaleWithBorder).inverse; // Account for the border of the metavoxel while scaling 472 | 473 | // for (int pp = 0; pp < numParticlesEmitted; pp++) 474 | // { 475 | // // xform particle to mv space to make it a sphere-aabb intersection test 476 | // Vector3 wsParticlePos = particleSys.transform.localToWorldMatrix.MultiplyPoint3x4(parts[pp].position); 477 | // Vector3 mvParticlePos = worldToMetavoxelMatrix.MultiplyPoint3x4(wsParticlePos); 478 | // float radius = (parts[pp].size / 2f) / mvScaleWithBorder.x; 479 | 480 | // bool particle_intersects_metavoxel = MathUtil.DoesBoxIntersectSphere(new Vector3(-0.5f, -0.5f, -0.5f), 481 | // new Vector3(0.5f, 0.5f, 0.5f), 482 | // mvParticlePos, 483 | // radius); 484 | 485 | // if (particle_intersects_metavoxel) 486 | // mvGrid[zz, yy, xx].mParticlesCovered.Add(parts[pp]); 487 | // } // pp 488 | 489 | // } // xx 490 | // } // yy 491 | //} // zz 492 | } 493 | 494 | 495 | void FillMetavoxels() 496 | { 497 | // Clear the light propogation texture before we write to it 498 | Graphics.SetRenderTarget(lightPropogationUAV); 499 | GL.Clear(false, true, Color.red); 500 | 501 | SetFillPassConstants(); 502 | numMetavoxelsCovered = 0; 503 | 504 | // process the metavoxels in order of Z-slice closest to light to farthest 505 | for (int zz = 0; zz < numMetavoxelsZ; zz++) 506 | { 507 | for (int yy = 0; yy < numMetavoxelsY; yy++) 508 | { 509 | for (int xx = 0; xx < numMetavoxelsX; xx++) 510 | { 511 | if (mvGrid[zz, yy, xx].mParticlesCovered.Count != 0) 512 | { 513 | FillMetavoxel(xx, yy, zz); 514 | numMetavoxelsCovered++; 515 | } 516 | } 517 | } 518 | } 519 | 520 | } 521 | 522 | 523 | void SetFillPassConstants() 524 | { 525 | // metavoxel specific stuff 526 | matFillVolume.SetVector("_MetavoxelGridDim", new Vector3(numMetavoxelsX, numMetavoxelsY, numMetavoxelsZ)); 527 | matFillVolume.SetFloat("_NumVoxels", numVoxelsInMetavoxel); 528 | matFillVolume.SetInt("_MetavoxelBorderSize", Mathf.Clamp(numBorderVoxels, 0, numVoxelsInMetavoxel - 2)); 529 | matFillVolume.SetFloat("_MetavoxelScaleZ", mvScaleWithBorder.z); 530 | 531 | // scene related stuff 532 | // -- light 533 | matFillVolume.SetTexture("_LightDepthMap", lightDepthMap); 534 | matFillVolume.SetMatrix("_WorldToLight", lightCamera.transform.worldToLocalMatrix); 535 | matFillVolume.SetVector("_LightForward", dirLight.transform.forward.normalized); 536 | matFillVolume.SetVector("_LightColor", dirLight.color); 537 | matFillVolume.SetVector("_AmbientColor", ambientColor); 538 | matFillVolume.SetFloat("_InitLightIntensity", 1.0f); 539 | matFillVolume.SetFloat("_NearZ", lightCamera.GetComponent().nearClipPlane); 540 | matFillVolume.SetFloat("_FarZ", lightCamera.GetComponent().farClipPlane); 541 | 542 | Camera c = lightCamera.GetComponent(); 543 | matFillVolume.SetMatrix("_LightProjection", c.projectionMatrix); 544 | 545 | // -- particles 546 | matFillVolume.SetFloat("_OpacityFactor", opacityFactor); 547 | matFillVolume.SetFloat("_DisplacementScale", fDisplacementScale); 548 | 549 | int fadeParticles = 0; 550 | if (fadeOutParticles) 551 | fadeParticles = 1; 552 | 553 | matFillVolume.SetInt("_FadeOutParticles", fadeParticles); 554 | } 555 | 556 | 557 | // Each metavoxel that has particles in it needs to be filled with volume info (opacity for now) 558 | // Since nothing is rendered to the screen while filling the metavoxel volume textures up, we have to resort to 559 | void FillMetavoxel(int xx, int yy, int zz) 560 | { 561 | //Graphics.ClearRandomWriteTargets(); 562 | 563 | // Note: Calling Create lets you create it up front. Create does nothing if the texture is already created. 564 | // file:///C:/Program%20Files%20(x86)/Unity/Editor/Data/Documentation/html/en/ScriptReference/RenderTexture.Create.html 565 | if (!mvFillTextures[zz, yy, xx].IsCreated()) 566 | mvFillTextures[zz, yy, xx].Create(); 567 | 568 | // don't need to clear the mv fill texture since we write to every pixel on it (on every depth slice) 569 | // regardless of whether that pixel is covered or not. 570 | Graphics.SetRenderTarget(fillMetavoxelRT); 571 | Graphics.SetRandomWriteTarget(1, mvFillTextures[zz, yy, xx]); 572 | Graphics.SetRandomWriteTarget(2, lightPropogationUAV); 573 | 574 | // fill structured buffer 575 | int numParticles = mvGrid[zz, yy, xx].mParticlesCovered.Count; 576 | DisplacedParticle[] dpArray = new DisplacedParticle[numParticles]; 577 | 578 | int index = 0; 579 | 580 | foreach (ParticleSystem.Particle p in mvGrid[zz, yy, xx].mParticlesCovered) 581 | { 582 | Vector3 wsPos = particleSys.transform.localToWorldMatrix.MultiplyPoint3x4(p.position); 583 | dpArray[index].mWorldToLocal = Matrix4x4.TRS(wsPos, Quaternion.AngleAxis(p.rotation, particleSys.transform.forward), new Vector3(p.size, p.size, p.size)).inverse; 584 | dpArray[index].mWorldPos = wsPos; 585 | dpArray[index].mRadius = p.size / 2f; 586 | dpArray[index].mOpacity = p.lifetime / p.startLifetime; // [time-particle-will-remain-alive / particle-lifetime] use this to make particles less "dense" as they meet their end. 587 | index++; 588 | } 589 | 590 | ComputeBuffer dpBuffer = new ComputeBuffer(numParticles, 591 | Marshal.SizeOf(dpArray[0])); 592 | dpBuffer.SetData(dpArray); 593 | 594 | // Set material state 595 | 596 | matFillVolume.SetMatrix("_MetavoxelToWorld", Matrix4x4.TRS(mvGrid[zz, yy, xx].mPos, 597 | lightOrientation, 598 | mvScaleWithBorder)); // need to fill the border voxels of this metavoxel too (so we need to make it "seem" bigger) 599 | matFillVolume.SetVector("_MetavoxelIndex", new Vector3(xx, yy, zz)); 600 | matFillVolume.SetInt("_NumParticles", numParticles); 601 | matFillVolume.SetBuffer("_Particles", dpBuffer); 602 | //matFillVolume.SetPass(0); 603 | 604 | Graphics.Blit(fillMetavoxelRT1, fillMetavoxelRT1, matFillVolume, 0); 605 | //Graphics.DrawMeshNow(quadMesh, Vector3.zero, Quaternion.identity); 606 | // cleanup 607 | dpBuffer.Release(); 608 | Graphics.ClearRandomWriteTargets(); 609 | } 610 | 611 | 612 | // The ray march step uses alpha blending and imposes order requirements 613 | List SortMetavoxelSlicesFarToNearFromEye() 614 | { 615 | List mvPerSliceFarToNear = new List(); 616 | Vector3 cameraPos = Camera.main.transform.position; 617 | 618 | for (int yy = 0; yy < numMetavoxelsY; yy++) 619 | { 620 | for (int xx = 0; xx < numMetavoxelsX; xx++) 621 | { 622 | Vector3 distFromEye = mvGrid[0, yy, xx].mPos - cameraPos; 623 | //Debug.Log("Distance from mv " + xx + ", " + yy + "to camera is " + Vector3.Dot(distFromEye, distFromEye)); 624 | mvPerSliceFarToNear.Add(new MetavoxelSortData(xx, yy, Vector3.Dot(distFromEye, distFromEye))); 625 | } 626 | } 627 | 628 | mvPerSliceFarToNear.Sort(); 629 | mvPerSliceFarToNear.Reverse(); 630 | 631 | return mvPerSliceFarToNear; 632 | } 633 | 634 | 635 | // Submit a cube from the perspective of the main camera 636 | // This function is called from CameraScript.cs 637 | public void RenderMetavoxels() 638 | { 639 | List mvPerSliceFarToNear = SortMetavoxelSlicesFarToNearFromEye(); 640 | SetRaymarchPassConstants(); 641 | 642 | Vector3 lsCameraPos = dirLight.transform.worldToLocalMatrix.MultiplyPoint3x4(Camera.main.transform.position); 643 | float lsFirstZSlice = dirLight.transform.worldToLocalMatrix.MultiplyPoint3x4(mvGrid[0, 0, 0].mPos).z; 644 | float mvBlendOverIndex = (lsCameraPos.z - lsFirstZSlice) / mvScale.z; 645 | 646 | //float x = -0.6f; 647 | //Debug.Log("X: " + x + " Rounding x: " + Mathf.RoundToInt(x) + "Ceil(x): " + Mathf.Ceil(x) + " Floor(x): " + Mathf.Floor(x)); 648 | int zBoundary = Mathf.Clamp( Mathf.RoundToInt(mvBlendOverIndex), -1, numMetavoxelsZ - 1); 649 | 650 | int mvCount = 0; 651 | 652 | if (zBoundary >= 0) 653 | { 654 | // Render metavoxel slices with back to front blending 655 | // (a) increasing order along the direction of the light 656 | // (b) farthest-to-nearest from the camera per slice 657 | 658 | // Blend One OneMinusSrcAlpha, One OneMinusSrcAlpha // Back to Front blending (blend over) 659 | matRayMarch.SetInt("SrcFactor", (int)UnityEngine.Rendering.BlendMode.One); 660 | matRayMarch.SetInt("DstFactor", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); 661 | matRayMarch.SetInt("SrcFactorA", (int)UnityEngine.Rendering.BlendMode.One); 662 | matRayMarch.SetInt("DstFactorA", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); 663 | 664 | matRayMarch.SetInt("_RayMarchBlendOver", 1); 665 | 666 | 667 | for (int zz = 0; zz <= zBoundary; zz++) 668 | { 669 | foreach (MetavoxelSortData vv in mvPerSliceFarToNear) 670 | { 671 | //Debug.Log("F2N " + mvCount + "(" + vv.x + "," + vv.y + ")"); 672 | int xx = (int)vv.x, yy = (int)vv.y; 673 | 674 | if (mvGrid[zz, yy, xx].mParticlesCovered.Count != 0) 675 | { 676 | RenderMetavoxel(xx, yy, zz, mvCount++); 677 | } 678 | 679 | } 680 | } 681 | } 682 | 683 | // Render metavoxel slices 684 | // (a) increasing order along the direction of the light 685 | // (b) nearest-to-farthest from the camera per slice 686 | 687 | // Blend OneMinusDstAlpha One, OneMinusDstAlpha One // Front to Back blending (blend under) 688 | matRayMarch.SetInt("SrcFactor", (int)UnityEngine.Rendering.BlendMode.OneMinusDstAlpha); 689 | matRayMarch.SetInt("DstFactor", (int)UnityEngine.Rendering.BlendMode.One); 690 | matRayMarch.SetInt("SrcFactorA", (int)UnityEngine.Rendering.BlendMode.OneMinusDstAlpha); 691 | matRayMarch.SetInt("DstFactorA", (int)UnityEngine.Rendering.BlendMode.One); 692 | 693 | matRayMarch.SetInt("_RayMarchBlendOver", 0); 694 | 695 | mvPerSliceFarToNear.Reverse(); // make it nearest-to-farthest 696 | 697 | for (int zz = zBoundary + 1; zz < numMetavoxelsZ; zz++) 698 | { 699 | foreach (MetavoxelSortData vv in mvPerSliceFarToNear) 700 | { 701 | //Vector3 cam2mv = Camera.main.transform.position - mvGrid[zz, vv.y, vv.x].mPos; 702 | int xx = (int)vv.x, yy = (int)vv.y; 703 | 704 | if (mvGrid[zz, yy, xx].mParticlesCovered.Count != 0) 705 | { 706 | //matRayMarchUnder.renderQueue = 5000 + mvCount; 707 | //Debug.Log("N2F" + mvCount + "(" + vv.x + "," + vv.y + "," + zz + ") at dist " + cam2mv.sqrMagnitude); 708 | RenderMetavoxel(xx, yy, zz, mvCount++); 709 | } 710 | } 711 | } 712 | 713 | } 714 | 715 | 716 | void SetRaymarchPassConstants() 717 | { 718 | // Resources 719 | matRayMarch.SetTexture("_LightPropogationTexture", lightPropogationUAV); 720 | 721 | // Metavoxel grid uniforms 722 | matRayMarch.SetFloat("_NumVoxels", numVoxelsInMetavoxel); 723 | matRayMarch.SetVector("_MetavoxelSize", mvScale); 724 | matRayMarch.SetVector("_MetavoxelGridDim", new Vector3(numMetavoxelsX, numMetavoxelsY, numMetavoxelsZ)); 725 | matRayMarch.SetVector("_MetavoxelGridCenter", wsGridCenter); 726 | matRayMarch.SetInt("_MetavoxelBorderSize", numBorderVoxels); 727 | 728 | // Camera uniforms 729 | //matRayMarch.SetVector("_CameraWorldPos", Camera.main.transform.position); 730 | // Unity sets the _CameraToWorld and _WorldToCamera constant buffers by default - but these would be on the metavoxel camera 731 | // that's attached to the directional light. We're interested in the main camera's matrices, not the pseudo-mv cam! 732 | //matRayMarch.SetMatrix("_CameraToWorldMatrix", Camera.main.cameraToWorldMatrix); 733 | matRayMarch.SetMatrix("_WorldToCameraMatrix", Camera.main.worldToCameraMatrix); 734 | matRayMarch.SetFloat("_Fov", Mathf.Deg2Rad * Camera.main.fieldOfView); 735 | //matRayMarch.SetFloat("_Near", Camera.main.nearClipPlane); 736 | //matRayMarch.SetFloat("_Far", Camera.main.farClipPlane); 737 | matRayMarch.SetVector("_ScreenRes", new Vector2(Screen.width, Screen.height)); 738 | 739 | // Ray march uniforms 740 | matRayMarch.SetInt("_NumRaymarchStepsPerMV", rayMarchSteps); 741 | //m.SetVector("_AABBMin", pBounds.aabb.min); 742 | //m.SetVector("_AABBMax", pBounds.aabb.max); 743 | 744 | int showNumSamples_i = 0; 745 | if (bShowRayMarchSamplesPerPixel) 746 | showNumSamples_i = 1; 747 | 748 | matRayMarch.SetInt("_ShowNumSamples", showNumSamples_i); 749 | 750 | int showMetavoxelDrawOrder_i = 0; 751 | if (bShowMetavoxelDrawOrder) 752 | showMetavoxelDrawOrder_i = 1; 753 | 754 | matRayMarch.SetInt("_ShowMetavoxelDrawOrder", showMetavoxelDrawOrder_i); 755 | matRayMarch.SetInt("_NumMetavoxelsCovered", numMetavoxelsCovered); 756 | 757 | int showRayMarchBlendFunc_i = 0; 758 | if (bShowRayMarchBlendFunc) 759 | showRayMarchBlendFunc_i = 1; 760 | 761 | matRayMarch.SetInt("_ShowRayMarchBlendFunc", showRayMarchBlendFunc_i); 762 | matRayMarch.SetInt("_SoftDistance", softParticleStepDistance); 763 | } 764 | 765 | 766 | void RenderMetavoxel(int xx, int yy, int zz, int orderIndex) 767 | { 768 | //Debug.Log("rendering mv " + xx + "," + yy +"," + zz); 769 | mvFillTextures[zz, yy, xx].filterMode = FilterMode.Bilinear; 770 | mvFillTextures[zz, yy, xx].wrapMode = TextureWrapMode.Repeat; 771 | mvFillTextures[zz, yy, xx].anisoLevel = volumeTextureAnisoLevel; 772 | 773 | matRayMarch.SetTexture("_VolumeTexture", mvFillTextures[zz, yy, xx]); 774 | Matrix4x4 mvToWorld = Matrix4x4.TRS(mvGrid[zz, yy, xx].mPos, 775 | lightOrientation, 776 | mvScale); // border should NOT be included here. we want to rasterize only the pixels covered by the metavoxel 777 | matRayMarch.SetMatrix("_MetavoxelToWorld", mvToWorld); 778 | matRayMarch.SetMatrix("_CameraToMetavoxel", mvToWorld.inverse * Camera.main.cameraToWorldMatrix); 779 | //matRayMarch.SetMatrix("_WorldToMetavoxel", mvToWorld.inverse); 780 | matRayMarch.SetVector("_MetavoxelIndex", new Vector3(xx, yy, zz)); 781 | matRayMarch.SetFloat("_ParticleCoverageRatio", mvGrid[zz, yy, xx].mParticlesCovered.Count / (float)numParticlesEmitted); 782 | matRayMarch.SetInt("_OrderIndex", orderIndex); 783 | 784 | 785 | // Absence of the line below caused several hours of debugging madness. 786 | // SetPass needs to be called AFTER all material properties are set prior to every DrawMeshNow call. 787 | bool setPass = matRayMarch.SetPass(0); 788 | if (!setPass) 789 | { 790 | Debug.LogError("material set pass returned false;.."); 791 | } 792 | 793 | Graphics.DrawMeshNow(cubeMesh, Vector3.zero, Quaternion.identity); 794 | } 795 | 796 | 797 | void CreateMeshes() 798 | { 799 | CreateCubeMesh(); 800 | CreateQuadMesh(); 801 | } 802 | 803 | 804 | void CreateCubeMesh() 805 | { 806 | cubeMesh = new Mesh(); 807 | 808 | float length = 1f; 809 | float width = 1f; 810 | float height = 1f; 811 | 812 | #region Vertices 813 | Vector3 p0 = new Vector3(-length * .5f, -width * .5f, height * .5f); 814 | Vector3 p1 = new Vector3(length * .5f, -width * .5f, height * .5f); 815 | Vector3 p2 = new Vector3(length * .5f, -width * .5f, -height * .5f); 816 | Vector3 p3 = new Vector3(-length * .5f, -width * .5f, -height * .5f); 817 | 818 | Vector3 p4 = new Vector3(-length * .5f, width * .5f, height * .5f); 819 | Vector3 p5 = new Vector3(length * .5f, width * .5f, height * .5f); 820 | Vector3 p6 = new Vector3(length * .5f, width * .5f, -height * .5f); 821 | Vector3 p7 = new Vector3(-length * .5f, width * .5f, -height * .5f); 822 | 823 | Vector3[] vertices = new Vector3[] 824 | { 825 | // Bottom 826 | p0, p1, p2, p3, 827 | 828 | // Left 829 | p7, p4, p0, p3, 830 | 831 | // Front 832 | p4, p5, p1, p0, 833 | 834 | // Back 835 | p6, p7, p3, p2, 836 | 837 | // Right 838 | p5, p6, p2, p1, 839 | 840 | // Top 841 | p7, p6, p5, p4 842 | }; 843 | #endregion 844 | 845 | #region Normales 846 | Vector3 up = Vector3.up; 847 | Vector3 down = Vector3.down; 848 | Vector3 front = Vector3.forward; 849 | Vector3 back = Vector3.back; 850 | Vector3 left = Vector3.left; 851 | Vector3 right = Vector3.right; 852 | 853 | Vector3[] normales = new Vector3[] 854 | { 855 | // Bottom 856 | down, down, down, down, 857 | 858 | // Left 859 | left, left, left, left, 860 | 861 | // Front 862 | front, front, front, front, 863 | 864 | // Back 865 | back, back, back, back, 866 | 867 | // Right 868 | right, right, right, right, 869 | 870 | // Top 871 | up, up, up, up 872 | }; 873 | #endregion 874 | 875 | #region UVs 876 | Vector2 _00 = new Vector2(0f, 0f); 877 | Vector2 _10 = new Vector2(1f, 0f); 878 | Vector2 _01 = new Vector2(0f, 1f); 879 | Vector2 _11 = new Vector2(1f, 1f); 880 | 881 | Vector2[] uvs = new Vector2[] 882 | { 883 | // Bottom 884 | _11, _01, _00, _10, 885 | 886 | // Left 887 | _11, _01, _00, _10, 888 | 889 | // Front 890 | _11, _01, _00, _10, 891 | 892 | // Back 893 | _11, _01, _00, _10, 894 | 895 | // Right 896 | _11, _01, _00, _10, 897 | 898 | // Top 899 | _11, _01, _00, _10, 900 | }; 901 | #endregion 902 | 903 | #region Triangles 904 | int[] triangles = new int[] 905 | { 906 | // Bottom 907 | 3, 1, 0, 908 | 3, 2, 1, 909 | 910 | // Left 911 | 3 + 4 * 1, 1 + 4 * 1, 0 + 4 * 1, 912 | 3 + 4 * 1, 2 + 4 * 1, 1 + 4 * 1, 913 | 914 | // Front 915 | 3 + 4 * 2, 1 + 4 * 2, 0 + 4 * 2, 916 | 3 + 4 * 2, 2 + 4 * 2, 1 + 4 * 2, 917 | 918 | // Back 919 | 3 + 4 * 3, 1 + 4 * 3, 0 + 4 * 3, 920 | 3 + 4 * 3, 2 + 4 * 3, 1 + 4 * 3, 921 | 922 | // Right 923 | 3 + 4 * 4, 1 + 4 * 4, 0 + 4 * 4, 924 | 3 + 4 * 4, 2 + 4 * 4, 1 + 4 * 4, 925 | 926 | // Top 927 | 3 + 4 * 5, 1 + 4 * 5, 0 + 4 * 5, 928 | 3 + 4 * 5, 2 + 4 * 5, 1 + 4 * 5, 929 | 930 | }; 931 | #endregion 932 | 933 | cubeMesh.vertices = vertices; 934 | cubeMesh.normals = normales; 935 | cubeMesh.uv = uvs; 936 | cubeMesh.triangles = triangles; 937 | 938 | cubeMesh.RecalculateBounds(); 939 | cubeMesh.Optimize(); 940 | } 941 | 942 | 943 | void CreateQuadMesh() 944 | { 945 | quadMesh = new Mesh(); 946 | 947 | Vector3 botleft = new Vector3(-1f, -1f, 0f), 948 | botRight = new Vector3(1f, -1f, 0f), 949 | topRight = new Vector3(1f, 1f, 0f), 950 | topLeft = new Vector3(-1f, 1f, 0f); 951 | 952 | quadMesh.vertices = new Vector3[] { 953 | botleft, botRight, topRight, topLeft 954 | }; 955 | 956 | quadMesh.triangles = new int[] { 957 | 0, 1, 2, 958 | 0, 2, 3 959 | }; 960 | } 961 | 962 | 963 | public void DrawMetavoxelGrid() 964 | { 965 | for (int zz = 0; zz < numMetavoxelsZ; zz++) 966 | { 967 | for (int yy = 0; yy < numMetavoxelsY; yy++) 968 | { 969 | for (int xx = 0; xx < numMetavoxelsX; xx++) 970 | { 971 | if (mvGrid[zz, yy, xx].mParticlesCovered.Count != 0) 972 | DrawMetavoxel(xx, yy, zz); 973 | } 974 | } 975 | } 976 | } 977 | 978 | 979 | void DrawMetavoxel(int xx, int yy, int zz) 980 | { 981 | List points = new List(); 982 | mvLineColor.SetPass(0); 983 | Vector3 mvPos = mvGrid[zz, yy, xx].mPos; 984 | Quaternion q = lightOrientation; 985 | 986 | 987 | float halfWidth = mvScale.x * 0.5f, halfHeight = mvScale.y * 0.5f, halfDepth = mvScale.z * 0.5f; 988 | // back, front --> Z ; top, bot --> Y ; left, right --> X 989 | Vector3 offBotLeftBack = q * new Vector3(-halfWidth, -halfHeight, halfDepth), 990 | offBotLeftFront = q * new Vector3(-halfWidth, -halfHeight, -halfDepth), 991 | offTopLeftBack = q * new Vector3(-halfWidth, halfHeight, halfDepth), 992 | offTopLeftFront = q * new Vector3(-halfWidth, halfHeight, -halfDepth), 993 | offBotRightBack = q * new Vector3(halfWidth, -halfHeight, halfDepth), 994 | offBotRightFront = q * new Vector3(halfWidth, -halfHeight, -halfDepth), 995 | offTopRightBack = q * new Vector3(halfWidth, halfHeight, halfDepth), 996 | offTopRightFront = q * new Vector3(halfWidth, halfHeight, -halfDepth); 997 | 998 | // left 999 | points.Add(mvPos + offBotLeftBack); 1000 | points.Add(mvPos + offBotLeftFront); 1001 | points.Add(mvPos + offBotLeftFront); 1002 | points.Add(mvPos + offTopLeftFront); 1003 | points.Add(mvPos + offTopLeftFront); 1004 | points.Add(mvPos + offTopLeftBack); 1005 | points.Add(mvPos + offTopLeftBack); 1006 | points.Add(mvPos + offBotLeftBack); 1007 | // right 1008 | points.Add(mvPos + offBotRightBack); 1009 | points.Add(mvPos + offBotRightFront); 1010 | points.Add(mvPos + offBotRightFront); 1011 | points.Add(mvPos + offTopRightFront); 1012 | points.Add(mvPos + offTopRightFront); 1013 | points.Add(mvPos + offTopRightBack); 1014 | points.Add(mvPos + offTopRightBack); 1015 | points.Add(mvPos + offBotRightBack); 1016 | // join left and right 1017 | points.Add(mvPos + offTopLeftBack); 1018 | points.Add(mvPos + offTopRightBack); 1019 | points.Add(mvPos + offTopLeftFront); 1020 | points.Add(mvPos + offTopRightFront); 1021 | 1022 | points.Add(mvPos + offBotLeftBack); 1023 | points.Add(mvPos + offBotRightBack); 1024 | points.Add(mvPos + offBotLeftFront); 1025 | points.Add(mvPos + offBotRightFront); 1026 | 1027 | GL.Begin(GL.LINES); 1028 | foreach (Vector3 v in points) 1029 | { 1030 | GL.Vertex3(v.x, v.y, v.z); 1031 | } 1032 | GL.End(); 1033 | } 1034 | 1035 | 1036 | /*********************** Gui callback setters ************************************** 1037 | * Functions below have been hooked to the appropriate GUI element in the inspector 1038 | */ 1039 | //-- render options 1040 | public void SetDisplacementScale(float ds) 1041 | { 1042 | fDisplacementScale = ds; 1043 | } 1044 | 1045 | 1046 | public void SetRayMarchSteps(float steps) 1047 | { 1048 | rayMarchSteps = (int) steps; 1049 | } 1050 | 1051 | 1052 | public void SetGridDimensions(float a) 1053 | { 1054 | // Resize grid 1055 | //ResizeMVGrid(a); 1056 | } 1057 | 1058 | public void SetGridScale(float s) 1059 | { 1060 | mvScale = new Vector3(s, s, s); 1061 | UpdateMetavoxelPositions(); 1062 | } 1063 | 1064 | //-- particle options 1065 | public void SetFadeOutParticles(bool fade) 1066 | { 1067 | fadeOutParticles = fade; 1068 | } 1069 | 1070 | public void SetParticleOpacityFactor(float f) 1071 | { 1072 | opacityFactor = f; 1073 | } 1074 | 1075 | public void SetNumParticles(float n) 1076 | { 1077 | particleSys.maxParticles = (int)n; 1078 | } 1079 | 1080 | public void SetFadeParticles(bool fade) 1081 | { 1082 | fadeOutParticles = fade; 1083 | } 1084 | 1085 | //-- render debug options 1086 | public void SetShowMetavoxelGrid(bool show) 1087 | { 1088 | bShowMetavoxelGrid = show; 1089 | } 1090 | 1091 | public void SetShowRayMarchSamples(bool show) 1092 | { 1093 | bShowRayMarchSamplesPerPixel = show; 1094 | } 1095 | 1096 | public void SetShowMetavoxelDrawOrder(bool show) 1097 | { 1098 | bShowMetavoxelDrawOrder = show; 1099 | } 1100 | 1101 | public void SetShowRayMarchBlendFunc(bool show) 1102 | { 1103 | bShowRayMarchBlendFunc = show; 1104 | } 1105 | 1106 | public void SetUpdateInterval(float interval) 1107 | { 1108 | updateInterval = (int) interval; 1109 | } 1110 | 1111 | public void SetTimeScale(float ts) 1112 | { 1113 | Time.timeScale = ts; 1114 | } 1115 | 1116 | public void SetSoftParticleDistance(float stepDistance) 1117 | { 1118 | softParticleStepDistance = (int) stepDistance; 1119 | } 1120 | 1121 | #if UNITY_EDITOR 1122 | void OnDrawGizmos() 1123 | { 1124 | Gizmos.color = Color.blue; 1125 | Vector3 lsWorldOrigin = dirLight.transform.worldToLocalMatrix.MultiplyPoint3x4(wsGridCenter); // xform origin to light space 1126 | 1127 | for (int zz = 0; zz < numMetavoxelsZ; zz++) 1128 | { 1129 | for (int yy = 0; yy < numMetavoxelsY; yy++) 1130 | { 1131 | for (int xx = 0; xx < numMetavoxelsX; xx++) 1132 | { 1133 | // if the scene isn't playing, the metavoxel grid wouldn't have been created. 1134 | // recalculate metavoxel positions and rotations based on the light 1135 | Vector3 lsOffset = Vector3.Scale(new Vector3(numMetavoxelsX / 2 - xx, numMetavoxelsY / 2 - yy, numMetavoxelsZ / 2 - zz), mvScale); 1136 | Vector3 wsMetavoxelPos = dirLight.transform.localToWorldMatrix.MultiplyPoint3x4(lsWorldOrigin - lsOffset); // using - lsOffset means that zz = 0 is closer to the light 1137 | Quaternion q = new Quaternion(); 1138 | q.SetLookRotation(dirLight.transform.forward, dirLight.transform.up); 1139 | Gizmos.matrix = Matrix4x4.TRS(wsMetavoxelPos, q, mvScale); 1140 | Gizmos.DrawWireCube(Vector3.zero, Vector3.one); 1141 | } 1142 | } 1143 | } 1144 | } 1145 | #endif 1146 | } 1147 | 1148 | 1149 | 1150 | } -------------------------------------------------------------------------------- /Assets/Main Scene/VolumetricParticleRenderer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 43ce582a35930e042899371fcfbb1102 3 | timeCreated: 1426787257 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: 8 | - dirLight: {instanceID: 0} 9 | - particleSys: {instanceID: 0} 10 | - guiOptions: {instanceID: 0} 11 | - matFillVolume: {fileID: 2100000, guid: 742e800cae20c4547bc14935a578e998, type: 2} 12 | - matRayMarch: {fileID: 2100000, guid: 865bff02ba66c2b4490cdab2d995b16f, type: 2} 13 | - matBlendParticles: {fileID: 2100000, guid: 81bb6726bf20108478e2d39eedcfffce, type: 2} 14 | - mvLineColor: {fileID: 2100000, guid: e091f90250c3ccc4eb5732506a7b76f6, type: 2} 15 | - generateLightDepthMapShader: {fileID: 4800000, guid: d503664f424880d40a00f7762d575f5c, 16 | type: 3} 17 | - lightPropogationUAV: {instanceID: 0} 18 | - lightDepthMap: {instanceID: 0} 19 | executionOrder: 0 20 | icon: {instanceID: 0} 21 | userData: 22 | assetBundleName: 23 | assetBundleVariant: 24 | -------------------------------------------------------------------------------- /Assets/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3d34a0e64691f3441869667e86a9489e 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Materials/Metavoxel.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1d4b0bd7abb9f8f42b66ac3bf204ecae 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Materials/Metavoxel/CompositeParticles.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 5 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: CompositeParticles 10 | m_Shader: {fileID: 4800000, guid: be36e9e514bc97142a8f15a82cd8709d, type: 3} 11 | m_ShaderKeywords: 12 | m_LightmapFlags: 5 13 | m_CustomRenderQueue: -1 14 | m_SavedProperties: 15 | serializedVersion: 2 16 | m_TexEnvs: 17 | data: 18 | first: 19 | name: _MainTex 20 | second: 21 | m_Texture: {fileID: 0} 22 | m_Scale: {x: 1, y: 1} 23 | m_Offset: {x: 0, y: 0} 24 | m_Floats: {} 25 | m_Colors: 26 | data: 27 | first: 28 | name: _Color 29 | second: {r: 1, g: 1, b: 1, a: 1} 30 | -------------------------------------------------------------------------------- /Assets/Materials/Metavoxel/CompositeParticles.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 81bb6726bf20108478e2d39eedcfffce 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Materials/Metavoxel/FillVolume.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 3 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: FillVolume 10 | m_Shader: {fileID: 4800000, guid: fa08e66a0b50f7c48a965042a5e7298e, type: 3} 11 | m_ShaderKeywords: [] 12 | m_CustomRenderQueue: -1 13 | m_SavedProperties: 14 | serializedVersion: 2 15 | m_TexEnvs: 16 | data: 17 | first: 18 | name: _MainTex 19 | second: 20 | m_Texture: {fileID: 0} 21 | m_Scale: {x: 1, y: 1} 22 | m_Offset: {x: 0, y: 0} 23 | data: 24 | first: 25 | name: _DisplacementTexture 26 | second: 27 | m_Texture: {fileID: 8900000, guid: 58fa667d98a6d2c4ca34acb0ad6bb945, type: 2} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | data: 31 | first: 32 | name: _RampTexture 33 | second: 34 | m_Texture: {fileID: 2800000, guid: 4f812e38977347943b92138e13876fd5, type: 3} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | data: 38 | first: 39 | name: _ParticleDisplacement 40 | second: 41 | m_Texture: {fileID: 0} 42 | m_Scale: {x: 1, y: 1} 43 | m_Offset: {x: 0, y: 0} 44 | m_Floats: 45 | data: 46 | first: 47 | name: _NumVoxels 48 | second: 32 49 | data: 50 | first: 51 | name: _InitLightIntensity 52 | second: 1 53 | m_Colors: 54 | data: 55 | first: 56 | name: _Color 57 | second: {r: 1, g: 1, b: 1, a: 1} 58 | -------------------------------------------------------------------------------- /Assets/Materials/Metavoxel/FillVolume.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 742e800cae20c4547bc14935a578e998 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Materials/Metavoxel/RayMarch.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 5 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: RayMarch 10 | m_Shader: {fileID: 4800000, guid: c62d2fea6be6f2c4788c9ee70dbba3f1, type: 3} 11 | m_ShaderKeywords: BLEND_UNDER 12 | m_LightmapFlags: 5 13 | m_CustomRenderQueue: -1 14 | m_SavedProperties: 15 | serializedVersion: 2 16 | m_TexEnvs: 17 | data: 18 | first: 19 | name: _MainTex 20 | second: 21 | m_Texture: {fileID: 0} 22 | m_Scale: {x: 1, y: 1} 23 | m_Offset: {x: 0, y: 0} 24 | data: 25 | first: 26 | name: _VolumeTexture 27 | second: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | data: 32 | first: 33 | name: _LightPropogationTexture 34 | second: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | m_Floats: 39 | data: 40 | first: 41 | name: SrcFactor 42 | second: 8 43 | data: 44 | first: 45 | name: DstFactor 46 | second: 1 47 | data: 48 | first: 49 | name: SrcFactorA 50 | second: 8 51 | data: 52 | first: 53 | name: DstFactorA 54 | second: 1 55 | m_Colors: 56 | data: 57 | first: 58 | name: _Color 59 | second: {r: 1, g: 1, b: 1, a: 1} 60 | -------------------------------------------------------------------------------- /Assets/Materials/Metavoxel/RayMarch.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 865bff02ba66c2b4490cdab2d995b16f 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Materials/Sampling.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b81d7b9f39b52d438ce3ba22406dec4 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Materials/Sampling/Sample2DTexture.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 3 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: Sample2DTexture 10 | m_Shader: {fileID: 4800000, guid: a3ff4195c4a69de4d9726a59048ab258, type: 3} 11 | m_ShaderKeywords: [] 12 | m_CustomRenderQueue: -1 13 | m_SavedProperties: 14 | serializedVersion: 2 15 | m_TexEnvs: 16 | data: 17 | first: 18 | name: _Plane 19 | second: 20 | m_Texture: {fileID: 0} 21 | m_Scale: {x: 1, y: 1} 22 | m_Offset: {x: 0, y: 0} 23 | data: 24 | first: 25 | name: _Volume 26 | second: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | m_Floats: 31 | data: 32 | first: 33 | name: _Slice 34 | second: 0 35 | m_Colors: {} 36 | -------------------------------------------------------------------------------- /Assets/Materials/Sampling/Sample2DTexture.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f8cf575e89a1f9e4eaf6221419e80a66 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Materials/Sampling/Sample3DTexture.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 3 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: Sample3DTexture 10 | m_Shader: {fileID: 4800000, guid: caebc3aa1d7f8594097c035cf0df6176, type: 3} 11 | m_ShaderKeywords: [] 12 | m_CustomRenderQueue: -1 13 | m_SavedProperties: 14 | serializedVersion: 2 15 | m_TexEnvs: 16 | data: 17 | first: 18 | name: _MainTex 19 | second: 20 | m_Texture: {fileID: 0} 21 | m_Scale: {x: 1, y: 1} 22 | m_Offset: {x: 0, y: 0} 23 | data: 24 | first: 25 | name: _VolumeTexture 26 | second: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | data: 31 | first: 32 | name: _LightPropogationTexture 33 | second: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | data: 38 | first: 39 | name: _Plane 40 | second: 41 | m_Texture: {fileID: 0} 42 | m_Scale: {x: 1, y: 1} 43 | m_Offset: {x: 0, y: 0} 44 | data: 45 | first: 46 | name: _Volume 47 | second: 48 | m_Texture: {fileID: 0} 49 | m_Scale: {x: 1, y: 1} 50 | m_Offset: {x: 0, y: 0} 51 | m_Floats: 52 | data: 53 | first: 54 | name: _NumVoxels 55 | second: 8 56 | m_Colors: 57 | data: 58 | first: 59 | name: _Color 60 | second: {r: 1, g: 1, b: 1, a: 1} 61 | -------------------------------------------------------------------------------- /Assets/Materials/Sampling/Sample3DTexture.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b1752c50d7a21b14799679916d6a3812 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Materials/Scene.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 59003395c72da45409b405e891fd47ef 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Materials/Scene/Cubes.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 5 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: Cubes 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: 12 | m_LightmapFlags: 5 13 | m_CustomRenderQueue: -1 14 | m_SavedProperties: 15 | serializedVersion: 2 16 | m_TexEnvs: 17 | data: 18 | first: 19 | name: _MainTex 20 | second: 21 | m_Texture: {fileID: 0} 22 | m_Scale: {x: 1, y: 1} 23 | m_Offset: {x: 0, y: 0} 24 | data: 25 | first: 26 | name: _BumpMap 27 | second: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | data: 32 | first: 33 | name: _DetailNormalMap 34 | second: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | data: 39 | first: 40 | name: _ParallaxMap 41 | second: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | data: 46 | first: 47 | name: _OcclusionMap 48 | second: 49 | m_Texture: {fileID: 0} 50 | m_Scale: {x: 1, y: 1} 51 | m_Offset: {x: 0, y: 0} 52 | data: 53 | first: 54 | name: _EmissionMap 55 | second: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | data: 60 | first: 61 | name: _DetailMask 62 | second: 63 | m_Texture: {fileID: 0} 64 | m_Scale: {x: 1, y: 1} 65 | m_Offset: {x: 0, y: 0} 66 | data: 67 | first: 68 | name: _DetailAlbedoMap 69 | second: 70 | m_Texture: {fileID: 0} 71 | m_Scale: {x: 1, y: 1} 72 | m_Offset: {x: 0, y: 0} 73 | data: 74 | first: 75 | name: _MetallicGlossMap 76 | second: 77 | m_Texture: {fileID: 0} 78 | m_Scale: {x: 1, y: 1} 79 | m_Offset: {x: 0, y: 0} 80 | m_Floats: 81 | data: 82 | first: 83 | name: _Cutoff 84 | second: .5 85 | data: 86 | first: 87 | name: _SrcBlend 88 | second: 1 89 | data: 90 | first: 91 | name: _DstBlend 92 | second: 0 93 | data: 94 | first: 95 | name: _Parallax 96 | second: .0199999996 97 | data: 98 | first: 99 | name: _ZWrite 100 | second: 1 101 | data: 102 | first: 103 | name: _Glossiness 104 | second: .5 105 | data: 106 | first: 107 | name: _BumpScale 108 | second: 1 109 | data: 110 | first: 111 | name: _OcclusionStrength 112 | second: 1 113 | data: 114 | first: 115 | name: _DetailNormalMapScale 116 | second: 1 117 | data: 118 | first: 119 | name: _UVSec 120 | second: 0 121 | data: 122 | first: 123 | name: _EmissionScaleUI 124 | second: 0 125 | data: 126 | first: 127 | name: _Mode 128 | second: 0 129 | data: 130 | first: 131 | name: _Metallic 132 | second: 0 133 | m_Colors: 134 | data: 135 | first: 136 | name: _EmissionColor 137 | second: {r: 0, g: 0, b: 0, a: 0} 138 | data: 139 | first: 140 | name: _Color 141 | second: {r: .814500451, g: .963235319, b: .950926244, a: 1} 142 | data: 143 | first: 144 | name: _EmissionColorUI 145 | second: {r: 1, g: 1, b: 1, a: 1} 146 | -------------------------------------------------------------------------------- /Assets/Materials/Scene/Cubes.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8205c9f80c49b314796f73aff877ba67 3 | timeCreated: 1427132388 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Materials/Scene/Cylinders.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 5 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: Cylinders 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: 12 | m_LightmapFlags: 5 13 | m_CustomRenderQueue: -1 14 | m_SavedProperties: 15 | serializedVersion: 2 16 | m_TexEnvs: 17 | data: 18 | first: 19 | name: _MainTex 20 | second: 21 | m_Texture: {fileID: 0} 22 | m_Scale: {x: 1, y: 1} 23 | m_Offset: {x: 0, y: 0} 24 | data: 25 | first: 26 | name: _BumpMap 27 | second: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | data: 32 | first: 33 | name: _DetailNormalMap 34 | second: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | data: 39 | first: 40 | name: _ParallaxMap 41 | second: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | data: 46 | first: 47 | name: _OcclusionMap 48 | second: 49 | m_Texture: {fileID: 0} 50 | m_Scale: {x: 1, y: 1} 51 | m_Offset: {x: 0, y: 0} 52 | data: 53 | first: 54 | name: _EmissionMap 55 | second: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | data: 60 | first: 61 | name: _DetailMask 62 | second: 63 | m_Texture: {fileID: 0} 64 | m_Scale: {x: 1, y: 1} 65 | m_Offset: {x: 0, y: 0} 66 | data: 67 | first: 68 | name: _DetailAlbedoMap 69 | second: 70 | m_Texture: {fileID: 0} 71 | m_Scale: {x: 1, y: 1} 72 | m_Offset: {x: 0, y: 0} 73 | data: 74 | first: 75 | name: _MetallicGlossMap 76 | second: 77 | m_Texture: {fileID: 0} 78 | m_Scale: {x: 1, y: 1} 79 | m_Offset: {x: 0, y: 0} 80 | m_Floats: 81 | data: 82 | first: 83 | name: _Cutoff 84 | second: .5 85 | data: 86 | first: 87 | name: _SrcBlend 88 | second: 1 89 | data: 90 | first: 91 | name: _DstBlend 92 | second: 0 93 | data: 94 | first: 95 | name: _Parallax 96 | second: .0199999996 97 | data: 98 | first: 99 | name: _ZWrite 100 | second: 1 101 | data: 102 | first: 103 | name: _Glossiness 104 | second: .5 105 | data: 106 | first: 107 | name: _BumpScale 108 | second: 1 109 | data: 110 | first: 111 | name: _OcclusionStrength 112 | second: 1 113 | data: 114 | first: 115 | name: _DetailNormalMapScale 116 | second: 1 117 | data: 118 | first: 119 | name: _UVSec 120 | second: 0 121 | data: 122 | first: 123 | name: _EmissionScaleUI 124 | second: 0 125 | data: 126 | first: 127 | name: _Mode 128 | second: 0 129 | data: 130 | first: 131 | name: _Metallic 132 | second: 0 133 | m_Colors: 134 | data: 135 | first: 136 | name: _EmissionColor 137 | second: {r: 0, g: 0, b: 0, a: 0} 138 | data: 139 | first: 140 | name: _Color 141 | second: {r: .889705896, g: .866245091, b: .549524248, a: 1} 142 | data: 143 | first: 144 | name: _EmissionColorUI 145 | second: {r: 1, g: 1, b: 1, a: 1} 146 | -------------------------------------------------------------------------------- /Assets/Materials/Scene/Cylinders.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1c40e863bc40f94409d0aa64294e1acf 3 | timeCreated: 1427134321 4 | licenseType: Free 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Materials/Scene/Ground.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 5 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: Ground 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: 12 | m_LightmapFlags: 5 13 | m_CustomRenderQueue: -1 14 | m_SavedProperties: 15 | serializedVersion: 2 16 | m_TexEnvs: 17 | data: 18 | first: 19 | name: _MainTex 20 | second: 21 | m_Texture: {fileID: 0} 22 | m_Scale: {x: 1, y: 1} 23 | m_Offset: {x: 0, y: 0} 24 | data: 25 | first: 26 | name: _BumpMap 27 | second: 28 | m_Texture: {fileID: 0} 29 | m_Scale: {x: 1, y: 1} 30 | m_Offset: {x: 0, y: 0} 31 | data: 32 | first: 33 | name: _DetailNormalMap 34 | second: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | data: 39 | first: 40 | name: _ParallaxMap 41 | second: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | data: 46 | first: 47 | name: _OcclusionMap 48 | second: 49 | m_Texture: {fileID: 0} 50 | m_Scale: {x: 1, y: 1} 51 | m_Offset: {x: 0, y: 0} 52 | data: 53 | first: 54 | name: _EmissionMap 55 | second: 56 | m_Texture: {fileID: 0} 57 | m_Scale: {x: 1, y: 1} 58 | m_Offset: {x: 0, y: 0} 59 | data: 60 | first: 61 | name: _DetailMask 62 | second: 63 | m_Texture: {fileID: 0} 64 | m_Scale: {x: 1, y: 1} 65 | m_Offset: {x: 0, y: 0} 66 | data: 67 | first: 68 | name: _DetailAlbedoMap 69 | second: 70 | m_Texture: {fileID: 0} 71 | m_Scale: {x: 1, y: 1} 72 | m_Offset: {x: 0, y: 0} 73 | data: 74 | first: 75 | name: _MetallicGlossMap 76 | second: 77 | m_Texture: {fileID: 0} 78 | m_Scale: {x: 1, y: 1} 79 | m_Offset: {x: 0, y: 0} 80 | data: 81 | first: 82 | name: _SpecGlossMap 83 | second: 84 | m_Texture: {fileID: 0} 85 | m_Scale: {x: 1, y: 1} 86 | m_Offset: {x: 0, y: 0} 87 | m_Floats: 88 | data: 89 | first: 90 | name: _Cutoff 91 | second: .5 92 | data: 93 | first: 94 | name: _SrcBlend 95 | second: 1 96 | data: 97 | first: 98 | name: _DstBlend 99 | second: 0 100 | data: 101 | first: 102 | name: _Parallax 103 | second: .0199999996 104 | data: 105 | first: 106 | name: _ZWrite 107 | second: 1 108 | data: 109 | first: 110 | name: _Glossiness 111 | second: .5 112 | data: 113 | first: 114 | name: _BumpScale 115 | second: 1 116 | data: 117 | first: 118 | name: _OcclusionStrength 119 | second: 1 120 | data: 121 | first: 122 | name: _DetailNormalMapScale 123 | second: 1 124 | data: 125 | first: 126 | name: _UVSec 127 | second: 0 128 | data: 129 | first: 130 | name: _EmissionScaleUI 131 | second: 0 132 | data: 133 | first: 134 | name: _Mode 135 | second: 0 136 | data: 137 | first: 138 | name: _Metallic 139 | second: 0 140 | m_Colors: 141 | data: 142 | first: 143 | name: _EmissionColor 144 | second: {r: 0, g: 0, b: 0, a: 0} 145 | data: 146 | first: 147 | name: _Color 148 | second: {r: .669117689, g: .608778298, b: .54611814, a: 1} 149 | data: 150 | first: 151 | name: _SpecColor 152 | second: {r: .200000003, g: .200000003, b: .200000003, a: 1} 153 | data: 154 | first: 155 | name: _EmissionColorUI 156 | second: {r: 1, g: 1, b: 1, a: 1} 157 | -------------------------------------------------------------------------------- /Assets/Materials/Scene/Ground.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6c9db4a8ded6ecb4da0459f537cafb24 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Materials/Scene/matGridLines.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 3 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: matGridLines 10 | m_Shader: {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: [] 12 | m_CustomRenderQueue: -1 13 | m_SavedProperties: 14 | serializedVersion: 2 15 | m_TexEnvs: 16 | data: 17 | first: 18 | name: _MainTex 19 | second: 20 | m_Texture: {fileID: 0} 21 | m_Scale: {x: 1, y: 1} 22 | m_Offset: {x: 0, y: 0} 23 | m_Floats: {} 24 | m_Colors: 25 | data: 26 | first: 27 | name: _Color 28 | second: {r: .136786312, g: .808823526, b: .252654821, a: 1} 29 | -------------------------------------------------------------------------------- /Assets/Materials/Scene/matGridLines.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e091f90250c3ccc4eb5732506a7b76f6 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Materials/matFill2D3DTexture.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 3 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: matFill2D3DTexture 10 | m_Shader: {fileID: 4800000, guid: 6f9f2988c51a4514c966684bfa4c3025, type: 3} 11 | m_ShaderKeywords: [] 12 | m_CustomRenderQueue: -1 13 | m_SavedProperties: 14 | serializedVersion: 2 15 | m_TexEnvs: 16 | data: 17 | first: 18 | name: _MainTex 19 | second: 20 | m_Texture: {fileID: 0} 21 | m_Scale: {x: 1, y: 1} 22 | m_Offset: {x: 0, y: 0} 23 | m_Floats: {} 24 | m_Colors: 25 | data: 26 | first: 27 | name: _Color 28 | second: {r: 1, g: 1, b: 1, a: 1} 29 | -------------------------------------------------------------------------------- /Assets/Materials/matFill2D3DTexture.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 12bd877ecc2172942a891cf614989715 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5cae99094af3b345b37dd8d6f53c4e6 3 | folderAsset: yes 4 | timeCreated: 1427152933 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ce3a2ae81ad083c4a95888e109c56fdf 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Shaders/Metavoxel.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 79f543fde9d68b54f8b06ca1b582f5a1 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Shaders/Metavoxel/CompositeParticles.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/Composite Particles" { 2 | Properties { 3 | _MainTex ("Particle Texture", 2D) = "white" {} 4 | } 5 | SubShader { 6 | Tags{ "Queue" = "Transparent"} 7 | Pass{ 8 | Cull Off ZWrite Off ZTest Always // ZTest Always => Don't perform ZTest 9 | // Syntax: Blend SrcFactor DstFactor, SrcFactorA DstFactorA 10 | Blend One OneMinusSrcAlpha, One One 11 | BlendOp Add 12 | 13 | CGPROGRAM 14 | #pragma vertex vert_img 15 | #pragma fragment frag 16 | #include "UnityCG.cginc" 17 | 18 | sampler2D _MainTex; 19 | 20 | float4 frag(v2f_img i) : COLOR{ 21 | float4 c = tex2D(_MainTex, i.uv); 22 | return c; 23 | } 24 | ENDCG 25 | } 26 | }FallBack Off 27 | } 28 | -------------------------------------------------------------------------------- /Assets/Shaders/Metavoxel/CompositeParticles.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: be36e9e514bc97142a8f15a82cd8709d 3 | ShaderImporter: 4 | defaultTextures: [] 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Shaders/Metavoxel/FillVolume.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/Fill Volume" { 2 | Properties { 3 | _DisplacementTexture("Displaced sphere", Cube) = "white" {} 4 | _RampTexture("Ramp Texture", 2D) = "" {} 5 | } 6 | SubShader { 7 | Pass{ 8 | Cull Off ZWrite Off ZTest Off 9 | CGPROGRAM 10 | #pragma target 5.0 11 | //#pragma exclude_renderers flash 12 | #pragma enable_d3d11_debug_symbols 13 | #pragma vertex vert_img 14 | //#pragma vertex vert 15 | #pragma fragment frag 16 | #define NUM_VOXELS 32 17 | 18 | #include "UnityCG.cginc" 19 | 20 | // If filling the metavoxels via DrawMeshNow, we'll need to use a standard VS instead of the built-in vert_img 21 | // Note: DrawMeshNow doesn't work with multiple UAV writes. Hence going with Graphics.Blit in the main script 22 | //struct vs_input { 23 | // float4 vertex : POSITION; 24 | //}; 25 | 26 | //struct v2f { 27 | // float4 pos : SV_POSITION; 28 | //}; 29 | 30 | //v2f vert(vs_input i) { 31 | // v2f o; 32 | // o.pos = i.vertex; 33 | // return o; 34 | //} 35 | 36 | // particle 37 | struct Particle { 38 | float4x4 mWorldToLocal; 39 | float3 mWorldPos; 40 | float mRadius; 41 | float mLifetimeOpacity; // [0.0, 1.0] 42 | }; 43 | 44 | struct Voxel { 45 | half density; // affects opacity 46 | half ao; // affects color 47 | }; 48 | 49 | // UAVs 50 | RWTexture3D volumeTex; // out 51 | RWTexture2D lightPropogationTex; // in-out 52 | 53 | // Particles covering the current metavoxel 54 | StructuredBuffer _Particles; // in 55 | 56 | // Textures 57 | samplerCUBE _DisplacementTexture; 58 | sampler2D _RampTexture; 59 | sampler2D _LightDepthMap; 60 | 61 | // Current metavoxel's constants 62 | CBUFFER_START(MetavoxelConstants) 63 | float4x4 _MetavoxelToWorld; 64 | float3 _MetavoxelIndex; 65 | int _NumParticles; 66 | CBUFFER_END 67 | 68 | // Uniforms over entire fill pass 69 | // -- light stuff 70 | CBUFFER_START(LightConstants) 71 | float4x4 _WorldToLight; 72 | float4x4 _LightProjection; 73 | float3 _LightForward; // worldspace 74 | float3 _LightColor; 75 | float3 _AmbientColor; 76 | float _InitLightIntensity; 77 | float _NearZ, _FarZ; 78 | CBUFFER_END 79 | 80 | // -- metavoxel stuff 81 | CBUFFER_START(VolumeConstants) 82 | float3 _MetavoxelGridDim; 83 | float _NumVoxels; // (nv) each metavoxel is made up of nv * nv * nv voxels 84 | int _MetavoxelBorderSize; 85 | float _MetavoxelScaleZ; 86 | CBUFFER_END 87 | 88 | // -- particle stuff 89 | CBUFFER_START(ParticleConstants) 90 | float _OpacityFactor; 91 | int _FadeOutParticles; 92 | float _DisplacementScale; 93 | CBUFFER_END 94 | 95 | // helper methods 96 | float4 97 | get_voxel_world_pos(float2 svPos, float zSlice) 98 | { 99 | // svPos goes from [0, numVoxels]. transform to a [-0.5, 0.5] range w.r.t metavoxel centered at origin 100 | // the metavoxel grid follows the light space -- i.e, x0, y0, z0 is left-bot-front (and closest to the light) 101 | // see VolumetricParticleRenderer::UpdateMetavoxelPositions() 102 | float3 voxelPos = float3(svPos, zSlice); 103 | float4 normPos = float4((svPos - _NumVoxels/2) / _NumVoxels, (zSlice - _NumVoxels/2) / _NumVoxels, 1.0); 104 | 105 | // with all dimensions in normalizaed unit cube (metavoxel) space, transform to world space 106 | return mul(_MetavoxelToWorld, normPos); 107 | } 108 | 109 | 110 | void 111 | compute_voxel_color(float3 psVoxelPos /*voxel position in particle space*/, 112 | float opacity, /*particle opacity -- particle fades away as it dies*/ 113 | out Voxel v) 114 | { 115 | // sample the displacement noise texture for the particle 116 | half rawDisplacement = texCUBE(_DisplacementTexture, 2*psVoxelPos).x; // [todo] -- is the texcoord correct for cube sampling?? 117 | 118 | // the scale factor can be used to weigh the above calculated noise displacement. 119 | half netDisplacement = _DisplacementScale * rawDisplacement + (1.0 - _DisplacementScale); // disp. from center in the range [0, 1] 120 | 121 | float voxelParticleDistSq = dot(2 * psVoxelPos, 2 * psVoxelPos); // make it [0, 1] 122 | 123 | // how dense is this particle at the current voxel? (density falls quickly as we move to the outer surface of the particle) 124 | // voxelParticleDistSq < 0.7 * netDisplacement ==> baseDensity = 1, voxelParticleDistSq > netDisplacement ==> baseDensity = 0 125 | // 0.7 * netDisplacement < voxelParticleDistSq < netDisplacement ==> baseDensity ==> linear drop 126 | half baseDensity = smoothstep(netDisplacement, 0.7 * netDisplacement, voxelParticleDistSq); // [0.0, 1.0] 127 | half density = baseDensity * _OpacityFactor; 128 | 129 | // factor in the particle's lifetime opacity & opacity factor 130 | if (_FadeOutParticles == 1) 131 | density *= opacity; 132 | 133 | v.density = density; 134 | v.ao = netDisplacement; 135 | } 136 | 137 | 138 | // return a lightTransmission factor in the range [0.0, 1.0] for hardShadows .. softShadows 139 | half 140 | shadowDropOff(int voxelIndex, int shadowIndex) 141 | { 142 | // the closer the voxel is to a shadow caster, the lesser light it receives and the "harder" the shadow casted on it looks 143 | // we know for sure that shadowIndex <= voxelIndex (since hte voxel is in shadow) 144 | 145 | return ( 1 - rcp(1 + (voxelIndex - shadowIndex)) ); 146 | } 147 | 148 | 149 | // Fragment shader fills a "voxel column" of the metavoxel's volume texture 150 | // For each voxel in the voxel column of our metavoxel, we iterate through all the displaced particles covered by the metavoxel and test for coverage. 151 | // If a displaced particle covers the voxel's center, we calculate its contribution to "density" and "ao". 152 | half4 153 | frag(v2f_img i) : COLOR 154 | { 155 | int slice, pp; // loop counters 156 | Voxel voxelColumn[NUM_VOXELS]; // temporary storage for the voxel column associated with the current fragment 157 | 158 | // Iterate through the voxel column with the first particle, clearing the voxel if it isn't covered 159 | // (This saves us a conditional check for every other particle) 160 | float oneVoxelSize = _MetavoxelScaleZ / _NumVoxels; // assuming scale is same in X and Y below (this scale includes the border) 161 | float3 voxel0WorldPos = get_voxel_world_pos(i.pos.xy, 0); 162 | float3 voxelWorldPos = voxel0WorldPos; 163 | 164 | for (slice = 0; slice < _NumVoxels; slice++) 165 | { 166 | Particle p = _Particles[0]; 167 | 168 | // get world pos for the current voxel accounting for the "scaled" metavoxel 169 | float3 psVoxelPos = mul( p.mWorldToLocal, float4(voxelWorldPos, 1.0) ); // voxel position in particle space 170 | float dist2 = dot(psVoxelPos, psVoxelPos); 171 | 172 | if (dist2 <= 0.25) // 0.5 * 0.5 -- if the voxel center is within the particle it'd be less than 0.5 units away from the particle center in particle space 173 | { 174 | compute_voxel_color(psVoxelPos, p.mLifetimeOpacity, voxelColumn[slice]); 175 | } 176 | else 177 | { 178 | // particle doesn't cover voxel. clear it. 179 | voxelColumn[slice].density = 0.0; 180 | voxelColumn[slice].ao = 0.0; 181 | } 182 | 183 | voxelWorldPos += _LightForward * oneVoxelSize; 184 | } 185 | 186 | voxelWorldPos = voxel0WorldPos; // reset 187 | // Iterate through all the remaining particles for every voxel in the voxel column 188 | for (slice = 0; slice < _NumVoxels; slice++) 189 | { 190 | for (pp = 1; pp < _NumParticles; pp++) 191 | { 192 | Particle p = _Particles[pp]; 193 | 194 | float3 psVoxelPos = mul( p.mWorldToLocal, float4(voxelWorldPos, 1.0) ); // voxel position in particle space 195 | float dist2 = dot(psVoxelPos, psVoxelPos); 196 | Voxel v; 197 | 198 | if (dist2 <= 0.25) // 0.5 * 0.5 -- if the voxel center is within the particle it'd be less than 0.5 units away from the particle center in particle space 199 | { 200 | compute_voxel_color(psVoxelPos, p.mLifetimeOpacity, v); 201 | 202 | voxelColumn[slice].density += v.density; 203 | voxelColumn[slice].ao = max(voxelColumn[slice].ao, v.ao); 204 | } 205 | } // per particle 206 | 207 | voxelWorldPos += _LightForward * oneVoxelSize; 208 | } // per slice 209 | 210 | // Account for occlusion of the voxel column by objects in the scene 211 | float4 lsVoxel0 = mul(_WorldToLight, get_voxel_world_pos(i.pos.xy, 0)); 212 | 213 | // don't need to convert voxel to light clip space since our shadow map is constrained to the exact dimensions of a "slice" of the volume grid 214 | float2 lsTexCoord = (i.pos.xy + _MetavoxelIndex.xy * _NumVoxels) / (_MetavoxelGridDim.xy * _NumVoxels); 215 | // don't need to invert the y component of UV (even though Unity renders to the depth texture with Y inverted). 216 | float d = tex2D(_LightDepthMap, lsTexCoord); // [0,1] 217 | float a = rcp(_FarZ - _NearZ), b = -_NearZ * a; 218 | float lsSceneDepth = (d - b) * rcp(a); 219 | float lsVoxelColumnStart = lsVoxel0.z; 220 | 221 | int shadowIndex = (lsSceneDepth - lsVoxelColumnStart) / (oneVoxelSize); 222 | 223 | // transmitted light is used to shade a voxel (and is attenuated by density or occlusion) 224 | float transmittedLight = (_MetavoxelIndex.z == 0)? _InitLightIntensity : lightPropogationTex[int2(i.pos.xy + _MetavoxelIndex.xy * _NumVoxels)]; 225 | // propagated light is what ends up written to the light propagation texture (duh!). it represents the amount of light that made it through the volume 226 | // prior to occlusion. this way, we can project the light propagation texture on to the scene to correctly influence lighting (and thus have shadows cast by the volume) 227 | float propagatedLight = transmittedLight; 228 | float diffuseColor = 0.4; // constant "color" if not emissive 229 | int borderVoxelIndex = _NumVoxels - _MetavoxelBorderSize; 230 | 231 | for (slice = 0; slice < borderVoxelIndex; slice++) 232 | { 233 | bool inShadow = (slice >= shadowIndex); 234 | 235 | if (inShadow) { 236 | //transmittedLight = propagatedLight * shadowDropOff(slice, shadowIndex); 237 | transmittedLight = 0.0; 238 | } 239 | else 240 | propagatedLight = transmittedLight; 241 | 242 | half3 finalColor = diffuseColor * transmittedLight /* direct lighting */ + 243 | (_AmbientColor * voxelColumn[slice].ao); /* indirect lighting */ 244 | 245 | transmittedLight *= rcp(1.0 + voxelColumn[slice].density); 246 | 247 | volumeTex[int3(i.pos.xy, slice)] = half4(finalColor, voxelColumn[slice].density); 248 | } 249 | 250 | lightPropogationTex[int2(i.pos.xy + _MetavoxelIndex.xy * _NumVoxels)] = propagatedLight; 251 | 252 | // go over border voxels in the "far" end of the voxel column (this can be simplified if border is restricted to 0 or 1) 253 | // light transmitted by the "far border voxels" isn't written to the light propagation texture to ensure correct light transmittance to 254 | // the "near border voxels" of the voxel column behind this one 255 | 256 | for(slice = borderVoxelIndex; slice < _NumVoxels; slice++) 257 | { 258 | bool inShadow = (slice >= shadowIndex); 259 | 260 | if (inShadow) 261 | transmittedLight = 0.0; 262 | 263 | half3 finalColor = diffuseColor * transmittedLight /* direct lighting */ + 264 | (_AmbientColor * voxelColumn[slice].ao); /* indirect lighting */ 265 | 266 | transmittedLight *= rcp(1.0 + voxelColumn[slice].density); 267 | 268 | volumeTex[int3(i.pos.xy, slice)] = half4(finalColor, voxelColumn[slice].density); 269 | } 270 | 271 | /* this fragment shader does NOT return anything. it's merely used for filling a voxel column with color and density values by propagating light through it*/ 272 | discard; 273 | return half4(d, lsVoxel0.z, lsSceneDepth, 1.0f); // return statement is required by the compiler 274 | } 275 | 276 | ENDCG 277 | } 278 | }FallBack Off 279 | } 280 | 281 | 282 | 283 | -------------------------------------------------------------------------------- /Assets/Shaders/Metavoxel/FillVolume.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa08e66a0b50f7c48a965042a5e7298e 3 | ShaderImporter: 4 | defaultTextures: 5 | - _DisplacementTexture: {fileID: 8900000, guid: 58fa667d98a6d2c4ca34acb0ad6bb945, 6 | type: 2} 7 | - _RampTexture: {fileID: 2800000, guid: 4f812e38977347943b92138e13876fd5, type: 3} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Shaders/Metavoxel/GenerateLightDepthMap.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/Generate Light Depth Map" { 2 | Properties { 3 | } 4 | SubShader { 5 | Pass{ 6 | Cull Front ZWrite On ZTest Less 7 | 8 | CGPROGRAM 9 | #pragma target 4.0 10 | #pragma enable_d3d11_debug_symbols 11 | #pragma vertex vert 12 | #pragma fragment frag 13 | 14 | #include "UnityCG.cginc" 15 | 16 | struct v2f { 17 | float4 pos : SV_POSITION; 18 | }; 19 | 20 | 21 | v2f vert(appdata_base i) 22 | { 23 | v2f o; 24 | o.pos = mul(UNITY_MATRIX_MVP, i.vertex); 25 | return o; 26 | } 27 | 28 | float4 frag(v2f i) : COLOR 29 | { 30 | return float4(1,1,1,1); // Invoking this shader with only a depth texture bound makes this line useless (i.e., only the depth is written to. Color isn't even bound) 31 | } 32 | 33 | ENDCG 34 | } // Pass 35 | }FallBack Off // Subshader 36 | } // Shader -------------------------------------------------------------------------------- /Assets/Shaders/Metavoxel/GenerateLightDepthMap.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d503664f424880d40a00f7762d575f5c 3 | ShaderImporter: 4 | defaultTextures: [] 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Shaders/Metavoxel/RayMarchVoxel.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/RayMarchMetavoxel" { 2 | Properties{ 3 | _VolumeTexture("Metavoxel fill data", 3D) = "" {} 4 | _LightPropogationTexture("Light Propogation", 2D) = "" {} 5 | SrcFactor ("SrcFactor", Int) = 0 6 | DstFactor ("DstFactor", Int) = 0 7 | SrcFactorA ("SrcFactorA", Int) = 0 8 | DstFactorA ("DstFactorA", Int) = 0 9 | } 10 | SubShader 11 | { 12 | Pass 13 | { 14 | Cull Front ZWrite Off ZTest Less 15 | // Syntax: Blend SrcFactor DstFactor, SrcFactorA DstFactorA 16 | // Set these properties via script to avoid having two shaders that differ only in the blend modes 17 | Blend [SrcFactor] [DstFactor], [SrcFactorA] [DstFactorA] 18 | BlendOp Add 19 | 20 | CGPROGRAM 21 | #pragma target 5.0 22 | //#pragma exclude_renderers flash 23 | #pragma enable_d3d11_debug_symbols 24 | #pragma vertex vert 25 | #pragma fragment frag 26 | 27 | #include "UnityCG.cginc" 28 | #define green1 float4(0.0, 0.2, 0.0, 0.5) 29 | #define green2 float4(0.0, 0.5, 0.0, 0.5) 30 | #define yellow float4(0.5, 0.5, 0.0, 0.5) 31 | #define orange float4(0.6, 0.4, 0.0, 0.5) 32 | #define red float4(0.6, 0.0, 0.0, 0.5) 33 | #define red2 float4(0.8, 0.0, 0.0, 0.5) 34 | #define red3 float4(1.0, 0.0, 0.0, 0.5) 35 | #define redb float4(0.5, 0.0, 0.0, 1.0) 36 | #define blueb float4(0.0, 0.0, 0.5, 1.0) 37 | #define greenb float4(0.0, 0.5, 0.0, 1.0) 38 | #define seethrough float4(0.0, 0.0, 0.0, 0.0) 39 | 40 | #define SQ_ROOT_3 1.73205 41 | 42 | sampler3D _VolumeTexture; 43 | sampler2D _LightPropogationTexture; 44 | 45 | // Metavoxel uniforms 46 | CBUFFER_START(MetavoxelConstants) 47 | float4x4 _MetavoxelToWorld; 48 | float4x4 _CameraToMetavoxel; 49 | //float4x4 _WorldToMetavoxel; 50 | float3 _MetavoxelIndex; 51 | float _ParticleCoverageRatio; 52 | CBUFFER_END 53 | 54 | CBUFFER_START(VolumeConstants) 55 | float3 _MetavoxelGridDim; 56 | float3 _MetavoxelSize; 57 | float3 _MetavoxelGridCenter; 58 | float _NumVoxels; // metavoxel's voxel dimensions 59 | int _MetavoxelBorderSize; 60 | int _NumRaymarchStepsPerMV; 61 | int _SoftDistance; 62 | //float4 _AABBMin; 63 | //float4 _AABBMax; 64 | //float3 _MetavoxelScale; 65 | CBUFFER_END 66 | 67 | // Camera uniforms 68 | CBUFFER_START(CameraConstants) 69 | //float4x4 _CameraToWorldMatrix; // need to explicitly define this to get the main camera's matrices 70 | float4x4 _WorldToCameraMatrix; 71 | //float3 _CameraWorldPos; 72 | float _Fov; 73 | //float _Near; 74 | //float _Far; 75 | float4 _ScreenRes; 76 | CBUFFER_END 77 | 78 | // tmp 79 | CBUFFER_START(TmpConstants) 80 | int _ShowNumSamples; 81 | int _ShowMetavoxelDrawOrder; 82 | int _OrderIndex; 83 | int _NumMetavoxelsCovered; 84 | int _ShowRayMarchBlendFunc; 85 | int _RayMarchBlendOver; 86 | CBUFFER_END 87 | 88 | struct Ray { 89 | float3 o; // origin 90 | float3 d; // direction (normalized) 91 | }; 92 | 93 | 94 | // Simon Green's beautiful ray-box intersection code 95 | bool 96 | IntersectBox(Ray r, float3 boxmin, float3 boxmax, 97 | out float tnear, out float tfar) 98 | { 99 | // compute intersection of ray with all six bbox planes 100 | float3 invR = 1.0 / r.d; 101 | float3 tbot = invR * (boxmin.xyz - r.o); 102 | float3 ttop = invR * (boxmax.xyz - r.o); 103 | // re-order intersections to find smallest and largest on each axis 104 | float3 tmin = min(ttop, tbot); 105 | float3 tmax = max(ttop, tbot); 106 | // find the largest tmin and the smallest tmax 107 | float2 t0 = max(tmin.xx, tmin.yz); 108 | tnear = max(t0.x, t0.y); 109 | t0 = min(tmax.xx, tmax.yz); 110 | tfar = min(t0.x, t0.y); 111 | // check for hit 112 | bool hit; 113 | if ((tnear > tfar)) 114 | hit = false; 115 | else 116 | hit = true; 117 | return hit; 118 | } 119 | 120 | 121 | // Color the metavoxels being raymarched in the order they were submitted 122 | // [t = 0] bright green --> dull green --> bright blue --> dull blue --> bright red --> dull red [t = end] 123 | float4 DrawOrderColoring() 124 | { 125 | int numColorsPerChannel = ceil(_NumMetavoxelsCovered / (float) 3); 126 | 127 | int channelSelect = _OrderIndex / numColorsPerChannel; 128 | int channelIndex = _OrderIndex % numColorsPerChannel; 129 | 130 | float channelIntensity = (numColorsPerChannel - channelIndex) / float (numColorsPerChannel); 131 | 132 | if (channelSelect == 0) 133 | return float4(0, channelIntensity, 0, 1); 134 | else if (channelSelect == 1) 135 | return float4(0, 0, channelIntensity, 1); 136 | else 137 | return float4(channelIntensity, 0, 0, 1); 138 | } 139 | 140 | 141 | struct v2f { 142 | float4 pos : SV_POSITION; 143 | //float3 worldPos : TEXCOORD; 144 | }; 145 | 146 | 147 | // Vertex shader 148 | v2f 149 | vert(appdata_base i) { 150 | // every vertex submitted is in a unit-metavoxel space 151 | // transform from model -> world -> eye -> proj -> clip space 152 | v2f o; 153 | 154 | // can't use the default UNITY_MATRIX_MVP since the draw is made using Graphics.DrawMeshNow 155 | o.pos = mul(mul(UNITY_MATRIX_VP, _MetavoxelToWorld), i.vertex); // clip space 156 | //o.worldPos = mul(_MetavoxelToWorld, i.vertex); // world space 157 | return o; 158 | } 159 | 160 | // Fragment shader 161 | // Ray march the current metavoxel (against the light direction), sampling from its 3D texture and 162 | // blending samples back-to-front. 163 | // The number of samples per ray through the volume is constant. i.e., the step length when projected onto 164 | // the view direction is constant (step length varies to ensure 165 | // same # of samples per ray) 166 | half4 167 | frag(v2f i) : COLOR 168 | { 169 | // Debug options 170 | if (_ShowMetavoxelDrawOrder == 1) 171 | { 172 | return DrawOrderColoring(); 173 | } 174 | else if (_ShowRayMarchBlendFunc == 1) 175 | { 176 | if (_RayMarchBlendOver == 1) 177 | return float4(0.5, 0.5, 0, 1); // yellow for back-to-front blending 178 | else 179 | return float4(0, 0.5, 0.5, 1); // cyan for front-to-back blending 180 | 181 | } 182 | 183 | 184 | // positions and directions are generally prefixed with their space [cs = camera (view) space, mv = metavoxel space] 185 | // cs is RHS (see link below), while everything else is LHS (as in the Unity editor) 186 | 187 | // Find ray direction from camera through this pixel 188 | float3 csRayDir; 189 | csRayDir.xy = (2.0 * i.pos.xy / _ScreenRes) - 1.0; // [0, wh] to [-1, 1]; 190 | csRayDir.x *= (_ScreenRes.x / _ScreenRes.y); // account for aspect ratio 191 | // Note that camera space (alone) matches OpenGL convention: camera's forward is the negative Z axis http://docs.unity3d.com/ScriptReference/Camera-worldToCameraMatrix.html 192 | // Hence the - sign below 193 | csRayDir.z = -rcp(tan(_Fov / 2.0)); // tan(fov_y / 2) = 1 / (norm_z) 194 | csRayDir = normalize(csRayDir); 195 | 196 | // alternative way to find ray direction using interpolated world pos from the VS 197 | //float3 csRayDir = normalize(mul(_WorldToCameraMatrix, float4(i.worldPos - _CameraWorldPos, 0))); 198 | 199 | // Using a camere-AABB for the volume shows a snapping artifact as the camera moves 200 | // Unsure if this is a lag problem or sth else. 201 | //float3 csAABBStart = csRayDir * (_AABBMin.z / csRayDir.z); 202 | //float3 csAABBEnd = csRayDir * (_AABBMax.z / csRayDir.z); 203 | 204 | // Find the approximate bounds of the entire metavoxel grid region in camera space 205 | // This is done to to find the near and far AABB planes of the volume (parallel to camera view plane) to start/end the ray march through the volume 206 | float3 csVolOrigin = mul(_WorldToCameraMatrix, float4(_MetavoxelGridCenter, 1)); // [todo] remove restriction on grid being centered at world origin 207 | float2 nn = max(_MetavoxelGridDim.xx, _MetavoxelGridDim.yz); 208 | float maxGridDim = max(nn.x, nn.y); 209 | 210 | float csVolHalfZ = SQ_ROOT_3 * 0.5 * maxGridDim * _MetavoxelSize.x; 211 | float csZVolMin = csVolOrigin.z + csVolHalfZ, // minZ > maxZ since -Z is the camera view direction 212 | csZVolMax = csVolOrigin.z - csVolHalfZ; 213 | float3 csAABBStart = csRayDir * (csZVolMin / csRayDir.z); // start is closer to the camera; camera is at the origin in camera space 214 | float csRayLength = 2 * csVolHalfZ; 215 | 216 | Ray mvRay; 217 | mvRay.o = mul(_CameraToMetavoxel, float4(csAABBStart, 1)); 218 | mvRay.d = normalize( mul(_CameraToMetavoxel, float4(csRayDir, 0)) ); 219 | 220 | // The number of steps marched along any ray from the camera is a constant. The step length varies as a result (oblique rays == longer steps) 221 | float totalRayMarchSteps = /*SQ_ROOT_3*/ maxGridDim * float(_NumRaymarchStepsPerMV); // per ray 222 | float oneOverTotalRayMarchSteps = rcp(totalRayMarchSteps); 223 | float mvRayLength = csRayLength * rcp(_MetavoxelSize.z); // [todo] this restricts metavoxel to only cubes 224 | float mvStepSize = mvRayLength * oneOverTotalRayMarchSteps; 225 | 226 | // Find the intersection between the ray and the current metavoxel 227 | float3 mvMin = float3(-0.5, -0.5, -0.5); 228 | float t1, t2; // t1 and t2 represent distance from the ray origin (near plane of the volume AABB) of the intersection points on the metavoxel (t1, t2 >= 0) 229 | bool intersects = IntersectBox(mvRay, mvMin, -mvMin, t1, t2); 230 | if (!intersects) 231 | return seethrough; // ray passes through the cube corner 232 | 233 | // find step indices; note that tentry and texit are guaranteed to be >=0 234 | // however, it is possible for the camera to be within the current metavoxel, in which case texit > tcamera >= tentry. 235 | // for this case, we should ensure we don't sample points (within the metavoxel) behind the camera 236 | int tEntry = ceil(t1 / mvStepSize); // entry index 237 | int tExit = floor(t2 / mvStepSize); // exit index 238 | float3 mvCameraPos = mul(_CameraToMetavoxel, float4(0, 0, 0, 1)); // camera position along this ray (for soft particles) 239 | int tCamera = sqrt(dot(mvCameraPos - mvRay.o, mvCameraPos - mvRay.o)) / mvStepSize; 240 | tEntry = max(tEntry, tCamera); 241 | 242 | // loop variables 243 | float3 result = float3(0, 0, 0); 244 | float transmittance = 1.0f; 245 | float borderVoxelOffset = rcp(_NumVoxels) * _MetavoxelBorderSize; 246 | int samples = 0; 247 | int stepIndex; 248 | float3 mvRayStep = mvRay.d * mvStepSize, 249 | mvRayPos = mvRay.o + tExit * mvRayStep; 250 | 251 | // Sample uniformly in the opposite direction of the ray, starting from the current metavoxel's exit and stopping 252 | // once we hit the camera (or) are outside the metavoxel. 253 | // Samples are blended back-to-front. (This is orthogonal to the metavoxel raymarch blend mode, which is b/w metavoxels) 254 | for (stepIndex = tExit; stepIndex >= tEntry; stepIndex--) { 255 | float3 samplePos = mvRayPos + 0.5; //[-0.5, 0.5] -->[0, 1] 256 | 257 | // adjust for the metavoxel border -- the border voxels are only for filtering 258 | samplePos = samplePos * (1.0 - 2.0 * borderVoxelOffset) + borderVoxelOffset; // [0, 1] ---> [offset, 1 - offset] 259 | 260 | // supply 0 derivatives when sampling -- this ensures that the loop doesn't have to unrolled on SM 5.0 (hlsl) 261 | // due to a gradient instruction (such as tex3D) 262 | half4 voxelColor = tex3D(_VolumeTexture, samplePos, float3(0,0,0), float3(0,0,0)); 263 | half3 color = voxelColor.rgb; 264 | half density = voxelColor.a; 265 | 266 | // if samples are very close to the camera, make them more transparent (a la soft particles) 267 | if (stepIndex - tCamera < _SoftDistance) { 268 | // make less dense 269 | density *= (stepIndex - tCamera) * rcp(_SoftDistance); 270 | } 271 | 272 | half blendFactor = rcp(1.0 + density); 273 | 274 | result.rgb = lerp(color, result.rgb, blendFactor); 275 | transmittance *= blendFactor; 276 | 277 | mvRayPos -= mvRayStep; 278 | samples++; 279 | } 280 | 281 | 282 | // Another debug viewer to color code number of samples per ray for this metavoxel 283 | if (_ShowNumSamples == 1) { 284 | // Ray march steps per metavoxel caps the # of samples we'll make (64 for a 32-voxel-wide metavoxel => 2 samples per voxel) 285 | if (samples < 5) 286 | return green1; 287 | if (samples < 10) 288 | return green2; 289 | if (samples < 20) 290 | return yellow; 291 | if (samples < 30) 292 | return orange; 293 | if (samples < 40) 294 | return red; 295 | if (samples < 50) 296 | return red2; 297 | 298 | return red3; 299 | } 300 | 301 | return float4(result.rgb, 1 - transmittance); 302 | } // frag 303 | 304 | ENDCG 305 | } // Pass 306 | }FallBack Off 307 | } -------------------------------------------------------------------------------- /Assets/Shaders/Metavoxel/RayMarchVoxel.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c62d2fea6be6f2c4788c9ee70dbba3f1 3 | ShaderImporter: 4 | defaultTextures: [] 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Shaders/Sampling.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 49911b996f8f72e42b98bde144f5b867 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Shaders/Sampling/Sample2DTexture.shader: -------------------------------------------------------------------------------- 1 |  2 | Shader "Custom/Sample 2D Texture" { 3 | Properties{ 4 | _Plane("Plane Texture", 2D) = "blue" {} 5 | } 6 | SubShader{ 7 | Pass{ 8 | 9 | CGPROGRAM 10 | #pragma vertex vert 11 | #pragma fragment frag 12 | #pragma exclude_renderers flash gles 13 | 14 | #include "UnityCG.cginc" 15 | 16 | struct vs_input { 17 | float4 vertex : POSITION; 18 | float2 uv : TEXCOORD0; 19 | }; 20 | 21 | struct ps_input { 22 | float4 pos : SV_POSITION; 23 | float2 uv : TEXCOORD0; 24 | }; 25 | 26 | 27 | ps_input vert(vs_input v) 28 | { 29 | ps_input o; 30 | o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 31 | o.uv = v.uv; 32 | return o; 33 | } 34 | 35 | sampler2D _Plane; 36 | 37 | float4 frag(ps_input i) : COLOR 38 | { 39 | //return half4(0.3f, 0.0f, 0.5f, 1.0f); 40 | return tex2D(_Plane, i.uv); 41 | } 42 | 43 | ENDCG 44 | 45 | } 46 | } 47 | 48 | Fallback Off 49 | } 50 | -------------------------------------------------------------------------------- /Assets/Shaders/Sampling/Sample2DTexture.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a3ff4195c4a69de4d9726a59048ab258 3 | ShaderImporter: 4 | defaultTextures: [] 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Shaders/Sampling/Sample3DTexture.shader: -------------------------------------------------------------------------------- 1 |  2 | Shader "Custom/Sample 3D Texture" { 3 | Properties{ 4 | _Volume("Volume Texture", 3D) = "blue" {} 5 | } 6 | SubShader{ 7 | Pass{ 8 | 9 | CGPROGRAM 10 | #pragma vertex vert 11 | #pragma fragment frag 12 | #pragma exclude_renderers flash gles 13 | 14 | #include "UnityCG.cginc" 15 | 16 | struct vs_input { 17 | float4 vertex : POSITION; 18 | }; 19 | 20 | struct ps_input { 21 | float4 pos : SV_POSITION; 22 | float3 uv : TEXCOORD0; 23 | }; 24 | 25 | 26 | ps_input vert(vs_input v) 27 | { 28 | ps_input o; 29 | o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 30 | o.uv = v.vertex.xyz*0.5 + 0.5; 31 | return o; 32 | } 33 | 34 | sampler3D _Volume; 35 | 36 | float4 frag(ps_input i) : COLOR 37 | { 38 | //return fixed4(0.6f, 0.0f, 0.0f, 1.0f); 39 | return tex3D(_Volume, i.uv); 40 | } 41 | 42 | ENDCG 43 | 44 | } 45 | } 46 | 47 | Fallback Off 48 | } 49 | -------------------------------------------------------------------------------- /Assets/Shaders/Sampling/Sample3DTexture.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: caebc3aa1d7f8594097c035cf0df6176 3 | ShaderImporter: 4 | defaultTextures: [] 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Shaders/UAV Write.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9d2e28a0ee579014ea9118169e2e543c 3 | folderAsset: yes 4 | timeCreated: 1427155251 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Standard Assets.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 428af41a6fc7dc44ba85c3bbb007da8c 3 | folderAsset: yes 4 | timeCreated: 1427155251 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Standard Assets/CrossPlatformInput.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 33b1fd7b1fbc60b45bdee3dcf34cb708 3 | folderAsset: yes 4 | timeCreated: 1427155251 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Standard Assets/CrossPlatformInput/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4258a1ad4420d404fb9fa1bcf098748c 3 | folderAsset: yes 4 | timeCreated: 1427155251 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Standard Assets/CrossPlatformInput/Scripts/PlatformSpecific.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4b8611fd80025f344994eede1d2eaf4a 3 | folderAsset: yes 4 | timeCreated: 1427155251 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Standard Assets/ParticleSystems.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6961ee684b6cb6042a0a023249de8c74 3 | folderAsset: yes 4 | timeCreated: 1427155251 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Standard Assets/ParticleSystems/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 04ac662c675437942aca250e1972dd9c 3 | folderAsset: yes 4 | timeCreated: 1427155251 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Standard Assets/ParticleSystems/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f7be0473f7faf8949a17e6b63f710061 3 | folderAsset: yes 4 | timeCreated: 1427155251 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Standard Assets/Utility.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa3eb7021e259df49881bd1a323b898d 3 | folderAsset: yes 4 | timeCreated: 1427155251 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Textures.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1b0479b855bd50b4e831d763cc0f1452 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Textures/DisplacementTexture.cubemap.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 58fa667d98a6d2c4ca34acb0ad6bb945 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Textures/cm_c00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajabala/Volumetric-Particles-For-Unity/c2e975b01fdea772a63c6ce23559d25a00e453c3/Assets/Textures/cm_c00.png -------------------------------------------------------------------------------- /Assets/Textures/cm_c00.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6bc18dd7bff323b448dc9f492871b3f3 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | serializedVersion: 2 6 | mipmaps: 7 | mipMapMode: 0 8 | enableMipMap: 1 9 | linearTexture: 0 10 | correctGamma: 0 11 | fadeOut: 0 12 | borderMipMap: 0 13 | mipMapFadeDistanceStart: 1 14 | mipMapFadeDistanceEnd: 3 15 | bumpmap: 16 | convertToNormalMap: 0 17 | externalNormalMap: 0 18 | heightScale: .25 19 | normalMapFilter: 0 20 | isReadable: 0 21 | grayScaleToAlpha: 0 22 | generateCubemap: 0 23 | seamlessCubemap: 0 24 | textureFormat: -1 25 | maxTextureSize: 1024 26 | textureSettings: 27 | filterMode: -1 28 | aniso: -1 29 | mipBias: -1 30 | wrapMode: -1 31 | nPOTScale: 1 32 | lightmap: 0 33 | compressionQuality: 50 34 | spriteMode: 0 35 | spriteExtrude: 1 36 | spriteMeshType: 1 37 | alignment: 0 38 | spritePivot: {x: .5, y: .5} 39 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 40 | spritePixelsToUnits: 100 41 | alphaIsTransparency: 0 42 | textureType: -1 43 | buildTargetSettings: [] 44 | spriteSheet: 45 | sprites: [] 46 | spritePackingTag: 47 | userData: 48 | -------------------------------------------------------------------------------- /Assets/Textures/cm_c01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajabala/Volumetric-Particles-For-Unity/c2e975b01fdea772a63c6ce23559d25a00e453c3/Assets/Textures/cm_c01.png -------------------------------------------------------------------------------- /Assets/Textures/cm_c01.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 31bbff1c5949aec49b8bed679d892b22 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | serializedVersion: 2 6 | mipmaps: 7 | mipMapMode: 0 8 | enableMipMap: 1 9 | linearTexture: 0 10 | correctGamma: 0 11 | fadeOut: 0 12 | borderMipMap: 0 13 | mipMapFadeDistanceStart: 1 14 | mipMapFadeDistanceEnd: 3 15 | bumpmap: 16 | convertToNormalMap: 0 17 | externalNormalMap: 0 18 | heightScale: .25 19 | normalMapFilter: 0 20 | isReadable: 0 21 | grayScaleToAlpha: 0 22 | generateCubemap: 0 23 | seamlessCubemap: 0 24 | textureFormat: -1 25 | maxTextureSize: 1024 26 | textureSettings: 27 | filterMode: -1 28 | aniso: -1 29 | mipBias: -1 30 | wrapMode: -1 31 | nPOTScale: 1 32 | lightmap: 0 33 | compressionQuality: 50 34 | spriteMode: 0 35 | spriteExtrude: 1 36 | spriteMeshType: 1 37 | alignment: 0 38 | spritePivot: {x: .5, y: .5} 39 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 40 | spritePixelsToUnits: 100 41 | alphaIsTransparency: 0 42 | textureType: -1 43 | buildTargetSettings: [] 44 | spriteSheet: 45 | sprites: [] 46 | spritePackingTag: 47 | userData: 48 | -------------------------------------------------------------------------------- /Assets/Textures/cm_c02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajabala/Volumetric-Particles-For-Unity/c2e975b01fdea772a63c6ce23559d25a00e453c3/Assets/Textures/cm_c02.png -------------------------------------------------------------------------------- /Assets/Textures/cm_c02.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7dcdb1e674ca3d24e96ddef2c8906bca 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | serializedVersion: 2 6 | mipmaps: 7 | mipMapMode: 0 8 | enableMipMap: 1 9 | linearTexture: 0 10 | correctGamma: 0 11 | fadeOut: 0 12 | borderMipMap: 0 13 | mipMapFadeDistanceStart: 1 14 | mipMapFadeDistanceEnd: 3 15 | bumpmap: 16 | convertToNormalMap: 0 17 | externalNormalMap: 0 18 | heightScale: .25 19 | normalMapFilter: 0 20 | isReadable: 0 21 | grayScaleToAlpha: 0 22 | generateCubemap: 0 23 | seamlessCubemap: 0 24 | textureFormat: -1 25 | maxTextureSize: 1024 26 | textureSettings: 27 | filterMode: -1 28 | aniso: -1 29 | mipBias: -1 30 | wrapMode: -1 31 | nPOTScale: 1 32 | lightmap: 0 33 | compressionQuality: 50 34 | spriteMode: 0 35 | spriteExtrude: 1 36 | spriteMeshType: 1 37 | alignment: 0 38 | spritePivot: {x: .5, y: .5} 39 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 40 | spritePixelsToUnits: 100 41 | alphaIsTransparency: 0 42 | textureType: -1 43 | buildTargetSettings: [] 44 | spriteSheet: 45 | sprites: [] 46 | spritePackingTag: 47 | userData: 48 | -------------------------------------------------------------------------------- /Assets/Textures/cm_c03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajabala/Volumetric-Particles-For-Unity/c2e975b01fdea772a63c6ce23559d25a00e453c3/Assets/Textures/cm_c03.png -------------------------------------------------------------------------------- /Assets/Textures/cm_c03.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 158a5d7a3c2b5414fa51d4f38763da85 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | serializedVersion: 2 6 | mipmaps: 7 | mipMapMode: 0 8 | enableMipMap: 1 9 | linearTexture: 0 10 | correctGamma: 0 11 | fadeOut: 0 12 | borderMipMap: 0 13 | mipMapFadeDistanceStart: 1 14 | mipMapFadeDistanceEnd: 3 15 | bumpmap: 16 | convertToNormalMap: 0 17 | externalNormalMap: 0 18 | heightScale: .25 19 | normalMapFilter: 0 20 | isReadable: 0 21 | grayScaleToAlpha: 0 22 | generateCubemap: 0 23 | seamlessCubemap: 0 24 | textureFormat: -1 25 | maxTextureSize: 1024 26 | textureSettings: 27 | filterMode: -1 28 | aniso: -1 29 | mipBias: -1 30 | wrapMode: -1 31 | nPOTScale: 1 32 | lightmap: 0 33 | compressionQuality: 50 34 | spriteMode: 0 35 | spriteExtrude: 1 36 | spriteMeshType: 1 37 | alignment: 0 38 | spritePivot: {x: .5, y: .5} 39 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 40 | spritePixelsToUnits: 100 41 | alphaIsTransparency: 0 42 | textureType: -1 43 | buildTargetSettings: [] 44 | spriteSheet: 45 | sprites: [] 46 | spritePackingTag: 47 | userData: 48 | -------------------------------------------------------------------------------- /Assets/Textures/cm_c04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajabala/Volumetric-Particles-For-Unity/c2e975b01fdea772a63c6ce23559d25a00e453c3/Assets/Textures/cm_c04.png -------------------------------------------------------------------------------- /Assets/Textures/cm_c04.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5f7da7f9f3a08845be736bb95abd82f 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | serializedVersion: 2 6 | mipmaps: 7 | mipMapMode: 0 8 | enableMipMap: 1 9 | linearTexture: 0 10 | correctGamma: 0 11 | fadeOut: 0 12 | borderMipMap: 0 13 | mipMapFadeDistanceStart: 1 14 | mipMapFadeDistanceEnd: 3 15 | bumpmap: 16 | convertToNormalMap: 0 17 | externalNormalMap: 0 18 | heightScale: .25 19 | normalMapFilter: 0 20 | isReadable: 0 21 | grayScaleToAlpha: 0 22 | generateCubemap: 0 23 | seamlessCubemap: 0 24 | textureFormat: -1 25 | maxTextureSize: 1024 26 | textureSettings: 27 | filterMode: -1 28 | aniso: -1 29 | mipBias: -1 30 | wrapMode: -1 31 | nPOTScale: 1 32 | lightmap: 0 33 | compressionQuality: 50 34 | spriteMode: 0 35 | spriteExtrude: 1 36 | spriteMeshType: 1 37 | alignment: 0 38 | spritePivot: {x: .5, y: .5} 39 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 40 | spritePixelsToUnits: 100 41 | alphaIsTransparency: 0 42 | textureType: -1 43 | buildTargetSettings: [] 44 | spriteSheet: 45 | sprites: [] 46 | spritePackingTag: 47 | userData: 48 | -------------------------------------------------------------------------------- /Assets/Textures/cm_c05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajabala/Volumetric-Particles-For-Unity/c2e975b01fdea772a63c6ce23559d25a00e453c3/Assets/Textures/cm_c05.png -------------------------------------------------------------------------------- /Assets/Textures/cm_c05.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f34809c91c53f1a47834ffc1f815f221 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | serializedVersion: 2 6 | mipmaps: 7 | mipMapMode: 0 8 | enableMipMap: 1 9 | linearTexture: 0 10 | correctGamma: 0 11 | fadeOut: 0 12 | borderMipMap: 0 13 | mipMapFadeDistanceStart: 1 14 | mipMapFadeDistanceEnd: 3 15 | bumpmap: 16 | convertToNormalMap: 0 17 | externalNormalMap: 0 18 | heightScale: .25 19 | normalMapFilter: 0 20 | isReadable: 0 21 | grayScaleToAlpha: 0 22 | generateCubemap: 0 23 | seamlessCubemap: 0 24 | textureFormat: -1 25 | maxTextureSize: 1024 26 | textureSettings: 27 | filterMode: -1 28 | aniso: -1 29 | mipBias: -1 30 | wrapMode: -1 31 | nPOTScale: 1 32 | lightmap: 0 33 | compressionQuality: 50 34 | spriteMode: 0 35 | spriteExtrude: 1 36 | spriteMeshType: 1 37 | alignment: 0 38 | spritePivot: {x: .5, y: .5} 39 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 40 | spritePixelsToUnits: 100 41 | alphaIsTransparency: 0 42 | textureType: -1 43 | buildTargetSettings: [] 44 | spriteSheet: 45 | sprites: [] 46 | spritePackingTag: 47 | userData: 48 | -------------------------------------------------------------------------------- /Assets/Textures/explosionramp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajabala/Volumetric-Particles-For-Unity/c2e975b01fdea772a63c6ce23559d25a00e453c3/Assets/Textures/explosionramp.png -------------------------------------------------------------------------------- /Assets/Textures/explosionramp.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f812e38977347943b92138e13876fd5 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | serializedVersion: 2 6 | mipmaps: 7 | mipMapMode: 0 8 | enableMipMap: 1 9 | linearTexture: 0 10 | correctGamma: 0 11 | fadeOut: 0 12 | borderMipMap: 0 13 | mipMapFadeDistanceStart: 1 14 | mipMapFadeDistanceEnd: 3 15 | bumpmap: 16 | convertToNormalMap: 0 17 | externalNormalMap: 0 18 | heightScale: .25 19 | normalMapFilter: 0 20 | isReadable: 0 21 | grayScaleToAlpha: 0 22 | generateCubemap: 0 23 | seamlessCubemap: 0 24 | textureFormat: -1 25 | maxTextureSize: 1024 26 | textureSettings: 27 | filterMode: -1 28 | aniso: -1 29 | mipBias: -1 30 | wrapMode: -1 31 | nPOTScale: 1 32 | lightmap: 0 33 | compressionQuality: 50 34 | spriteMode: 0 35 | spriteExtrude: 1 36 | spriteMeshType: 1 37 | alignment: 0 38 | spritePivot: {x: .5, y: .5} 39 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 40 | spritePixelsToUnits: 100 41 | alphaIsTransparency: 0 42 | textureType: -1 43 | buildTargetSettings: [] 44 | spriteSheet: 45 | sprites: [] 46 | spritePackingTag: 47 | userData: 48 | -------------------------------------------------------------------------------- /Assets/UnityVS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 02fe78e962405814a83b8ba6c9471d32 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnityVS/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6e71a3e2fb5854e43823a9da25b68e21 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/UnityVS/Editor/SyntaxTree.VisualStudio.Unity.Bridge.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajabala/Volumetric-Particles-For-Unity/c2e975b01fdea772a63c6ce23559d25a00e453c3/Assets/UnityVS/Editor/SyntaxTree.VisualStudio.Unity.Bridge.dll -------------------------------------------------------------------------------- /Assets/UnityVS/Editor/SyntaxTree.VisualStudio.Unity.Bridge.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 38d405c119fcc7c4e83d4a478a40ff2f 3 | MonoAssemblyImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | userData: 8 | -------------------------------------------------------------------------------- /Assets/UnityVS/Editor/SyntaxTree.VisualStudio.Unity.Messaging.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajabala/Volumetric-Particles-For-Unity/c2e975b01fdea772a63c6ce23559d25a00e453c3/Assets/UnityVS/Editor/SyntaxTree.VisualStudio.Unity.Messaging.dll -------------------------------------------------------------------------------- /Assets/UnityVS/Editor/SyntaxTree.VisualStudio.Unity.Messaging.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4ad02dc83da735c4e8d945332b9202f6 3 | MonoAssemblyImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | userData: 8 | -------------------------------------------------------------------------------- /Assets/UnityVS/Editor/UnityVS.VersionSpecific.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajabala/Volumetric-Particles-For-Unity/c2e975b01fdea772a63c6ce23559d25a00e453c3/Assets/UnityVS/Editor/UnityVS.VersionSpecific.dll -------------------------------------------------------------------------------- /Assets/UnityVS/Editor/UnityVS.VersionSpecific.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 389d855b601ff4046a3e045516b019bb 3 | timeCreated: 1426061976 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Any: 12 | enabled: 0 13 | settings: {} 14 | Editor: 15 | enabled: 1 16 | settings: 17 | DefaultValueInitialized: true 18 | userData: 19 | assetBundleName: 20 | assetBundleVariant: 21 | -------------------------------------------------------------------------------- /Assets/Volumetric_Particle_System.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba62690ff438410488e38c5713a2f834 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | m_SpeedOfSound: 347 9 | Doppler Factor: 1 10 | Default Speaker Mode: 2 11 | m_DSPBufferSize: 0 12 | m_DisableAudio: 0 13 | -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | m_Gravity: {x: 0, y: -9.81000042, z: 0} 7 | m_DefaultMaterial: {fileID: 0} 8 | m_BounceThreshold: 2 9 | m_SleepVelocity: .150000006 10 | m_SleepAngularVelocity: .140000001 11 | m_MaxAngularVelocity: 7 12 | m_MinPenetrationForPenalty: .00999999978 13 | m_SolverIterationCount: 6 14 | m_RaycastsHitTriggers: 1 15 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 16 | -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/Volumetric_Particle_System.unity 10 | -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 3 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_WebSecurityEmulationEnabled: 0 10 | m_WebSecurityEmulationHostUrl: http://www.mydomain.com/mygame.unity3d 11 | m_DefaultBehaviorMode: 0 12 | m_SpritePackerMode: 0 13 | -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 3 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_LegacyDeferred: 11 | m_Mode: 1 12 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 13 | m_AlwaysIncludedShaders: 14 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 15 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 16 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 17 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 18 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 19 | - {fileID: 10782, guid: 0000000000000000f000000000000000, type: 0} 20 | m_PreloadedShaders: [] 21 | m_LightmapStripping: 0 22 | m_LightmapKeepPlain: 1 23 | m_LightmapKeepDirCombined: 1 24 | m_LightmapKeepDirSeparate: 1 25 | m_LightmapKeepDynamic: 1 26 | m_FogStripping: 0 27 | m_FogKeepLinear: 1 28 | m_FogKeepExp: 1 29 | m_FogKeepExp2: 1 30 | -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | m_Axes: 7 | - serializedVersion: 3 8 | m_Name: Horizontal 9 | descriptiveName: 10 | descriptiveNegativeName: 11 | negativeButton: left 12 | positiveButton: right 13 | altNegativeButton: a 14 | altPositiveButton: d 15 | gravity: 3 16 | dead: .00100000005 17 | sensitivity: 3 18 | snap: 1 19 | invert: 0 20 | type: 0 21 | axis: 0 22 | joyNum: 0 23 | - serializedVersion: 3 24 | m_Name: Vertical 25 | descriptiveName: 26 | descriptiveNegativeName: 27 | negativeButton: down 28 | positiveButton: up 29 | altNegativeButton: s 30 | altPositiveButton: w 31 | gravity: 3 32 | dead: .00100000005 33 | sensitivity: 3 34 | snap: 1 35 | invert: 0 36 | type: 0 37 | axis: 0 38 | joyNum: 0 39 | - serializedVersion: 3 40 | m_Name: Fire1 41 | descriptiveName: 42 | descriptiveNegativeName: 43 | negativeButton: 44 | positiveButton: left ctrl 45 | altNegativeButton: 46 | altPositiveButton: mouse 0 47 | gravity: 1000 48 | dead: .00100000005 49 | sensitivity: 1000 50 | snap: 0 51 | invert: 0 52 | type: 0 53 | axis: 0 54 | joyNum: 0 55 | - serializedVersion: 3 56 | m_Name: Fire2 57 | descriptiveName: 58 | descriptiveNegativeName: 59 | negativeButton: 60 | positiveButton: left alt 61 | altNegativeButton: 62 | altPositiveButton: mouse 1 63 | gravity: 1000 64 | dead: .00100000005 65 | sensitivity: 1000 66 | snap: 0 67 | invert: 0 68 | type: 0 69 | axis: 0 70 | joyNum: 0 71 | - serializedVersion: 3 72 | m_Name: Fire3 73 | descriptiveName: 74 | descriptiveNegativeName: 75 | negativeButton: 76 | positiveButton: left cmd 77 | altNegativeButton: 78 | altPositiveButton: mouse 2 79 | gravity: 1000 80 | dead: .00100000005 81 | sensitivity: 1000 82 | snap: 0 83 | invert: 0 84 | type: 0 85 | axis: 0 86 | joyNum: 0 87 | - serializedVersion: 3 88 | m_Name: Jump 89 | descriptiveName: 90 | descriptiveNegativeName: 91 | negativeButton: 92 | positiveButton: space 93 | altNegativeButton: 94 | altPositiveButton: 95 | gravity: 1000 96 | dead: .00100000005 97 | sensitivity: 1000 98 | snap: 0 99 | invert: 0 100 | type: 0 101 | axis: 0 102 | joyNum: 0 103 | - serializedVersion: 3 104 | m_Name: Mouse X 105 | descriptiveName: 106 | descriptiveNegativeName: 107 | negativeButton: 108 | positiveButton: 109 | altNegativeButton: 110 | altPositiveButton: 111 | gravity: 0 112 | dead: 0 113 | sensitivity: .100000001 114 | snap: 0 115 | invert: 0 116 | type: 1 117 | axis: 0 118 | joyNum: 0 119 | - serializedVersion: 3 120 | m_Name: Mouse Y 121 | descriptiveName: 122 | descriptiveNegativeName: 123 | negativeButton: 124 | positiveButton: 125 | altNegativeButton: 126 | altPositiveButton: 127 | gravity: 0 128 | dead: 0 129 | sensitivity: .100000001 130 | snap: 0 131 | invert: 0 132 | type: 1 133 | axis: 1 134 | joyNum: 0 135 | - serializedVersion: 3 136 | m_Name: Mouse ScrollWheel 137 | descriptiveName: 138 | descriptiveNegativeName: 139 | negativeButton: 140 | positiveButton: 141 | altNegativeButton: 142 | altPositiveButton: 143 | gravity: 0 144 | dead: 0 145 | sensitivity: .100000001 146 | snap: 0 147 | invert: 0 148 | type: 1 149 | axis: 2 150 | joyNum: 0 151 | - serializedVersion: 3 152 | m_Name: Horizontal 153 | descriptiveName: 154 | descriptiveNegativeName: 155 | negativeButton: 156 | positiveButton: 157 | altNegativeButton: 158 | altPositiveButton: 159 | gravity: 0 160 | dead: .189999998 161 | sensitivity: 1 162 | snap: 0 163 | invert: 0 164 | type: 2 165 | axis: 0 166 | joyNum: 0 167 | - serializedVersion: 3 168 | m_Name: Vertical 169 | descriptiveName: 170 | descriptiveNegativeName: 171 | negativeButton: 172 | positiveButton: 173 | altNegativeButton: 174 | altPositiveButton: 175 | gravity: 0 176 | dead: .189999998 177 | sensitivity: 1 178 | snap: 0 179 | invert: 1 180 | type: 2 181 | axis: 1 182 | joyNum: 0 183 | - serializedVersion: 3 184 | m_Name: Fire1 185 | descriptiveName: 186 | descriptiveNegativeName: 187 | negativeButton: 188 | positiveButton: joystick button 0 189 | altNegativeButton: 190 | altPositiveButton: 191 | gravity: 1000 192 | dead: .00100000005 193 | sensitivity: 1000 194 | snap: 0 195 | invert: 0 196 | type: 0 197 | axis: 0 198 | joyNum: 0 199 | - serializedVersion: 3 200 | m_Name: Fire2 201 | descriptiveName: 202 | descriptiveNegativeName: 203 | negativeButton: 204 | positiveButton: joystick button 1 205 | altNegativeButton: 206 | altPositiveButton: 207 | gravity: 1000 208 | dead: .00100000005 209 | sensitivity: 1000 210 | snap: 0 211 | invert: 0 212 | type: 0 213 | axis: 0 214 | joyNum: 0 215 | - serializedVersion: 3 216 | m_Name: Fire3 217 | descriptiveName: 218 | descriptiveNegativeName: 219 | negativeButton: 220 | positiveButton: joystick button 2 221 | altNegativeButton: 222 | altPositiveButton: 223 | gravity: 1000 224 | dead: .00100000005 225 | sensitivity: 1000 226 | snap: 0 227 | invert: 0 228 | type: 0 229 | axis: 0 230 | joyNum: 0 231 | - serializedVersion: 3 232 | m_Name: Jump 233 | descriptiveName: 234 | descriptiveNegativeName: 235 | negativeButton: 236 | positiveButton: joystick button 3 237 | altNegativeButton: 238 | altPositiveButton: 239 | gravity: 1000 240 | dead: .00100000005 241 | sensitivity: 1000 242 | snap: 0 243 | invert: 0 244 | type: 0 245 | axis: 0 246 | joyNum: 0 247 | -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshLayers: 5 | m_ObjectHideFlags: 0 6 | Built-in Layer 0: 7 | name: Default 8 | cost: 1 9 | editType: 2 10 | Built-in Layer 1: 11 | name: Not Walkable 12 | cost: 1 13 | editType: 0 14 | Built-in Layer 2: 15 | name: Jump 16 | cost: 2 17 | editType: 2 18 | User Layer 0: 19 | name: 20 | cost: 1 21 | editType: 3 22 | User Layer 1: 23 | name: 24 | cost: 1 25 | editType: 3 26 | User Layer 2: 27 | name: 28 | cost: 1 29 | editType: 3 30 | User Layer 3: 31 | name: 32 | cost: 1 33 | editType: 3 34 | User Layer 4: 35 | name: 36 | cost: 1 37 | editType: 3 38 | User Layer 5: 39 | name: 40 | cost: 1 41 | editType: 3 42 | User Layer 6: 43 | name: 44 | cost: 1 45 | editType: 3 46 | User Layer 7: 47 | name: 48 | cost: 1 49 | editType: 3 50 | User Layer 8: 51 | name: 52 | cost: 1 53 | editType: 3 54 | User Layer 9: 55 | name: 56 | cost: 1 57 | editType: 3 58 | User Layer 10: 59 | name: 60 | cost: 1 61 | editType: 3 62 | User Layer 11: 63 | name: 64 | cost: 1 65 | editType: 3 66 | User Layer 12: 67 | name: 68 | cost: 1 69 | editType: 3 70 | User Layer 13: 71 | name: 72 | cost: 1 73 | editType: 3 74 | User Layer 14: 75 | name: 76 | cost: 1 77 | editType: 3 78 | User Layer 15: 79 | name: 80 | cost: 1 81 | editType: 3 82 | User Layer 16: 83 | name: 84 | cost: 1 85 | editType: 3 86 | User Layer 17: 87 | name: 88 | cost: 1 89 | editType: 3 90 | User Layer 18: 91 | name: 92 | cost: 1 93 | editType: 3 94 | User Layer 19: 95 | name: 96 | cost: 1 97 | editType: 3 98 | User Layer 20: 99 | name: 100 | cost: 1 101 | editType: 3 102 | User Layer 21: 103 | name: 104 | cost: 1 105 | editType: 3 106 | User Layer 22: 107 | name: 108 | cost: 1 109 | editType: 3 110 | User Layer 23: 111 | name: 112 | cost: 1 113 | editType: 3 114 | User Layer 24: 115 | name: 116 | cost: 1 117 | editType: 3 118 | User Layer 25: 119 | name: 120 | cost: 1 121 | editType: 3 122 | User Layer 26: 123 | name: 124 | cost: 1 125 | editType: 3 126 | User Layer 27: 127 | name: 128 | cost: 1 129 | editType: 3 130 | User Layer 28: 131 | name: 132 | cost: 1 133 | editType: 3 134 | -------------------------------------------------------------------------------- /ProjectSettings/NavMeshLayers.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshLayers: 5 | m_ObjectHideFlags: 0 6 | Built-in Layer 0: 7 | name: Default 8 | cost: 1 9 | editType: 2 10 | Built-in Layer 1: 11 | name: Not Walkable 12 | cost: 1 13 | editType: 0 14 | Built-in Layer 2: 15 | name: Jump 16 | cost: 2 17 | editType: 2 18 | User Layer 0: 19 | name: 20 | cost: 1 21 | editType: 3 22 | User Layer 1: 23 | name: 24 | cost: 1 25 | editType: 3 26 | User Layer 2: 27 | name: 28 | cost: 1 29 | editType: 3 30 | User Layer 3: 31 | name: 32 | cost: 1 33 | editType: 3 34 | User Layer 4: 35 | name: 36 | cost: 1 37 | editType: 3 38 | User Layer 5: 39 | name: 40 | cost: 1 41 | editType: 3 42 | User Layer 6: 43 | name: 44 | cost: 1 45 | editType: 3 46 | User Layer 7: 47 | name: 48 | cost: 1 49 | editType: 3 50 | User Layer 8: 51 | name: 52 | cost: 1 53 | editType: 3 54 | User Layer 9: 55 | name: 56 | cost: 1 57 | editType: 3 58 | User Layer 10: 59 | name: 60 | cost: 1 61 | editType: 3 62 | User Layer 11: 63 | name: 64 | cost: 1 65 | editType: 3 66 | User Layer 12: 67 | name: 68 | cost: 1 69 | editType: 3 70 | User Layer 13: 71 | name: 72 | cost: 1 73 | editType: 3 74 | User Layer 14: 75 | name: 76 | cost: 1 77 | editType: 3 78 | User Layer 15: 79 | name: 80 | cost: 1 81 | editType: 3 82 | User Layer 16: 83 | name: 84 | cost: 1 85 | editType: 3 86 | User Layer 17: 87 | name: 88 | cost: 1 89 | editType: 3 90 | User Layer 18: 91 | name: 92 | cost: 1 93 | editType: 3 94 | User Layer 19: 95 | name: 96 | cost: 1 97 | editType: 3 98 | User Layer 20: 99 | name: 100 | cost: 1 101 | editType: 3 102 | User Layer 21: 103 | name: 104 | cost: 1 105 | editType: 3 106 | User Layer 22: 107 | name: 108 | cost: 1 109 | editType: 3 110 | User Layer 23: 111 | name: 112 | cost: 1 113 | editType: 3 114 | User Layer 24: 115 | name: 116 | cost: 1 117 | editType: 3 118 | User Layer 25: 119 | name: 120 | cost: 1 121 | editType: 3 122 | User Layer 26: 123 | name: 124 | cost: 1 125 | editType: 3 126 | User Layer 27: 127 | name: 128 | cost: 1 129 | editType: 3 130 | User Layer 28: 131 | name: 132 | cost: 1 133 | editType: 3 134 | -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!149 &1 4 | NetworkManager: 5 | m_ObjectHideFlags: 0 6 | m_DebugLevel: 0 7 | m_Sendrate: 15 8 | m_AssetToPrefab: {} 9 | -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | m_Gravity: {x: 0, y: -9.81000042} 7 | m_DefaultMaterial: {fileID: 0} 8 | m_VelocityIterations: 8 9 | m_PositionIterations: 3 10 | m_VelocityThreshold: 1 11 | m_MaxLinearCorrection: .200000003 12 | m_MaxAngularCorrection: 8 13 | m_MaxTranslationSpeed: 100 14 | m_MaxRotationSpeed: 360 15 | m_BaumgarteScale: .200000003 16 | m_BaumgarteTimeOfImpactScale: .75 17 | m_TimeToSleep: .5 18 | m_LinearSleepTolerance: .00999999978 19 | m_AngularSleepTolerance: 2 20 | m_RaycastsHitTriggers: 1 21 | m_DeleteStopsCallbacks: 1 22 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 23 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!129 &1 4 | PlayerSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 6 7 | AndroidProfiler: 0 8 | defaultScreenOrientation: 4 9 | targetDevice: 2 10 | targetGlesGraphics: 2 11 | targetIOSGraphics: -1 12 | targetResolution: 0 13 | accelerometerFrequency: 60 14 | companyName: Intel 15 | productName: Sparse Volumetric Particle System Demo 16 | cloudProjectId: 17 | defaultCursor: {fileID: 0} 18 | cursorHotspot: {x: 0, y: 0} 19 | defaultScreenWidth: 1024 20 | defaultScreenHeight: 768 21 | defaultScreenWidthWeb: 960 22 | defaultScreenHeightWeb: 600 23 | m_RenderingPath: 1 24 | m_MobileRenderingPath: 1 25 | m_ActiveColorSpace: 0 26 | m_MTRendering: 1 27 | m_MobileMTRendering: 0 28 | m_UseDX11: 1 29 | m_Stereoscopic3D: 0 30 | iosShowActivityIndicatorOnLoading: -1 31 | androidShowActivityIndicatorOnLoading: -1 32 | iosAppInBackgroundBehavior: 0 33 | displayResolutionDialog: 1 34 | allowedAutorotateToPortrait: 1 35 | allowedAutorotateToPortraitUpsideDown: 1 36 | allowedAutorotateToLandscapeRight: 1 37 | allowedAutorotateToLandscapeLeft: 1 38 | useOSAutorotation: 1 39 | use32BitDisplayBuffer: 1 40 | disableDepthAndStencilBuffers: 0 41 | defaultIsFullScreen: 0 42 | defaultIsNativeResolution: 1 43 | runInBackground: 1 44 | captureSingleScreen: 0 45 | Override IPod Music: 0 46 | Prepare IOS For Recording: 0 47 | submitAnalytics: 1 48 | usePlayerLog: 1 49 | bakeCollisionMeshes: 0 50 | forceSingleInstance: 0 51 | resizableWindow: 0 52 | useMacAppStoreValidation: 0 53 | gpuSkinning: 0 54 | xboxPIXTextureCapture: 0 55 | xboxEnableAvatar: 0 56 | xboxEnableKinect: 0 57 | xboxEnableKinectAutoTracking: 0 58 | xboxEnableFitness: 0 59 | visibleInBackground: 0 60 | macFullscreenMode: 2 61 | d3d9FullscreenMode: 1 62 | d3d11FullscreenMode: 1 63 | xboxSpeechDB: 0 64 | xboxEnableHeadOrientation: 0 65 | xboxEnableGuest: 0 66 | xboxOneResolution: 0 67 | ps3SplashScreen: {fileID: 0} 68 | videoMemoryForVertexBuffers: 0 69 | psp2PowerMode: 0 70 | psp2AcquireBGM: 1 71 | m_SupportedAspectRatios: 72 | 4:3: 1 73 | 5:4: 1 74 | 16:10: 1 75 | 16:9: 1 76 | Others: 1 77 | bundleIdentifier: com.intel.svpr 78 | bundleVersion: 1.0 79 | preloadedAssets: [] 80 | metroEnableIndependentInputSource: 0 81 | metroEnableLowLatencyPresentationAPI: 0 82 | xboxOneDisableKinectGpuReservation: 0 83 | productGUID: 2956ed3f17b4ad2448266aca84b406f3 84 | AndroidBundleVersionCode: 1 85 | AndroidMinSdkVersion: 19 86 | AndroidPreferredInstallLocation: 1 87 | aotOptions: 88 | apiCompatibilityLevel: 2 89 | iPhoneStrippingLevel: 0 90 | iPhoneScriptCallOptimization: 0 91 | ForceInternetPermission: 0 92 | ForceSDCardPermission: 0 93 | CreateWallpaper: 0 94 | APKExpansionFiles: 0 95 | preloadShaders: 0 96 | StripUnusedMeshComponents: 0 97 | iPhoneSdkVersion: 988 98 | iPhoneTargetOSVersion: 22 99 | uIPrerenderedIcon: 0 100 | uIRequiresPersistentWiFi: 0 101 | uIStatusBarHidden: 1 102 | uIExitOnSuspend: 0 103 | uIStatusBarStyle: 0 104 | iPhoneSplashScreen: {fileID: 0} 105 | iPhoneHighResSplashScreen: {fileID: 0} 106 | iPhoneTallHighResSplashScreen: {fileID: 0} 107 | iPhone47inSplashScreen: {fileID: 0} 108 | iPhone55inPortraitSplashScreen: {fileID: 0} 109 | iPhone55inLandscapeSplashScreen: {fileID: 0} 110 | iPadPortraitSplashScreen: {fileID: 0} 111 | iPadHighResPortraitSplashScreen: {fileID: 0} 112 | iPadLandscapeSplashScreen: {fileID: 0} 113 | iPadHighResLandscapeSplashScreen: {fileID: 0} 114 | iOSLaunchScreenType: 0 115 | iOSLaunchScreenPortrait: {fileID: 0} 116 | iOSLaunchScreenLandscape: {fileID: 0} 117 | iOSLaunchScreenBackgroundColor: 118 | serializedVersion: 2 119 | rgba: 0 120 | iOSLaunchScreenFillPct: 1 121 | iOSLaunchScreenCustomXibPath: 122 | AndroidTargetDevice: 0 123 | AndroidSplashScreenScale: 0 124 | AndroidKeystoreName: 125 | AndroidKeyaliasName: 126 | AndroidTVCompatibility: 1 127 | AndroidIsGame: 0 128 | androidEnableBanner: 1 129 | m_AndroidBanners: 130 | - width: 320 131 | height: 180 132 | banner: {fileID: 0} 133 | resolutionDialogBanner: {fileID: 2800000, guid: 6bc18dd7bff323b448dc9f492871b3f3, 134 | type: 3} 135 | m_BuildTargetIcons: 136 | - m_BuildTarget: 137 | m_Icons: 138 | - m_Icon: {fileID: 2800000, guid: 6bc18dd7bff323b448dc9f492871b3f3, type: 3} 139 | m_Size: 128 140 | - m_BuildTarget: Standalone 141 | m_Icons: 142 | - m_Icon: {fileID: 0} 143 | m_Size: 1024 144 | - m_Icon: {fileID: 0} 145 | m_Size: 512 146 | - m_Icon: {fileID: 0} 147 | m_Size: 256 148 | - m_Icon: {fileID: 0} 149 | m_Size: 128 150 | - m_Icon: {fileID: 0} 151 | m_Size: 48 152 | - m_Icon: {fileID: 2800000, guid: 6bc18dd7bff323b448dc9f492871b3f3, type: 3} 153 | m_Size: 32 154 | - m_Icon: {fileID: 0} 155 | m_Size: 16 156 | m_BuildTargetBatching: 157 | - m_BuildTarget: Standalone 158 | m_StaticBatching: 1 159 | m_DynamicBatching: 1 160 | webPlayerTemplate: APPLICATION:Default 161 | m_TemplateCustomTags: {} 162 | actionOnDotNetUnhandledException: 1 163 | enableInternalProfiler: 0 164 | logObjCUncaughtExceptions: 1 165 | enableCrashReportAPI: 0 166 | locationUsageDescription: 167 | XboxTitleId: 168 | XboxImageXexPath: 169 | XboxSpaPath: 170 | XboxGenerateSpa: 0 171 | XboxDeployKinectResources: 0 172 | XboxSplashScreen: {fileID: 0} 173 | xboxEnableSpeech: 0 174 | xboxAdditionalTitleMemorySize: 0 175 | xboxDeployKinectHeadOrientation: 0 176 | xboxDeployKinectHeadPosition: 0 177 | ps3TitleConfigPath: 178 | ps3DLCConfigPath: 179 | ps3ThumbnailPath: 180 | ps3BackgroundPath: 181 | ps3SoundPath: 182 | ps3NPAgeRating: 12 183 | ps3TrophyCommId: 184 | ps3NpCommunicationPassphrase: 185 | ps3TrophyPackagePath: 186 | ps3BootCheckMaxSaveGameSizeKB: 128 187 | ps3TrophyCommSig: 188 | ps3SaveGameSlots: 1 189 | ps3TrialMode: 0 190 | ps3VideoMemoryForAudio: 0 191 | ps3EnableVerboseMemoryStats: 0 192 | ps3UseSPUForUmbra: 0 193 | ps3EnableMoveSupport: 1 194 | ps3DisableDolbyEncoding: 0 195 | ps4NPAgeRating: 12 196 | ps4NPTitleSecret: 197 | ps4NPTrophyPackPath: 198 | ps4ParentalLevel: 1 199 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000 200 | ps4Category: 0 201 | ps4MasterVersion: 01.00 202 | ps4AppVersion: 01.00 203 | ps4AppType: 0 204 | ps4ParamSfxPath: 205 | ps4VideoOutPixelFormat: 0 206 | ps4VideoOutResolution: 4 207 | ps4PronunciationXMLPath: 208 | ps4PronunciationSIGPath: 209 | ps4BackgroundImagePath: 210 | ps4StartupImagePath: 211 | ps4SaveDataImagePath: 212 | ps4BGMPath: 213 | ps4ShareFilePath: 214 | ps4NPtitleDatPath: 215 | ps4RemotePlayKeyAssignment: -1 216 | ps4EnterButtonAssignment: 1 217 | ps4ApplicationParam1: 0 218 | ps4ApplicationParam2: 0 219 | ps4ApplicationParam3: 0 220 | ps4ApplicationParam4: 0 221 | ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ 222 | ps4pnSessions: 1 223 | ps4pnPresence: 1 224 | ps4pnFriends: 1 225 | ps4pnGameCustomData: 1 226 | playerPrefsSupport: 0 227 | monoEnv: 228 | psp2Splashimage: {fileID: 0} 229 | psp2NPTrophyPackPath: 230 | psp2NPSupportGBMorGJP: 0 231 | psp2NPAgeRating: 12 232 | psp2NPCommsID: 233 | psp2NPCommunicationsID: 234 | psp2NPCommsPassphrase: 235 | psp2NPCommsSig: 236 | psp2ParamSfxPath: 237 | psp2ManualPath: 238 | psp2LiveAreaGatePath: 239 | psp2LiveAreaBackroundPath: 240 | psp2LiveAreaPath: 241 | psp2LiveAreaTrialPath: 242 | psp2PatchChangeInfoPath: 243 | psp2PatchOriginalPackage: 244 | psp2PackagePassword: 245 | psp2KeystoneFile: 246 | psp2DRMType: 0 247 | psp2StorageType: 0 248 | psp2MediaCapacity: 0 249 | psp2DLCConfigPath: 250 | psp2ThumbnailPath: 251 | psp2BackgroundPath: 252 | psp2SoundPath: 253 | psp2TrophyCommId: 254 | psp2TrophyPackagePath: 255 | psp2PackagedResourcesPath: 256 | psp2SaveDataQuota: 10240 257 | psp2ParentalLevel: 1 258 | psp2ShortTitle: Not Set 259 | psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF 260 | psp2Category: 0 261 | psp2MasterVersion: 01.00 262 | psp2AppVersion: 01.00 263 | psp2TVBootMode: 0 264 | psp2EnterButtonAssignment: 2 265 | psp2TVDisableEmu: 0 266 | psp2AllowTwitterDialog: 1 267 | psp2Upgradable: 0 268 | psp2HealthWarning: 0 269 | psp2UseLibLocation: 0 270 | psp2InfoBarOnStartup: 0 271 | psp2InfoBarColor: 0 272 | psmSplashimage: {fileID: 0} 273 | spritePackerPolicy: 274 | scriptingDefineSymbols: 275 | 1: CROSS_PLATFORM_INPUT 276 | 2: CROSS_PLATFORM_INPUT 277 | 4: CROSS_PLATFORM_INPUT;MOBILE_INPUT 278 | 7: CROSS_PLATFORM_INPUT;MOBILE_INPUT 279 | 14: MOBILE_INPUT 280 | 15: CROSS_PLATFORM_INPUT;MOBILE_INPUT 281 | 16: CROSS_PLATFORM_INPUT;MOBILE_INPUT 282 | 17: MOBILE_INPUT 283 | 20: MOBILE_INPUT 284 | metroPackageName: Sparse Volumetric Particle System 285 | metroPackageLogo: 286 | metroPackageLogo140: 287 | metroPackageLogo180: 288 | metroPackageLogo240: 289 | metroPackageVersion: 290 | metroCertificatePath: 291 | metroCertificatePassword: 292 | metroCertificateSubject: 293 | metroCertificateIssuer: 294 | metroCertificateNotAfter: 0000000000000000 295 | metroApplicationDescription: Sparse Volumetric Particle System 296 | metroStoreTileLogo80: 297 | metroStoreTileLogo: 298 | metroStoreTileLogo140: 299 | metroStoreTileLogo180: 300 | metroStoreTileWideLogo80: 301 | metroStoreTileWideLogo: 302 | metroStoreTileWideLogo140: 303 | metroStoreTileWideLogo180: 304 | metroStoreTileSmallLogo80: 305 | metroStoreTileSmallLogo: 306 | metroStoreTileSmallLogo140: 307 | metroStoreTileSmallLogo180: 308 | metroStoreSmallTile80: 309 | metroStoreSmallTile: 310 | metroStoreSmallTile140: 311 | metroStoreSmallTile180: 312 | metroStoreLargeTile80: 313 | metroStoreLargeTile: 314 | metroStoreLargeTile140: 315 | metroStoreLargeTile180: 316 | metroStoreSplashScreenImage: 317 | metroStoreSplashScreenImage140: 318 | metroStoreSplashScreenImage180: 319 | metroPhoneAppIcon: 320 | metroPhoneAppIcon140: 321 | metroPhoneAppIcon240: 322 | metroPhoneSmallTile: 323 | metroPhoneSmallTile140: 324 | metroPhoneSmallTile240: 325 | metroPhoneMediumTile: 326 | metroPhoneMediumTile140: 327 | metroPhoneMediumTile240: 328 | metroPhoneWideTile: 329 | metroPhoneWideTile140: 330 | metroPhoneWideTile240: 331 | metroPhoneSplashScreenImage: 332 | metroPhoneSplashScreenImage140: 333 | metroPhoneSplashScreenImage240: 334 | metroTileShortName: Sparse Volume 335 | metroCommandLineArgsFile: 336 | metroTileShowName: 0 337 | metroMediumTileShowName: 0 338 | metroLargeTileShowName: 0 339 | metroWideTileShowName: 0 340 | metroDefaultTileSize: 1 341 | metroTileForegroundText: 1 342 | metroTileBackgroundColor: {r: 0, g: 0, b: 0, a: 1} 343 | metroSplashScreenBackgroundColor: {r: 0, g: 0, b: 0, a: 1} 344 | metroSplashScreenUseBackgroundColor: 0 345 | platformCapabilities: {} 346 | metroFTAName: 347 | metroFTAFileTypes: [] 348 | metroProtocolName: 349 | metroCompilationOverrides: 1 350 | blackberryDeviceAddress: 351 | blackberryDevicePassword: 352 | blackberryTokenPath: 353 | blackberryTokenExires: 354 | blackberryTokenAuthor: 355 | blackberryTokenAuthorId: 356 | blackberryCskPassword: 357 | blackberrySaveLogPath: 358 | blackberrySharedPermissions: 0 359 | blackberryCameraPermissions: 0 360 | blackberryGPSPermissions: 0 361 | blackberryDeviceIDPermissions: 0 362 | blackberryMicrophonePermissions: 0 363 | blackberryGamepadSupport: 0 364 | blackberryBuildId: 0 365 | blackberryLandscapeSplashScreen: {fileID: 0} 366 | blackberryPortraitSplashScreen: {fileID: 0} 367 | blackberrySquareSplashScreen: {fileID: 0} 368 | tizenProductDescription: 369 | tizenProductURL: 370 | tizenCertificatePath: 371 | tizenCertificatePassword: 372 | tizenGPSPermissions: 0 373 | tizenMicrophonePermissions: 0 374 | stvDeviceAddress: 375 | stvProductDescription: 376 | stvProductAuthor: 377 | stvProductAuthorEmail: 378 | stvProductLink: 379 | stvProductCategory: 0 380 | XboxOneProductId: 381 | XboxOneUpdateKey: 382 | XboxOneSandboxId: 383 | XboxOneContentId: 384 | XboxOneTitleId: 385 | XboxOneSCId: 386 | XboxOneGameOsOverridePath: 387 | XboxOnePackagingOverridePath: 388 | XboxOneAppManifestOverridePath: 389 | XboxOnePackageEncryption: 0 390 | XboxOneDescription: 391 | XboxOneIsContentPackage: 0 392 | XboxOneEnableGPUVariability: 0 393 | XboxOneSockets: {} 394 | XboxOneSplashScreen: {fileID: 0} 395 | XboxOneAllowedProductIds: [] 396 | XboxOnePersistentLocalStorageSize: 0 397 | intPropertyNames: 398 | - Metro::ScriptingBackend 399 | - WP8::ScriptingBackend 400 | - WebGL::ScriptingBackend 401 | - WebGL::audioCompressionFormat 402 | - WebGL::exceptionSupport 403 | - WebGL::memorySize 404 | - iOS::Architecture 405 | - iOS::ScriptingBackend 406 | Metro::ScriptingBackend: 2 407 | WP8::ScriptingBackend: 2 408 | WebGL::ScriptingBackend: 1 409 | WebGL::audioCompressionFormat: 4 410 | WebGL::exceptionSupport: 0 411 | WebGL::memorySize: 256 412 | iOS::Architecture: 0 413 | iOS::ScriptingBackend: 0 414 | boolPropertyNames: 415 | - WebGL::dataCaching 416 | WebGL::dataCaching: 0 417 | stringPropertyNames: 418 | - WebGL::emscriptenArgs 419 | - WebGL::template 420 | WebGL::emscriptenArgs: 421 | WebGL::template: APPLICATION:Default 422 | firstStreamedLevelWithResources: 0 423 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 5.0.0f4 2 | m_StandardAssetsVersion: 0 3 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 3 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Fastest 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowCascade2Split: .333333343 18 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 19 | blendWeights: 1 20 | textureQuality: 1 21 | anisotropicTextures: 0 22 | antiAliasing: 0 23 | softParticles: 0 24 | softVegetation: 0 25 | realtimeReflectionProbes: 0 26 | billboardsFaceCameraPosition: 0 27 | vSyncCount: 0 28 | lodBias: .300000012 29 | maximumLODLevel: 0 30 | particleRaycastBudget: 4 31 | excludedTargetPlatforms: [] 32 | - serializedVersion: 2 33 | name: Fast 34 | pixelLightCount: 0 35 | shadows: 0 36 | shadowResolution: 0 37 | shadowProjection: 1 38 | shadowCascades: 1 39 | shadowDistance: 20 40 | shadowCascade2Split: .333333343 41 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 42 | blendWeights: 2 43 | textureQuality: 0 44 | anisotropicTextures: 0 45 | antiAliasing: 0 46 | softParticles: 0 47 | softVegetation: 0 48 | realtimeReflectionProbes: 0 49 | billboardsFaceCameraPosition: 0 50 | vSyncCount: 0 51 | lodBias: .400000006 52 | maximumLODLevel: 0 53 | particleRaycastBudget: 16 54 | excludedTargetPlatforms: [] 55 | - serializedVersion: 2 56 | name: Simple 57 | pixelLightCount: 1 58 | shadows: 1 59 | shadowResolution: 0 60 | shadowProjection: 1 61 | shadowCascades: 1 62 | shadowDistance: 20 63 | shadowCascade2Split: .333333343 64 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 65 | blendWeights: 2 66 | textureQuality: 0 67 | anisotropicTextures: 1 68 | antiAliasing: 0 69 | softParticles: 0 70 | softVegetation: 0 71 | realtimeReflectionProbes: 0 72 | billboardsFaceCameraPosition: 0 73 | vSyncCount: 0 74 | lodBias: .699999988 75 | maximumLODLevel: 0 76 | particleRaycastBudget: 64 77 | excludedTargetPlatforms: [] 78 | - serializedVersion: 2 79 | name: Good 80 | pixelLightCount: 2 81 | shadows: 2 82 | shadowResolution: 1 83 | shadowProjection: 1 84 | shadowCascades: 2 85 | shadowDistance: 40 86 | shadowCascade2Split: .333333343 87 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 88 | blendWeights: 2 89 | textureQuality: 0 90 | anisotropicTextures: 1 91 | antiAliasing: 0 92 | softParticles: 1 93 | softVegetation: 1 94 | realtimeReflectionProbes: 1 95 | billboardsFaceCameraPosition: 1 96 | vSyncCount: 1 97 | lodBias: 1 98 | maximumLODLevel: 0 99 | particleRaycastBudget: 256 100 | excludedTargetPlatforms: [] 101 | - serializedVersion: 2 102 | name: Beautiful 103 | pixelLightCount: 3 104 | shadows: 2 105 | shadowResolution: 2 106 | shadowProjection: 1 107 | shadowCascades: 2 108 | shadowDistance: 70 109 | shadowCascade2Split: .333333343 110 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 111 | blendWeights: 4 112 | textureQuality: 0 113 | anisotropicTextures: 2 114 | antiAliasing: 2 115 | softParticles: 1 116 | softVegetation: 1 117 | realtimeReflectionProbes: 1 118 | billboardsFaceCameraPosition: 1 119 | vSyncCount: 1 120 | lodBias: 1.5 121 | maximumLODLevel: 0 122 | particleRaycastBudget: 1024 123 | excludedTargetPlatforms: [] 124 | - serializedVersion: 2 125 | name: Fantastic 126 | pixelLightCount: 4 127 | shadows: 2 128 | shadowResolution: 2 129 | shadowProjection: 1 130 | shadowCascades: 4 131 | shadowDistance: 150 132 | shadowCascade2Split: .333333343 133 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 134 | blendWeights: 4 135 | textureQuality: 0 136 | anisotropicTextures: 2 137 | antiAliasing: 0 138 | softParticles: 1 139 | softVegetation: 1 140 | realtimeReflectionProbes: 1 141 | billboardsFaceCameraPosition: 1 142 | vSyncCount: 1 143 | lodBias: 2 144 | maximumLODLevel: 0 145 | particleRaycastBudget: 4096 146 | excludedTargetPlatforms: [] 147 | m_PerPlatformDefaultQuality: 148 | Android: 0 149 | BlackBerry: 0 150 | Standalone: 0 151 | WP8: 0 152 | Web: 0 153 | WebGL: 0 154 | Windows Store Apps: 0 155 | iPhone: 0 156 | -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | tags: 6 | - 7 | Builtin Layer 0: Default 8 | Builtin Layer 1: TransparentFX 9 | Builtin Layer 2: Ignore Raycast 10 | Builtin Layer 3: 11 | Builtin Layer 4: Water 12 | Builtin Layer 5: UI 13 | Builtin Layer 6: 14 | Builtin Layer 7: 15 | User Layer 8: Raymarch metavoxel 16 | User Layer 9: Quad 17 | User Layer 10: Unrendered particles 18 | User Layer 11: 19 | User Layer 12: 20 | User Layer 13: 21 | User Layer 14: 22 | User Layer 15: 23 | User Layer 16: 24 | User Layer 17: 25 | User Layer 18: 26 | User Layer 19: 27 | User Layer 20: 28 | User Layer 21: 29 | User Layer 22: 30 | User Layer 23: 31 | User Layer 24: 32 | User Layer 25: 33 | User Layer 26: 34 | User Layer 27: 35 | User Layer 28: 36 | User Layer 29: 37 | User Layer 30: 38 | User Layer 31: 39 | m_SortingLayers: 40 | - name: Default 41 | userID: 0 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: .0199999996 7 | Maximum Allowed Timestep: .333333343 8 | m_TimeScale: 1 9 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | The death of billboarded particles in photorealistic games is imminent. 2 | Most games provide the illusion of 3D particle systems via textured quads that face the 3 | camera plane (or) the camera view direction, traditionally called billboards. You move, and these quads move as well. 4 | 5 | This makes volumetric lighting and self-shadowing hard, and the illusion breaks when you walk through the particle system (say, smoke) 6 | wherein the clipping of billboards is visible (and ugly). 7 | 8 | Treating volumetric particle effects such as smoke, dust & fire in a true 3D sense can yield effects closer to CGI, though making them 9 | run in real-time requires some hackery and cutting corners. 10 | 11 | This repo houses a work-in-progress Unity implementation of Doug Mcnabb's "Sparse Volumetric Particle system". 12 | Please check https://software.intel.com/en-us/articles/sparse-procedural-volumetric-rendering for a great overview of the technique and sample code. 13 | 14 | The gist of the idea is: 15 | The world is a grid of metavoxels that face the light. Each metavoxel is a 3D cube of voxels (volumetric pixels) and each voxel holds density and color information. 16 | 17 | Particles are represented as radially displaced spheres and use Unity's builtin particle simulation framework. However, they are not rendered by the camera (by tagging them on a separate layer). 18 | Since we want a realistic effect, we need to account for the light interaction with the particle system. 19 | 20 | We do this by filling a 3D texture per metavoxel to represent the volume information of the particles it covers. The metavoxels are filled nearest-to-farthest wrt the light, which lets us propagate light through the grid. 21 | The above filled metavoxels are raymarched from the eye by rendering each metavoxel as a cube and sampling from the 3D texture (that holds the voxel data). 22 | This is blended with the scene to give us a realistic volumetric effect. 23 | 24 | Assumptions: 25 | 1. The grid in (a) is centered at the origin. Needs to use view/light frustum to make a tight fit grid for a scene. 26 | 2. Only directional lights affect (or light) the volume. 27 | 28 | TODO: 29 | - The volume doesn't cast shadows on the scene. This needs to be done in the "ray march" stage. 30 | - Voxel border is assumed to be 1 in the Fill Volume shader. Make it a variable. 31 | - Fix sampling artifacts when viewing the metavoxel grid at oblique angles 32 | - Add more UI elements to play with the scene. 33 | - Add a box primitive 34 | -------------------------------------------------------------------------------- /UnityPlayer_Symbols.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajabala/Volumetric-Particles-For-Unity/c2e975b01fdea772a63c6ce23559d25a00e453c3/UnityPlayer_Symbols.pdb -------------------------------------------------------------------------------- /UnityVS.Sparse Volumetric Particle System.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True 3 | True 4 | True 5 | True 6 | True 7 | True 8 | True 9 | PerTechnology 10 | True 11 | True 12 | True 13 | True 14 | True 15 | None 16 | False 17 | -------------------------------------------------------------------------------- /UnityVS.Sparse-Volumetric-Particle-System.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True 3 | True 4 | True 5 | True 6 | True 7 | True 8 | True 9 | PerTechnology 10 | True 11 | True 12 | True 13 | True 14 | True 15 | None 16 | False 17 | -------------------------------------------------------------------------------- /gc.log: -------------------------------------------------------------------------------- 1 | GC Warning: Removing nonexistent thread 5264 2 | --------------------------------------------------------------------------------