3D Curl Noise

Controls

Drag to move camera, scroll to zoom.

Overview

This project renders instanced camera facing particles moving according to the curl of a 3D gradient noise FBM. The curl of a vector field can be thought of as describing a local rotation. In graphics, it can be used to render fluid-like flow as discussed in "Curl-Noise for Procedural Fluid Flow" by Bridson et al. This shader is based on a post by atyuwen: "the divergence of the cross product of two gradient fields is always zero".

vec3 computeCurl(vec3 p){
  const float eps = 1e-1;

  float dx = noise(p + vec3(eps, 0, 0)) - noise(p - vec3(eps, 0, 0));
  float dy = noise(p + vec3(0, eps, 0)) - noise(p - vec3(0, eps, 0));
  float dz = noise(p + vec3(0, 0, eps)) - noise(p - vec3(0, 0, eps));

  vec3 noiseGrad0 = vec3(dx, dy, dz) / (2.0 * eps);

  // Offset position by a random value for second uncorrelated noise read
  p += 1008.5;

  dx = noise(p + vec3(eps, 0, 0)) - noise(p - vec3(eps, 0, 0));
  dy = noise(p + vec3(0, eps, 0)) - noise(p - vec3(0, eps, 0));
  dz = noise(p + vec3(0, 0, eps)) - noise(p - vec3(0, 0, eps));

  vec3 noiseGrad1 = vec3(dx, dy, dz) / (2.0 * eps);

  vec3 curl = cross(noiseGrad0, noiseGrad1);

  return normalize(curl);
}