|
 |
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
|
 |