Parallel graphics computing

I am currently working on a game in Java. For this project I have been looking into generating asteroid and planet textures procedurally. The functions below works pretty well, in fact it does exactly what I intend it to do and I am very pleased with the results. The object generates the graphic once while it initializes and then stores the BufferedImage for later rendering.

Since it is a 3D noise I am using (OpenSimplexNoise) it is very easy to implement a sort of animation in my graphic. By increasing the i variable and re-generating my graphic on every frame i can "animate" through the 3D noise, making for a really neat effect. This, however is very taxing as it has to iterate through every pixel of every graphic on every frame.

Here in lays my issue, and subsequent question. Is there a was to accelerate this with a GPU using a library like LWJGL? I have been trying to read up on LWJGL and other OpenGL libraries, but to no avail. Since every cycle is independent of the previous calculation in the loop I would guess that this is a perfect target for parallel computing, I am just unsure how to do it.

Another way to lower the computation time would be to just lower the "resolution" of the rendered image or lowering the amount of updates to something like one every second but I'm not too keen on any of these solutions.

TL:DR Parallel computing of graphics made easy in Java?

Two pictures of the current algorithm in action:
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/60422.html

上一篇: 渲染循环与显式调用更新方法

下一篇: 并行图形计算