Aetheria/Assets/Shaders/Compute/Stardust/Stardust.cs
Reinier Vens 69aca09f63 Boundless
Removed hard zone boundaries
Fixed stuff that broke because of hard zone boundary assumption (stardust placement, vertical fog)
Added a skybox!
Removed density-based albedo boost (_TintExponent) to improve perceptual uniformity at different step sizes, reconfigured shader to achieve / surpass previous looks and performance
Cell Brush has a material editor now to enable variant selection
Enabled Caching Shader Preprocessor
Moved raymarching loop into CloudShader
Get environment settings from game manager to enable configuration / variation
Introduced slope-based nebulae damping and volumetric flow
Hid optional volumetric features behind preprocessor branches
Created shader variants selected by global keywords for all shaders depending on volumetrics
Environment settings used to configure shader variant selection
Moved dynamic lighting settings to own subclass
Dynamically adjust gravity map isoline contour depth range according to zone contents
2022-07-21 21:40:44 +01:00

164 lines
5.3 KiB
C#

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Rendering;
public class Stardust : MonoBehaviour
{
#region variables
//public bool debugLog = false;
//public float proxyPersistTime = 2;
public GameSettings Settings;
public Camera TargetCamera;
public ComputeShader ParticleCalculation;
public Material ParticleMaterial;
public int Span = 512;
public float Period = .25f;
public float MinimumSize = .1f;
public float MaximumSize = 2;
public float Spacing = 4.0f;
public float Ceiling = -250.0f;
public float Floor = -25.0f;
public float MinHeadroom = 25;
public float MaxHeadroom = 100;
public float HeightExponent = 4;
public RenderTexture NebulaSurfaceHeight;
public RenderTexture NebulaPatchHeight;
public RenderTexture NebulaPatch;
public RenderTexture NebulaTint;
public Texture Heightmap;
public Texture2D ParticleColors;
//public Transform TargetTransform;
public Camera GravityCamera;
private float _flowScroll;
private const int GROUP_SIZE = 128;
private int _updateParticlesKernel;
#endregion
#region Structs
//Notice that this struct has to match the one in the compute shader exactly.
struct Particle
{
public Vector3 Position;
public Vector3 Color; //Color is a float3 in the compute shader, we need a Vector3 to match that layout, not a Color!
public float Size;
};
#endregion
#region buffers
private ComputeBuffer _particlesBuffer;
private const int PARTICLE_STRIDE = 28;
private ComputeBuffer _quadPoints;
private const int QUAD_STRIDE = 12;
#endregion
#region setup
// Use this for initialization
void Start()
{
//Find compute kernel
_updateParticlesKernel = ParticleCalculation.FindKernel("UpdateParticles");
//Create particle buffer
_particlesBuffer = new ComputeBuffer(Span * Span, PARTICLE_STRIDE);
Particle[] particles = new Particle[Span * Span];
for (int i = 0; i < Span * Span; ++i)
{
particles[i].Position = Random.insideUnitSphere * 100;
particles[i].Color = Vector3.one; //white
particles[i].Size = Random.value;
}
_particlesBuffer.SetData(particles);
//Create quad buffer
_quadPoints = new ComputeBuffer(6, QUAD_STRIDE);
_quadPoints.SetData(new[] {
new Vector3(-.5f, .5f),
new Vector3(.5f, .5f),
new Vector3(.5f, -.5f),
new Vector3(.5f, -.5f),
new Vector3(-.5f, -.5f),
new Vector3(-.5f, .5f)
});
}
#endregion
#region Compute update
// Update is called once per frame
void Update()
{
//Bind resources to compute shader
ParticleCalculation.SetBuffer(_updateParticlesKernel, "particles", _particlesBuffer);
ParticleCalculation.SetFloat("time", Time.time);
var pos = GravityCamera.transform.position;
ParticleCalculation.SetFloat("period", Period);
ParticleCalculation.SetFloat("spacing", Spacing);
ParticleCalculation.SetFloat("ceilingHeight", Ceiling);
ParticleCalculation.SetFloat("floorHeight", Floor);
ParticleCalculation.SetFloat("heightExponent", HeightExponent);
ParticleCalculation.SetFloat("maximumSize", MaximumSize);
ParticleCalculation.SetFloat("minimumSize", MinimumSize);
ParticleCalculation.SetFloat("minHeadroom", MinHeadroom);
ParticleCalculation.SetFloat("maxHeadroom", MaxHeadroom);
ParticleCalculation.SetInt("span", Span);
ParticleCalculation.SetTexture(_updateParticlesKernel, "HueTexture", ParticleColors);
//Dispatch, launch threads on GPU
int numberOfGroups = Mathf.CeilToInt((float)Span * Span / GROUP_SIZE);
ParticleCalculation.Dispatch(_updateParticlesKernel, numberOfGroups, 1, 1);
ParticleMaterial.SetBuffer("particles", _particlesBuffer);
ParticleMaterial.SetBuffer("quadPoints", _quadPoints);
Graphics.DrawProcedural(ParticleMaterial, new Bounds(pos, new Vector3(Spacing * Span, 2048, Spacing * Span)), MeshTopology.Triangles, 6, Span * Span, TargetCamera, null, ShadowCastingMode.Off, false, 0);
}
#endregion
#region rendering
// void OnRenderObject()
// {
// if (Camera.current == TargetCamera || Camera.current.name == "SceneCamera")
// {
// //Bind resources to material
// ParticleMaterial.SetBuffer("particles", _particlesBuffer);
// ParticleMaterial.SetBuffer("quadPoints", _quadPoints);
// // ParticleMaterial.SetFloat("velocityStretch", ParticleVelocityStretch);
// // ParticleMaterial.SetVector("velocity", PlayerVelocity);
//
// //Set the pass
// ParticleMaterial.SetPass(0);
//
// //Draw
// Graphics.DrawProceduralNow(MeshTopology.Triangles, 6, Span * Span);
// }
// }
#endregion
#region cleanup
void OnDestroy()
{
// m_emitterProxies.Release();
// _temperature.Release();
if(_particlesBuffer!=null)
{
_particlesBuffer.Release();
_quadPoints.Release();
}
// m_livingProxyIndices.Release();
}
#endregion
}