程序上生成“斑点"的好方法2D图形 [英] Good way to procedurally generate a "blob" graphic in 2D

查看:64
本文介绍了程序上生成“斑点"的好方法2D图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望以计算快速的方式创建斑点".此处的Blob定义为可以是任何形状但都连接在一起的像素的集合.例子:

I'm looking to create a "blob" in a computationally fast manner. A blob here is defined as a collection of pixels that could be any shape, but all connected. Examples:

.ooo....  
..oooo..  
....oo..  
.oooooo.
..o..o..  

...ooooooooooooooooooo...  
..........oooo.......oo..  
.....ooooooo..........o..  
.....oo..................  


......ooooooo....  
...ooooooooooo...  
..oooooooooooooo.  
..ooooooooooooooo  
..oooooooooooo...  
...ooooooo.......  
....oooooooo.....  
.....ooooo.......  
.......oo........  

在哪里.是死空间,o是标记像素.我只关心二进制"生成-像素为ON或OFF.因此,例如,它们看起来像是一些假想的番茄酱或虚构细菌或任何有机物质.

Where . is dead space and o is a marked pixel. I only care about "binary" generation - a pixel is either ON or OFF. So for instance these would look like some imaginary blob of ketchup or fictional bacterium or whatever organic substance.

什么样的算法可以做到这一点?我真的很茫然

What kind of algorithm could achieve this? I'm really at a loss

推荐答案

David Thonley的评论是正确的,但我将假设您想要一个具有有机"形状和平滑边缘的斑点.为此,您可以使用元球.Metaballs是在标量场上起作用的幂函数.使用行进立方体算法可以有效地渲染标量字段.通过更改球的数量,位置和半径可以制成不同的形状.

David Thonley's comment is right on, but I'm going to assume you want a blob with an 'organic' shape and smooth edges. For that you can use metaballs. Metaballs is a power function that works on a scalar field. Scalar fields can be rendered efficiently with the marching cubes algorithm. Different shapes can be made by changing the number of balls, their positions and their radius.

有关2D元球的介绍,请参见此处: https://web.archive.org/web/20161018194403/https://www.niksula.hut.fi/~hkankaan/Homepages/metaballs.html

See here for an introduction to 2D metaballs: https://web.archive.org/web/20161018194403/https://www.niksula.hut.fi/~hkankaan/Homepages/metaballs.html

以下是行进立方体算法的简介: https://web.archive.org/web/20120329000652/http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/

And here for an introduction to the marching cubes algorithm: https://web.archive.org/web/20120329000652/http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise/

请注意,3D中交点的256个组合仅是2D中的16个组合.这很容易实现.

Note that the 256 combinations for the intersections in 3D is only 16 combinations in 2D. It's very easy to implement.

我使用GLSL着色器整理了一个简单的示例.这是使用hkankaan主页上具有energy函数的50个blob的结果.

I hacked together a quick example with a GLSL shader. Here is the result by using 50 blobs, with the energy function from hkankaan's homepage.

这是实际的GLSL代码,尽管我评估了每个片段.我没有使用行进立方体算法.您需要渲染一个全屏四边形以使其正常工作(两个三角形).vec3统一数组只是通过 glUniform3fv 传递的各个斑点的2D位置和半径.

Here is the actual GLSL code, though I evaluate this per-fragment. I'm not using the marching cubes algorithm. You need to render a full-screen quad for it to work (two triangles). The vec3 uniform array is simply the 2D positions and radiuses of the individual blobs passed with glUniform3fv.

/* Trivial bare-bone vertex shader */
#version 150
in vec2 vertex;
void main()
{
    gl_Position = vec4(vertex.x, vertex.y, 0.0, 1.0);
}

/* Fragment shader */
#version 150
#define NUM_BALLS 50
out vec4 color_out;
uniform vec3 balls[NUM_BALLS]; //.xy is position .z is radius

bool energyField(in vec2 p, in float gooeyness, in float iso)
{
    float en = 0.0;
    bool result = false;
    for(int i=0; i<NUM_BALLS; ++i)
    {
        float radius = balls[i].z;
        float denom =  max(0.0001, pow(length(vec2(balls[i].xy - p)), gooeyness));
        en += (radius / denom);
    }
    if(en > iso)
        result = true;
    return result;
}
void main()
{
    bool outside;
    /* gl_FragCoord.xy is in screen space / fragment coordinates */
    outside = energyField(gl_FragCoord.xy, 1.0, 40.0);
    if(outside == true)
        color_out = vec4(1.0, 0.0, 0.0, 1.0);
    else
        discard;
}

这篇关于程序上生成“斑点"的好方法2D图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆