0% found this document useful (0 votes)
108 views52 pages

Curl Noise Slides

The document discusses curl noise, which is a technique used to simulate fluid effects like smoke and fire by moving particles around. It provides an overview and then discusses computing curl noise in 2D and 3D. Curl is a mathematical operator that takes a vector field as input and outputs a divergence-free vector field. The document explains how to compute the curl of a Perlin noise vector field by taking the gradients and plugging them into the curl definition. It also discusses using finite differences to approximate the gradients, which only requires basic math.

Uploaded by

registered99
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
108 views52 pages

Curl Noise Slides

The document discusses curl noise, which is a technique used to simulate fluid effects like smoke and fire by moving particles around. It provides an overview and then discusses computing curl noise in 2D and 3D. Curl is a mathematical operator that takes a vector field as input and outputs a divergence-free vector field. The document explains how to compute the curl of a Perlin noise vector field by taking the gradients and plugging them into the curl definition. It also discusses using finite differences to approximate the gradients, which only requires basic math.

Uploaded by

registered99
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 52

Curl

 Noise  

Peter  Werner  
Overview    
•  Take  a  look  at  end  results  
•  Cover  some  background  stuff  
•  Look  at  2D  case  
•  Some  more  background  stuff  
•  Look  at  3D  case  
•  General  computaBon  consideraBons  
Curl  Noise    
•  Move  a  bunch  of  parBcles  around  
•  Used  for  smoke,  fire,  fluid  effects  
•  RelaBvely  inexpensive  to  calculate  
•  Especially  compared  to  other  methods  of  fluid  
simulaBon  
•  Also  just  generally  looks  kinda  cool  
ObjecBves  
•  Aim  is  to  understand  what  the  curl  operator  
does  
•  Can  go  off  and  read  other  peoples  papers/
code    
•  Not  a  mathemaBcally  rigourous  talk  
•  Interludes  Bme  for  quesBons  
Background    
•  Curl  is  a  mathemaBcal  operator  like  +,  -­‐,  etc  
•  Its  input  is  a  vector  field  
•  Its  output  is  a  divergence  free  vector  field  
•  Measure  of  rotaBonal  force  
•  In  our  case  the  input  will  be  Perlin  Noise  
•  We  will  use  the  output  to  move  parBcles  around  
•  A  divergence  free  vector  field  will  stop  our  
parBcles  smooshing  together  too  much  
Perlin  Noise    
•  Used  whenever  you  want  something  that  varies  
but  not  completely  randomly  
•  Takes  x/y/z  locaBons    
•  Gives  values  from  [0,  1]  or  [-­‐1,  1]  
•  Low  frequency  noise  varies  from  high  values  to  
low  values  slowly  
•  High  frequency  noise  varies  quickly  
•  Common  to  sum  layers  of  noise  at  different  
frequencies  
Perlin  Noise  
Low  frequency   High  frequency   Sums  of  frequencies  
Vector  Field    
•  We  use  Perlin  noise  as  our  vector  field  
•  For  a  parBcle  at  a  certain  (x,  y)  posiBon  
•  Evaluate  the  noise  funcBon  at  (x,  y)  to  get  a  
value  n  
•  Make  our  velocity  vector  v  =  (n,  n)  
•  Next  parBcle  posiBon  =  (x,  y)  +  (n,  n)  
Perlin  noise  vector  field  
Curl  of  same  field  
Curl  in  2D  

•  PotenBal  Field  (perlin  noise)     ψ = (ψ1, ψ2 , ψ3 )
•  Instead:     F = (x, y, z)
•  In  2D:   F = (x, y)
•  Some  point     P = ( x1, y1 )
# ∂x ∂y &
•  Curl:     v(x, y) = 1
% ,− ( 1

$ ∂y ∂x '
•  v(x,  y)  is  the  output  of  the  curl  operator.    
•  It  has  a  vector  value,  so  x,y  in  2D,  x,y,z  in  3D  
•  The  derivaBve  terms  are  rates  of  change.  
Curl  in  2D  
•  Don’t  worry,  no  calculus  is  required  
∂x1
•  What  does  this  term      ∂y        really  mean?  
•  We  want  the  rate  of  change  in  x  
•  At  a  given  point  x1  
•  On  the  y  axis/relaBve  to  y  
•  i.e.  how  much  the  x1  value  would  change  as  
the  y  values  change  around  it  
•  Just  a  regular  number  as  its  value  
Curl  in  2D  
∂y1
•  Similarly  for   ∂x
•  How  much  do  y  values  change  around  some  
point  y1  …  
•  As  the  values  of  x  change?  
•  What’s  the  rate  of  change  in  y  relaBve  to  x?  
•  How  much  does  y  change  as  x  changes?  
•  Gradient  =  derivaBve  =  rate  of  change  
CompuBng  the  Curl  
•  Step  1:  Calculate  the  gradients    
•  Step  2:  Jigger  the  values  round  to  fit  curl  
definiBon  
# ∂x ∂y &
•  e.g.  Curl  definiBon   v(x, y) 1
= 1
% ,− (
$ ∂y ∂x '
•   Step  1:   a =
∂x
1
∂y
, b =1∂y
∂x
•   Step  2:   v(x, y) = (a, −b)
# ∂x ∂y &
v(x, y) = % 1 , − 1 (
$ ∂y ∂x '
Finite  Difference  Gradient  
•  But  how  to  compute  the  gradients?  
•  Can  be  done  using  calculus  using  simplex  
noise  
•  Much  easier  way  is  to  approximate  the  rate  of  
change  using  a  method  called  finite  
differences.  
•  Super  easy,  uses  primary  school  math    
Finite  Differences  
•  We  have  a  mystery  funcBon  we  want  to  
approximate  a  derivaBve  for  
Finite  Differences  
•  Have  some  2D  data  with  x  and  y  values  
•  Want  to  approximate  the  rate  of  change  of  y  
as  x  changes  (i.e.  dx      )  at  say  x  =  5  
dy

•  We  know  the  x  values  and  y  values  


•  But  not  the  funcBon  that  generated  them  
Finite  Differences  
•  How  about  we  take  the  average  y  values  at  
points  “close”  to  x  =  5  
•  In  this  case,  x  =  4  and  x  =  6  
Finite  Differences  
•  Looking  at  our  data,  we  get  y  =  16  and  y  =  36  
Finite  Differences  
•  Taking  the  average  gives   36 −16 = 20 = 10
  2 2

•  Our  funcBon  is  really  


2
y = x

dy
•  We  know  its  derivaBve     dx
= 2x

•  Which  at  x  =  5  gives  10,  the  same  as  our  


approximaBon  
Finite  Differences  
•  The  general  idea  for  some     ∂bot∂top
or
d top
d bot

•  Move  the  values  of  bot  a  bit  


•  Get  the  top  values  at  those  points  
•  Subtract  one  of  those  values  from  the  other    
•  Divide  it  by  2  to  get  the  average  
•  This  will  approximate  the  gradient  at  that  
point  
Finite  Differences  
•  Common  to  talk  of  small  differences  in  terms  
of  the  greek  epsilon    ε
•  For  our    dx      case  with     y = f ( x) = x
dy 2

•  Set  epsilon  to  some  small  value  (  ε    =      1    )  


•  Then  look  at   f (x + ε 2) −× εf (x − ε ) = f (5 +1)2−×1f (5 −1) = 6 −2 4 = ... = 10
2 2

•  If  you  are  using  normalized  texture  coords  


epsilon  might  be  0.0001    
CompuBng  the  Curl  
•  Step  1:        Calculate  the  gradients    
•  Step  2:        Jigger  the  values  round  to  fit  curl    
                           definiBon  
•  e.g.    Curl  definiBon  2D:   v(x, y) = %$ ∂y , − ∂x ('
1 1
# ∂x ∂y &

•   Step  1:   1 1
a =
∂x
∂y
, b =
∂y
∂x
•   Step  2:   v(x, y) = (a, −b)
# ∂x ∂y &
v(x, y) = % 1 , − 1 (
$ ∂y ∂x '
CompuBng  the  Curl  
ofVec2f  ComputeCurl(float  x,  float  y)  
{  
       float  eps  =  1.0;  
       float  n1,  n2,  a,  b;  
       
       n1  =  noise(x,  y  +  eps);   ∂x1
a=
       n2  =  noise(x,  y  -­‐  eps);   ∂y
       a  =  (n1  -­‐  n2)/(2  *  eps);  
 
       n1  =  noise(x  +  eps,  y);   ∂y1
       n2  =  noise(x  -­‐  eps,  y);   b=
∂x
       b  =  (n1  -­‐  n2)/(2  *  eps);  
         
       ofVec2f  curl  =  ofVec2f(a,  -­‐b);   # ∂x ∂y &
v(x, y) = % 1 , − 1 (
       return  curl;   $ ∂y ∂x '
}  
Recap  
•  Perlin  Noise  
•  Vector  Fields  
•  Curl  in  2D  
•  CompuBng  gradients  
•  CompuBng  curl  in  2D  
MathemaBcal  Fact  
•  cosine  can  be  used  to  approximate  the  normal  
distribuBon  
1+ cos ( x )
f ( x) = , x ∈ ( −π , π )

Curl  in  3D  
 " δψ3 δψ 2 δψ1 δψ3 δψ 2 δψ1 %
•  Bridson:   v ( x, y, z ) = $
# δy
− , − , −
δz δz δ x δ x δ y &
'

•  Some  point  in  3D     P = ( x1, y1, z1 )



We  get     v ( x, y, z) = $# δ y − δ z , δ z − δ x , δ x − δ y '&
"δz δ y δ x δz δ y δ x %
•  1 1 1 1 1 1

•  Three  valued  funcBon  (a  vector  in  3D)  


The  last  term  has      ∂x      and   ∂y
∂y ∂x
•  1 1

•  Just  like  we  saw  for  the  2D  case  


Curl  in  3D  
 " δ z1 δ y1 δ x1 δ z1 δ y1 δ x1 %
•  Curl   v ( x, y, z ) = $ − , − ,
# δ y δz δz δ x δ x δ y &
− '

•  Gives  a  vector  with  three  values:  



v ( x, y, z ) = ( rate of change for x, rate of change for y, rate of change for z )

•  Say  we  have  some  funcBon   f ( x, y, z) = x + y + z 2 2 2

•  To  find  the  rate  of  change  for  z  


•  Hold  z  constant    
•  Will  have  an  x  component  of  change  
•  And  a  y  component  of  change  
•  Hold  z  constant,  jigger  round  x  and  y  a  bit    
Curl  in  3D  
 " δ z1 δ y1 δ x1 δ z1 δ y1 δ x1 %
•  Curl    
v ( x, y, z ) = $ − , − ,
# δ y δz δz δ x δ x δ y &
− '

•  Also  need  to  find  the  rate  of  change  for  x    


•  Will  vary  relaBve  to  y  and  z  locaBons  
•  The  rate  of  change  for  y  
•  Will  vary  relaBve  to  x  and  z  locaBons  
•  Let’s  call  all  these    v ( x, y, z) = (Δx, Δy, Δz)
•  Delta  means  “change  in”  
Curl  3D  
•  Curl      " δ z1 δ y1 δ x1 δ z1 δ y1 δ x1 %
v ( x, y, z ) = $ − , − ,
# δ y δz δz δ x δ x δ y &
− '

•  NoBce   δ y − δ z 1
Δx 1
=
δz δ y

•  We  only  care  about  y/z  plane  


•  Likewise              δ    z    −  δ    x      x/z  plane  
1 1
Δy =
δ x δz

•  And    Δz    =    δδ  yx    −    δδ  xy      all  happening  in  the  x/y  plane  
1 1

•  Think  of  bopom  parts  as  the  2D  plane  lepers  


•  This  enables  a  performance  improvement  
when  actually  compuBng  the  values  
           =      δ z1 − δ y1
 Δx
  δ y δz
 Δy       δ x1 − δ z1
           =
  δz δ x
   Δz       δ y1 − δ x1
         =
  δx δy
Curl  in  3D  
 " δ z1 δ y1 δ x1 δ z1 δ y1 δ x1 %
•  Curl    
v ( x, y, z ) = $ − , − ,
# δ y δz δz δ x δ x δ y &
− '

•  Step  1:        Calculate  the  gradients    


•  Step  2:        Jigger  the  values  round  to  fit  curl    
                           definiBon  
•  If  we  think  in  terms  of  planes  
•  The  gradients  are  just  the  same  as  the  2D  case  
Curl  in  3D  
δ z1 δ y1
•  Lets  take  Δx = −
δ y δz

•  Let     a = ∂z∂y , b = ∂y∂z


1 1

•  Compute  these  two  values  as  we  did  before  


•  For  a,  hold  z  fixed,  move  y  around  
•  For  b,  hold  y  fixed,  move  z  around  
•  We  get   Δx = a − b
 # δ x δz δ y δ x &
•  We  now  have     ( ) %$ δ z − δ x , δ x − δ y ('
v x, y, z1
= 1
Δx, 1 1
CompuBng  the  Curl  
•  ConBnue  on  for  the  other  components  
•  Step  1:        Calculate  the  gradients    
•  Step  2:        Jigger  the  values  round  to  fit  curl    
                           definiBon  
CompuBng  the  Curl  
ofVec3f  ComputeCurl(float  x,  float  y,  float  z)  
{  
       float  eps  =  1.0;  
       float  n1,  n2,  a,  b;  
       ofVec3f  curl;  
 
       n1  =  noise(x,  y  +  eps,  z);  
       n2  =  noise(x,  y  -­‐  eps,  z);  
       a  =  (n1  -­‐  n2)/(2  *  eps);   δ z1 δ y1
         
       n1  =  noise(x,  y,  z  +  eps);  
Δx = −
       n2  =  noise(x,  y,  z  -­‐  eps);   δ y δz
       b  =  (n1  -­‐  n2)/(2  *  eps);  
         
       curl.x  =  a  -­‐  b;  
         
       n1  =  noise(x,  y,  z  +  eps);  
       n2  =  noise(x,  y,  z  -­‐  eps);  
       a  =  (n1  -­‐  n2)/(2  *  eps);   δ x1 δ z1
         
       n1  =  noise(x  +  eps,  y,  z);  
Δy = −
       n2  =  noise(x  +  eps,  y,  z);  
       b  =  (n1  -­‐  n2)/(2  *  eps);  
δz δ x
         
       curl.y  =  a  -­‐  b;  
 
       n1  =  noise(x  +  eps,  y,  z);  
       n2  =  noise(x  -­‐  eps,  y,  z);  
       a  =  (n1  -­‐  n2)/(2  *  eps);   δ y1 δ x1
    Δz = −
       n1  =  noise(x,  y  +  eps,  z);  
       n2  =  noise(x,  y  -­‐  eps,  z);   δx δy
       b  =  (n1  -­‐  n2)/(2  *  eps);  
         
       curl.z  =  a  -­‐  b;  
           "δz δ y δ x δz δ y δ x %
       return  curl;  
}  
v ( x, y, z ) = $ 1 − 1 , 1 − 1 , 1 − 1 '
# δ y δz δz δ x δ x δ y &
MathemaBcal  Fact  
•  An  infinite  dimensional  unit  sphere  (with  
radius  =  1)  has  no  volume  
ComputaBonal  ConsideraBons  
•  Typically  store  noise  values  in  floaBng  point  
textures  
•  Can  calculate  noise  on  the  fly  
•  Noise  scales  really  well,  examples  use  64x64  
noise  textures  
•  Turn  on  bilinear  interpolaBon  and  texture  
wrapping  
•  The  3D  case  could  also  use  GL_TEXTURE_3D  
•  Can  also  use  point  sprites,  billboarding,  blending  
etc  
ComputaBonal  ConsideraBons  
•  The  2D  case  uses  one  2D  texture  
•  My  3D  case  uses  three  2D  textures,  one  for  each  plane  
•  When  sampling  from  textures  add  half  a  textel  width  

vec2  Grad(float  x,  float  y)  


{  
       float  h  =  1/dims.x  *  0.5;  
       float  eps  =  1.0/dims.x;  
       float  n1,  n2,  dx,  dy;  
       vec2  dx0,  dx1,  dy0,  dy1;  
       dx0  =  vec2(x,  y  -­‐  eps)  +  h;  
       dx1  =  vec2(x,  y  +  eps)  +  h;  
…  
       n1  =  texture(uPtex,  dx0).r;  
       n2  =  texture(uPtex,  dx1).r;  
       dx  =  n1  -­‐  n2;  
ComputaBonal  ConsideraBons  
•  May  also  want  to  normalize  curl  values  
ofVec3f  curl  =  CalculateCurl(x,  y,  z);  
curl.normalize();  
•  Can  skip  the  divison  in  finite  differences  
•  Probably  also  want  some  fixed  velocity  for  
each  parBcle  
•  Curl  is  a  measure  of  rotaBonal  force,  so  
parBcles  will  end  up  in  loops  
ComputaBonal  ConsideraBons  
•  I  usually  have  a  variable  to  modulate  curl  
amount,  eg  from  [0,  1]  
•  Also  a  Bme  step  value  also  from  [0,  1]  
•  E.g.  
•  parBcle.xyz  +=  (fixedVel  +  curl  *  curlAmt)  *  dt;  
•  Where  curlAmt  ranges  [0,1]  
•  dt  is  Bme  step  also  from  [0,1]  
References  
•  Robert  Bridson,  original  paper  +  code   hpp://www.cs.ubc.ca/~rbridson/  

•  Philip  Rideout,  code/tutorials   hpp://prideout.net/blog/  

•  MiauMiau,  WebGL  code   hpp://www.miaumiau.cat  

•  Vector  Field  hpp://tutorial.math.lamar.edu/Classes/CalcIII/VectorFields.aspx    


•  ParBal  DerivaBves  hpp://tutorial.math.lamar.edu/Classes/CalcIII/ParBalDerivaBves.aspx  
•  Curl  hpp://tutorial.math.lamar.edu/Classes/CalcIII/CurlDivergence.aspx  

•  Bridson  has  a  book  on  fluid  simulaBon    


•  Rideout  has  a  cool  book  on  iPhone  OpenGL  
Me  
•  Blog  hpp://petewerner.blogspot.com.au/  
•  Twiper  hpps://twiper.com/dizzy_pete  
•  Tumblr  hpp://i-­‐am-­‐noise.tumblr.com/  
•  Vimeo  hpps://vimeo.com/dizzypete  
•  Github  hpps://github.com/petewerner  

You might also like