opengtl / shiva-collections (http://opengtl.org/)

No description has been added.

commit 29: 0211a21cfd52
parent 28: e70566ce05d1
branch: default
add a metaball generator
Cyrille Berger
5 months ago

Changed (Δ1.8 KB):

raw changeset »

generators/Metaball.shiva (74 lines added, 0 lines removed)

Up to file-list generators/Metaball.shiva:

1
<
2
  parameters: <
3
    metaballs: <
4
      label: "Number of metaballs";
5
      type: int;
6
    >;
7
    radius: <
8
      label: "Radius";
9
      type:float;
10
      defaultValue: 0.05;
11
    >;
12
    ringradius: <
13
      label: "Ring radius";
14
      type:float;
15
      defaultValue: 0.03;
16
    >;
17
    outsidecolor: <
18
      label: "Outside color";
19
      type: rgba;
20
      defaultValue: { 0.0, 0.0, 0.0, 1.0 };
21
    >;                                                                        
22
    metaballcolor: <
23
      label: "Metaball color";
24
      type: rgba;
25
      defaultValue: { 0.0, 1.0, 0.0, 1.0 };
26
    >;                                                                        
27
    
28
  >;
29
>;
30
kernel Metaball
31
{
32
  dependent float2 centers[ metaballs ];
33
  dependent float pxradius, pxringradius;
34
  void evaluateDependents()
35
  {
36
    int image_size = min(IMAGE_WIDTH, IMAGE_HEIGHT);
37
    pxradius = radius * image_size;
38
    pxringradius = ringradius * image_size;
39
    const float RAND_MAX  = 2147483647;
40
    for(int i = 0; i < metaballs; ++i)
41
    {
42
      centers[i].x = rand() / RAND_MAX * IMAGE_WIDTH;
43
      centers[i].y = rand() / RAND_MAX * IMAGE_HEIGHT;
44
    }
45
  }
46
  void evaluatePixel(out pixel4 result)
47
  {
48
    result = outsidecolor;
49
    float maxv = 1.1;
50
    for(int i = 0; i < metaballs; ++i)
51
    {
52
      float2 vec = result.coord - centers[i];
53
      float angle = atan2( vec.x, vec.y);
54
      float r = length(vec);
55
      if(r < pxradius )
56
      {
57
        result = outsidecolor;
58
        i = metaballs;
59
      } else if( r < (pxradius + pxringradius)) {
60
        float v = (r - pxradius) / pxringradius;
61
        if(v < maxv)
62
        {
63
          result = ( (1.0 - v) * metaballcolor + v * outsidecolor );
64
          maxv = v;
65
        }
66
      }
67
    }
68
  }
69
  region generated()
70
  {
71
    region reg = { 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT};
72
    return reg;
73
  }
74
}