并行图形计算

我目前正在使用Java开发一款游戏。 对于这个项目,我一直在研究在程序上产生小行星和行星纹理。 下面的功能工作得很好,实际上它完全符合我打算做的事情,我对结果非常满意。 该对象在初始化时会生成一次图形,然后存储BufferedImage以供以后呈现。

由于它是我使用的3D噪声(OpenSimplexNoise),因此在我的图形中实现一种动画非常容易。 通过增加i变量并在每帧上重新生成我的图形,我可以通过3D噪声“动画”,从而获得非常好的效果。 然而,这是非常重要的,因为它必须遍历每一帧的每个图形的每个像素。

这里列出了我的问题和后续问题。 使用像LWJGL这样的库,是否需要使用GPU进行加速? 我一直在尝试阅读LWJGL和其他OpenGL库,但无济于事。 由于每个循环独立于循环中的先前计算,所以我猜测这是并行计算的完美目标,我只是不确定如何去做。

降低计算时间的另一种方法是降低渲染图像的“分辨率”或将更新量降低到每秒一次,但我不太喜欢这些解决方案。

TL:DR在Java中,图形的并行计算变得简单了吗?

当前算法的两张图片:
henriknilsson.ml/2017-01-21%2022'49.PNG
henriknilsson.ml/2017-01-21%2023'20.PNG

Planet.generateGraphic

private static BufferedImage generateGraphic(int seed, double radius, double i){
    BufferedImage image = new BufferedImage((int)radius * 2, (int)radius * 2, BufferedImage.TYPE_4BYTE_ABGR);

    Random r = new Random(seed);

    //Select two random colors

    int cr = r.nextInt(256);
    int cg = r.nextInt(256);
    int cb = r.nextInt(256);

    Color color = new Color(cr, cg, cb);

    cr *= r.nextDouble() + 0.5;
    cg *= r.nextDouble() + 0.5;
    cb *= r.nextDouble() + 0.5;

    if(cr > 255)cr = 255;
    if(cg > 255)cg = 255;
    if(cb > 255)cb = 255;

    Color color2 = new Color(cr, cg, cb);

    OpenSimplexNoise osn = new OpenSimplexNoise(seed);
    double modifierx = r.nextDouble() * 5 + radius / 5;
    double modifiery = modifierx;

    double limit1 = 0.15;
    double limit2 = 0.05;

    //Offset the x and y modifiers for a Gas-giant "look"

    if(r.nextBoolean()){
        modifierx *= r.nextInt(8) + 4;
        modifiery /= 2;
    }

    //Itterate through every pixel

    for(int x = 0; x < image.getWidth(); x++){
        for(int y = 0; y < image.getWidth(); y++){
            double distance = Math.sqrt((x - radius) * (x - radius) + (y - radius) * (y - radius));

            if(distance > radius){
                image.setRGB(x, y, 0);
            }
            else{
                Color c;
                float noise = (float)osn.eval(x / modifierx, y / modifiery, i);

                if(noise > limit1){
                    c = color;
                }
                else if (noise > limit2){
                    float alpha = (float)(1 - (noise - limit2) / (limit1 - limit2)); 
                    c = Functions.blend(color, color2, alpha);
                }
                else{
                    c = color2;
                }

                float red = (float)c.getRed() / 255;
                float green = (float)c.getGreen() / 255;
                float blue = (float)c.getBlue() / 255;


                //Random offset
                double q = (((double)r.nextInt(81) + 960) / 1000);

                //Shadow
                double s = (Math.sqrt(radius * radius - distance * distance + 250) / radius);

                red *= q;
                green *= q;
                blue *= q;

                red *= s;
                green *= s;
                blue *= s;

                //Limit values
                if(red > 1)red = 1;
                if(green > 1)green = 1;
                if(blue > 1)blue = 1;

                image.setRGB(x, y, new Color(red, green, blue).getRGB());
            }
        }
    }
    return image;
}

Functions.blend

public static Color blend(Color c1, Color c2, float ratio) {
    if ( ratio > 1f ) ratio = 1f;
    else if ( ratio < 0f ) ratio = 0f;
    float iRatio = 1.0f - ratio;

    int i1 = c1.getRGB();
    int i2 = c2.getRGB();

    int a1 = (i1 >> 24 & 0xff);
    int r1 = ((i1 & 0xff0000) >> 16);
    int g1 = ((i1 & 0xff00) >> 8);
    int b1 = (i1 & 0xff);

    int a2 = (i2 >> 24 & 0xff);
    int r2 = ((i2 & 0xff0000) >> 16);
    int g2 = ((i2 & 0xff00) >> 8);
    int b2 = (i2 & 0xff);

    int a = (int)((a1 * iRatio) + (a2 * ratio));
    int r = (int)((r1 * iRatio) + (r2 * ratio));
    int g = (int)((g1 * iRatio) + (g2 * ratio));
    int b = (int)((b1 * iRatio) + (b2 * ratio));

    return new Color( a << 24 | r << 16 | g << 8 | b );
}
链接地址: http://www.djcxy.com/p/60421.html

上一篇: Parallel graphics computing

下一篇: GameDev : Engine/Graphics API/Custom?