Last active
August 18, 2021 01:35
-
-
Save yumayanagisawa/d95f947fb46474de836e5b7550187698 to your computer and use it in GitHub Desktop.
Unity3D | Curl Noise x Compute Shader
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/keijiro/NoiseShader | |
#include "HLSL/SimplexNoise3D.hlsl" | |
#pragma kernel CSParticle | |
// Particle's data | |
struct Particle | |
{ | |
float3 position; | |
float3 velocity; | |
float life; | |
}; | |
// Particle's data, shared with the shader | |
RWStructuredBuffer<Particle> particleBuffer; | |
// Variables set from the CPU | |
float deltaTime; | |
float2 mousePosition; | |
float nrand(float2 uv) | |
{ | |
return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453); | |
} | |
uint rng_state; | |
uint rand_xorshift() | |
{ | |
// Xorshift algorithm from George Marsaglia's paper | |
rng_state ^= (rng_state << 13); | |
rng_state ^= (rng_state >> 17); | |
rng_state ^= (rng_state << 5); | |
return rng_state; | |
} | |
// https://github.com/cabbibo/glsl-curl-noise/blob/master/curl.glsl | |
float3 snoiseVec3(float3 x) { | |
float s = snoise(x); | |
float s1 = snoise(float3(x.y - 19.1, x.z + 33.4, x.x + 47.2)); | |
float s2 = snoise(float3(x.z + 74.2, x.x - 124.5, x.y + 99.4)); | |
float3 c = float3(s, s1, s2); | |
return c; | |
} | |
float3 curlNoise(float3 p) { | |
const float e = .1; | |
float3 dx = float3(e, 0.0, 0.0); | |
float3 dy = float3(0.0, e, 0.0); | |
float3 dz = float3(0.0, 0.0, e); | |
float3 p_x0 = snoiseVec3(p - dx); | |
float3 p_x1 = snoiseVec3(p + dx); | |
float3 p_y0 = snoiseVec3(p - dy); | |
float3 p_y1 = snoiseVec3(p + dy); | |
float3 p_z0 = snoiseVec3(p - dz); | |
float3 p_z1 = snoiseVec3(p + dz); | |
float x = p_y1.z - p_y0.z - p_z1.y + p_z0.y; | |
float y = p_z1.x - p_z0.x - p_x1.z + p_x0.z; | |
float z = p_x1.y - p_x0.y - p_y1.x + p_y0.x; | |
const float divisor = 1.0 / (2.0 * e); | |
return normalize(float3(x, y, z) * divisor); | |
} | |
[numthreads(256, 1, 1)] | |
void CSParticle(uint3 id : SV_DispatchThreadID) | |
{ | |
// subtract the life based on deltaTime | |
particleBuffer[id.x].life -= deltaTime; | |
particleBuffer[id.x].position += curlNoise(particleBuffer[id.x].position) * 0.1; | |
if (particleBuffer[id.x].life < 0) | |
{ | |
// http://www.reedbeta.com/blog/quick-and-easy-gpu-random-numbers-in-d3d11/ | |
rng_state = id.x; | |
float f0 = float(rand_xorshift()) * (1.0 / 4294967296.0) - 0.5; | |
float f1 = float(rand_xorshift()) * (1.0 / 4294967296.0) - 0.5; | |
float f2 = float(rand_xorshift()) * (1.0 / 4294967296.0) - 0.5; | |
float3 normalF3 = normalize(float3(f0, f1, f2)) * 0.2f; | |
normalF3 *= float(rand_xorshift()) * (1.0 / 4294967296.0); | |
particleBuffer[id.x].position = float3(normalF3.x + mousePosition.x, normalF3.y + mousePosition.y, normalF3.z + 3.0); | |
// reset the life of this particle | |
particleBuffer[id.x].life = 5; | |
//particleBuffer[id.x].velocity = float3(0, 0, 0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment