POV-Ray : Newsgroups : povray.off-topic : New CA Simulation : Re: Thanks! Server Time
3 Sep 2024 21:19:09 EDT (-0400)
  Re: Thanks!  
From: stbenge
Date: 31 Jan 2011 20:07:51
Message: <4d475ce7@news.povray.org>
On 1/31/2011 2:49 PM, Thibaut Jonckheere wrote:

>> Thank you all for your input! I'd still like to hear any comments you
>> might have, if you can take the time.
>
> A few things I like particularly:
>
> - the different 'timescales' : after a click with the mouse, there is
> the rapid process destroying the cell, but the system takes a long time
> to reach a steady state as a whole

Well... cellular automaton simulations are an entirely natural process, 
so these things happen as a matter of consequence. As to just 
/what/exactly/ is being modeled is determined by the purity of the 
calculations. I know that some of my calculations have resulted in an 
approximation of a minimal surface, but others were added to increase 
growth. So maybe we have a biological organism with a lot of mucus...

> - I enjoy a lot when 'thin white lines' enter a big cell, and propagate
> slowly with successive branching, changing in the end a big part of the
> entire geometry.

That's one of the things that puts this sim into its own category. What 
you are seeing is related to reaction/diffusion and minimal surface 
systems, but I really don't think that its behavior is indicative of a 
"pure" minimal surface.

> I spent more time with it, and it is really fascinating ! It looks a lot
> like some sort of physical/biological process. If you can give some
> qualitative information on the way the algorithm works, I'll be very
> interested.

I can't really explain what I did. I know *what* I did, and *why* it 
does it, but ask me to put it into scientific or mathematical terms, and 
you won't get a satisfactory answer.

But here's the GLSL code. I'll attempt to provide useful descriptions:

// these uniform variables are piped in from the governing program:
uniform sampler2D bufA; // a 768x768 16-bit surface
uniform vec2 offset;    // offset.s = 1/768, offset.t = 1/768
uniform int DoPaint;    // is the mouse clicked? (a boolean would be better)
uniform float MX, MY, RX, RY; // mouse X/Y, random values X/Y

// variables for the red, green & blue components
float R, G, B;

// CA      = blur sample
// C0 - C8 = point samples
vec4 CA, C0, C1, C2, C3, C4, C5, C6, C7, C8;

// a noise function (not mine, used for adding noise to Area_Add[below])
float rand(vec2 UV){
  return

  fract(
   sin(
    dot(
     vec2(
      UV.x+RX,
      UV.y+RY
     ),
     vec2(12.9898,78.233)
    )
   )*43758.5453
  );
}

void main(void){

   float dx = offset.s; // 1/768
   float dy = offset.t; // 1/768

   // UV.x = 0.0 to 1.0, UV.y = 0.0 to 1.0
   vec2  UV = gl_TexCoord[0].st;

   // expansion vector (realized with POV)
   // uses the green channel
   vec2 Expansion =
    .0625*vec2(
      texture2D( bufA, UV + .5*vec2(-dx, 0.0) ).g
     -texture2D( bufA, UV + .5*vec2(dx, 0.0) ).g,
      texture2D( bufA, UV + .5*vec2(0.0, -dy) ).g
     -texture2D( bufA, UV + .5*vec2(0.0, dy) ).g
    );

   // applying the expansion to "UV"
   UV += 1.0*Expansion*(texture2D( bufA, UV).g);

   // center sample
   C0 = texture2D( bufA, UV);

   // samples clockwise from upper-left
   // total (with C0): 1 + 2 + .92 = 3.92 (values are also thanks to POV)
   C1 = texture2D( bufA, UV + vec2(-dx, -dy) )*0.23;
   C2 = texture2D( bufA, UV + vec2(0.0, -dy) )*0.5;
   C3 = texture2D( bufA, UV + vec2(+dx, -dy) )*0.23;
   C4 = texture2D( bufA, UV + vec2(+dx, 0.0) )*0.5;
   C5 = texture2D( bufA, UV + vec2(+dx, +dy) )*0.23;
   C6 = texture2D( bufA, UV + vec2(0.0, +dy) )*0.5;
   C7 = texture2D( bufA, UV + vec2(-dx, +dy) )*0.23;
   C8 = texture2D( bufA, UV + vec2(-dx, 0.0) )*0.5;

   // blur sample
   CA = (C0+C1+C2+C3+C4+C5+C6+C7+C8)/3.92;

   if(DoPaint==1){ // paint circular area

    // adds a noisy, circular density when the mouse is clicked
    float Area_Add =
     rand(UV)*clamp(
      1.0-16.0*sqrt( pow(UV.x-MX, 2.0) + pow(UV.y-MY, 2.0) ),
      0.0,
      1.0
     );

    // adds a noisy, circular density when the mouse is clicked
    R = clamp(CA.r + .05*Area_Add, 0.0, 1.0);

    // green is given a blurred version of the red channel
    G = CA.r;

    // blue is given a blurred version of its own channel
    B = CA.b;

   }else{          // return the usual values

    R = CA.r;
    G = CA.r;
    B = CA.b;

   }

   // edge-finding
   B = C0.r+(C0.r-CA.r)*760.0;

   // mix old values with squared edge values
   // ("mix" is the same as a linear interpolation["lerp"])
   B = mix(CA.b, B*B, .025);

   // add blurred edges to primary evaluation channel
   // and decrease all red values over time
   R = R + .045*CA.b - .0203065;

   // subtract blurred edge values from the green channel
   G = G - .107*CA.b;

   // prevent values from going below 0.0 (black) or above 1.0 (white)
   R = clamp(R, 0.0, 1.0);
   G = clamp(G, 0.0, 1.0);
   B = clamp(B, 0.0, 1.0);

   // carry values over to next iteration
   gl_FragColor = vec4(R, G, B, 1.0);

}


Post a reply to this message

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