并行图形计算
我目前正在使用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