Replaced Unity TAA with PlayDead TAA Custom keyboard layout test scene Adjusted Aetheric Drive VFX to be more subtle Reworked stardust VFX to reduce flickering artifacts Added Action Bar & weapon groups saving/loading Implemented security levels and faction safe zone visualization Improved station placement (now include defensive turrets)
133 lines
No EOL
3.6 KiB
Text
133 lines
No EOL
3.6 KiB
Text
//Tell unity that we have defined a kernel
|
|
#pragma kernel UpdateParticles
|
|
|
|
//Store Particle data in a struct
|
|
struct Particle
|
|
{
|
|
float3 position;
|
|
float3 color;
|
|
float size;
|
|
};
|
|
|
|
RWStructuredBuffer<Particle> particles;
|
|
|
|
// Use this texture to spawn particles over terrain
|
|
Texture2D Heightmap;
|
|
SamplerState samplerHeightmap;
|
|
|
|
// Use this texture to choose the color of the particle
|
|
Texture2D HueTexture;
|
|
SamplerState samplerHueTexture;
|
|
|
|
//uniform float4x4 noiseOffsetMatrix;
|
|
|
|
float time;
|
|
float3 transform;
|
|
float spacing;
|
|
float ceilingHeight;
|
|
float floorHeight;
|
|
float maximumSize;
|
|
float minimumSize;
|
|
float heightExponent;
|
|
uint span;
|
|
|
|
//================
|
|
//Bonus: Random number generator
|
|
//Using xorshift, and thread ID as a seed. If you only use xorshift,
|
|
//there is too much correlation, so we first hash the seed id in RandomFirst()
|
|
//See: http://www.reedbeta.com/blog/2013/01/12/quick-and-easy-gpu-random-numbers-in-d3d11/
|
|
|
|
uint rngState;
|
|
|
|
#define UINT_MAXF 4294967290.0f
|
|
|
|
|
|
float RandomFirst(uint a, uint b)
|
|
{
|
|
//wang hash the seed first to get rid of correlation.
|
|
a = (a ^ 61) ^ (a >> 16);
|
|
a *= 9;
|
|
a = a ^ (a >> 4);
|
|
a *= 0x27d4eb2d;
|
|
a = a ^ (a >> 15);
|
|
|
|
b -= (b<<6);
|
|
b ^= (a>>17);
|
|
b -= (b<<9);
|
|
b ^= (a<<4);
|
|
b -= (b<<3);
|
|
b ^= (b<<10);
|
|
b ^= (b>>15);
|
|
|
|
rngState = a ^ b;
|
|
|
|
return (float)rngState / UINT_MAXF;
|
|
}
|
|
|
|
|
|
float RandomValue()
|
|
{
|
|
// Xorshift algorithm from George Marsaglia's paper
|
|
//You could use RandomFirst() all the time - it'd just be more expensive.
|
|
rngState ^= (rngState << 13);
|
|
rngState ^= (rngState >> 17);
|
|
rngState ^= (rngState << 5);
|
|
return (float) rngState / UINT_MAXF;
|
|
}
|
|
|
|
#define HASHSCALE 0.1031
|
|
|
|
float hash(float p)
|
|
{
|
|
float3 p3 = frac(p.xxx * HASHSCALE);
|
|
p3 += dot(p3, p3.yzx + 19.19);
|
|
return frac((p3.x + p3.y) * p3.z);
|
|
}
|
|
|
|
float fade(float t) { return t*t*t*(t*(6.*t-15.)+10.); }
|
|
|
|
float grad(float hash, float p)
|
|
{
|
|
int i = int(1e4*hash);
|
|
return (i & 1) == 0 ? p : -p;
|
|
}
|
|
|
|
float perlinNoise1D(float p)
|
|
{
|
|
float pi = floor(p), pf = p - pi, w = fade(pf);
|
|
return lerp(grad(hash(pi), pf), grad(hash(pi + 1.0), pf - 1.0), w) * 2.0;
|
|
}
|
|
|
|
const float4 irrationals = float4(1.41421, 3.14159, 2.71828, 1.61803);
|
|
float noise(float p)
|
|
{
|
|
return (sin(irrationals.x * p) + sin(irrationals.y * p) + sin(irrationals.z * p) + sin(irrationals.w * p))/4;
|
|
}
|
|
|
|
const uint offset = 65535;
|
|
const float randomRange = 2048;
|
|
|
|
//Since we only have a long list of particles, our thread group is just a flat block of threads in the x direction
|
|
//128 threads in a group is a good amount for a couple of reasons
|
|
[numthreads(128, 1, 1)]
|
|
void UpdateParticles(uint3 id : SV_DispatchThreadID, int3 groupID : SV_GroupThreadID)
|
|
{
|
|
int x = id % span - span / 2;
|
|
int y = id / span - span / 2;
|
|
|
|
int xt = (int)(transform.x / spacing);
|
|
int yt = (int)(transform.y / spacing);
|
|
uint xp = x + xt + offset;
|
|
uint yp = y + yt + offset;
|
|
|
|
particles[id.x].color = HueTexture.SampleLevel(samplerHueTexture, float2(RandomFirst(xp, yp), 0.0f), 0.0f).rgb;
|
|
|
|
particles[id.x].position = float3(
|
|
x * spacing + xt * spacing + perlinNoise1D(RandomValue()*1024+time)*spacing, 0,
|
|
y * spacing + yt * spacing + perlinNoise1D(RandomValue()*1024+time)*spacing);
|
|
float2 puv = float2(.5,.5) - (particles[id.x].position.xz - transform.xy) / (transform.z);
|
|
float gravDepth = Heightmap.SampleLevel(samplerHeightmap, puv, 0.0f).r;
|
|
float headroom = (ceilingHeight+gravDepth);
|
|
particles[id.x].position.y = -gravDepth + floorHeight + -floorHeight * 4 * pow(RandomValue(), max(1, heightExponent/(headroom*headroom))) + perlinNoise1D(RandomValue()*1024+time)*spacing/2;
|
|
particles[id.x].size = lerp(minimumSize, maximumSize, RandomValue());
|
|
} |