POV-Ray : Newsgroups : povray.binaries.images : Line Integral Convolution (LIC) Server Time
30 Jul 2024 02:22:12 EDT (-0400)
  Line Integral Convolution (LIC) (Message 1 to 2 of 2)  
From: waggy
Subject: Line Integral Convolution (LIC)
Date: 25 Apr 2013 23:05:01
Message: <web.5179ee7024497c1621be1230@news.povray.org>
I was surprised a newsgroup search didn't turn up anything for this. I'm
planning to use this technique for an animation I'm doing as my final project
for a Scientific Visualization course, so I don't have time to get the code into
a form more suitable for general use. Perhaps someone might find it useful as it
is.

http://en.wikipedia.org/wiki/Line_integral_convolution

/* Line Integral Convolution Demonstration
 *
 * A line integral convolution is often used to visualize flows.
 * It effectively "smears" an underlying pattern along flowlines.
 * The flowlines are computed by gradient descent.
 * This would be better implemented internally as a warp.
 *
 povray +P +RP1 lic.pov
 */
#version 3.7;
global_settings {
   assumed_gamma 1.0
   ambient_light 0.1
}
#include "functions.inc"
#include "stage1.inc"

#declare Show_Gradient = 2;
#switch(Show_Gradient)
#case(1)// Gradient of x^2+y^2+z^2
  #declare F_gradx = function(X,Y,Z){(2*X )};
  #declare F_grady = function(X,Y,Z){(2*Y )};
  #declare F_gradz = function(X,Y,Z){(2*Z )};
  #break
#case(2)// Saddle Point
  #declare F_gradx = function(X,Y,Z){-Y/sqrt(pow(X,2)+pow(Y,2))};
  #declare F_grady = function(X,Y,Z){-X/sqrt(pow(X,2)+pow(Y,2))};
  #declare F_gradz = function(X,Y,Z){0};
  #break
#end
// Gradient Length
#declare F_gradl = function(X,Y,Z){
  sqrt(
  pow(F_gradx(X,Y,Z),2)
 +pow(F_grady(X,Y,Z),2)
 +pow(F_gradz(X,Y,Z),2)
  )
};
// Normalized Gradient
#declare F_granx = function(X,Y,Z){F_gradx(X,Y,Z)/F_gradl(X,Y,Z)};
#declare F_grany = function(X,Y,Z){F_grady(X,Y,Z)/F_gradl(X,Y,Z)};
#declare F_granz = function(X,Y,Z){F_gradz(X,Y,Z)/F_gradl(X,Y,Z)};

#declare LIC_F_Pattern = function(X,Y,Z){(
  f_granite(X/10,Y/10,Z/10) //Best?
  //f_leopard(X/2,Y/2,Z+.5)*(f_leopard(X/2,Y/2,Z+.5)>0.5)
  //(f_noise3d(X,Y,Z)>0.8)
  //f_noise_generator(X,Y,Z, 1)
  //f_spotted(X,Y,Z)//>0.5
  //f_crackle(X,Y,Z)*(f_crackle(X,Y,Z)>0.5)
  //f_dents(X,Y,Z)
  //f_bozo(X,Y,Z)
  //f_wrinkles(X,Y,Z)// Good
)};
// Convolution Envelopes
#declare LIC_F_Constant  = function(M,N){ 1 };
#declare LIC_F_Ramp_Down = function(M,N){ (1-M/N)*2 };
#declare LIC_F_Ramp_Up   = function(M,N){ M/N*2 };

//Line Integral Convolution Pattern Functions
#declare LIC_F_Forward = function(x,y,z, S,H,N){
 sum(M,0,N-1,
   LIC_F_Ramp_Down(M,N)
  *LIC_F_Pattern(
     (x+H*sum(I,0,M,F_granx((x+H*I),y,z)))/S,
     (y+H*sum(I,0,M,F_grany(x,(y+H*I),z)))/S,
     (z+H*sum(I,0,M,F_granz(x,y,(z+H*I))))/S
   ))/N
};
#declare LIC_F_Backward = function(x,y,z, S,H,N){
 sum(M,0,N-1,
   LIC_F_Ramp_Down(M,N)
  *LIC_F_Pattern(
     (x+H*sum(I,0,M,F_granx((x-H*I),y,z)))/S,
     (y+H*sum(I,0,M,F_grany(x,(y-H*I),z)))/S,
     (z+H*sum(I,0,M,F_granz(x,y,(z-H*I))))/S
   ))/N
};
#declare REFLECTION = 0.25;
#declare ROUGHNESS  = 0.05;
#declare Some_Finish = finish{ reflection REFLECTION
    diffuse 0.6 * (1 - REFLECTION)
    ambient 0.1 * (1 - REFLECTION)
    roughness ROUGHNESS
    #switch (2)
      #case (1) specular 0.25 * ((1/ROUGHNESS)+1) * REFLECTION #break
      #case (2) specular albedo REFLECTION #break
    #end
  };
//---------------------- Right Box ------------------------
#local LIC_Scale  =  0.03          ;// Scale the pattern.
#local LIC_Length = 10   *LIC_Scale;// Total length of contour
#local LIC_Samples= 20             ;// Number of samples along the contour
#local LIC_Step   = LIC_Length/LIC_Samples;
box{<-2,-2,0>,<2,2,1>
texture{
  pigment{
    color srgb<1,1,1>
  }
  normal{
    function{ LIC_F_Backward(x,y,z+Show_Gradient-1,
      LIC_Scale, LIC_Step, LIC_Samples) }
    0.25
  }
  finish{Some_Finish}
}//end texture
translate 2.1*x
}
//--------------------- Left Box ------------------------
#declare LIC_F_Leopard = function(X,Y,Z, Threhshold){(
  f_leopard(X,Y,Z)*(f_leopard(X,Y,Z)>Threhshold)
)};
#declare LIC_F_Backward_2 = function(x,y,z, S,H,N){
 sum(M,0,N-1,
   LIC_F_Ramp_Down(M,N)
  *LIC_F_Leopard(
     (x+H*sum(I,0,M,F_granx((x-H*I),y,z)))/S,
     (y+H*sum(I,0,M,F_grany(x,(y-H*I),z)))/S,
     (z+H*sum(I,0,M,F_granz(x,y,(z-H*I))))/S, 0.6
   ))/N
};
#local LIC_Scale  =  0.06          ;// Scale the pattern used.
#local LIC_Length = 10   *LIC_Scale;// Total length of contour
#local LIC_Samples= 20             ;// Number of samples along the contour
#local LIC_Step   = LIC_Length/LIC_Samples;
box{<-2,-2,0>,<2,2,1>
texture{
  pigment{
    function{1-2*LIC_F_Backward_2(x,y,z+Show_Gradient-1,
      LIC_Scale,LIC_Step,LIC_Samples)}
  }
  finish{Some_Finish}
}//end texture
translate -2.1*x
}


Post a reply to this message


Attachments:
Download 'lic.png' (251 KB)

Preview of image 'lic.png'
lic.png


 

From: waggy
Subject: Re: Line Integral Convolution (LIC)
Date: 26 Apr 2013 13:20:01
Message: <web.517ab73d4a36c23821be1230@news.povray.org>
> //Line Integral Convolution Pattern Functions
> #declare LIC_F_Forward = function(x,y,z, S,H,N){
>  sum(M,0,N-1,
>    LIC_F_Ramp_Down(M,N)
>   *LIC_F_Pattern(
>      (x+H*sum(I,0,M,F_granx((x+H*I),y,z)))/S,
>      (y+H*sum(I,0,M,F_grany(x,(y+H*I),z)))/S,
>      (z+H*sum(I,0,M,F_granz(x,y,(z+H*I))))/S
>    ))/N

I should note that this method of gradient ascent isn't correct, but seems to
provide a reasonable approximation. AFAICT, A correct SDL implementation would
need to use a recursive function, or a macro to build a proper ascent function.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.