Ok. So there was a bit more thought involved in this than I anticipated. I got a result, but it comes with an explanation:
The algorithm in that application normalizes the whole image - it gets the lowest value and the highest value and uses it as a scale for min-max (so if the colors only ever get to 0.8f - that will be the new 1.0 - and so everything becomes âlighterâ). In my image you see a lot of darker areas, and in your reference image itâs a lot lighter - and itâs because of that. But actually you donât want this with procedural generated worlds because it wonât join seamlessly. If my co-ordinates were 20 pixels to the right, the whole image might be slightly lighter or darker. The max brightness of a color might only be 0.7 now or even 0.9 and so the whole image will âshiftâ a bit lighter or darker.
You can toy with each layers scale, frequency, etc⌠to play around with which texture will be displayed more or less frequently.
I also had to update the fastnoise library, so youâll need to reference version 1.0.2
now (its already on jcenter).
Anyway, hereâs my result.
package com.jayfella.jme.fastnoise.debug;
import com.jayfella.fastnoise.FastNoise;
import com.jayfella.fastnoise.GradientPerturb;
import com.jayfella.fastnoise.LayeredNoise;
import com.jayfella.fastnoise.NoiseLayer;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.material.Materials;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Quad;
import com.jme3.system.AppSettings;
import com.jme3.texture.Image;
import com.jme3.texture.Texture2D;
import com.jme3.texture.image.ImageRaster;
import com.jme3.util.BufferUtils;
public class Main extends SimpleApplication {
private LayeredNoise layeredNoise;
private int sizeX, sizeY;
private ImageRaster textureRaster;
public static void main(String... args) {
Main main = new Main();
AppSettings appSettings = new AppSettings(true);
appSettings.setFrameRate(120);
appSettings.setResolution(1280, 720);
main.setSettings(appSettings);
main.start();
}
@Override
public void simpleInitApp() {
sizeX = cam.getWidth();
sizeY = cam.getHeight();
flyCam.setMoveSpeed(100);
flyCam.setDragToRotate(true);
Image image = new Image();
image.setWidth(sizeX);
image.setHeight(sizeY);
image.setFormat(Image.Format.BGRA8);
image.setData(BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 4));
textureRaster = ImageRaster.create(image);
Texture2D texture = new Texture2D(image);
Geometry textureGeom = new Geometry("Noise", new Quad(sizeX, sizeY));
textureGeom.setMaterial(new Material(assetManager, Materials.UNSHADED));
textureGeom.getMaterial().setTexture("ColorMap", texture);
initNoise();
generateTexture();
guiNode.attachChild(textureGeom);
}
private NoiseLayer createLayer() {
NoiseLayer layer = new NoiseLayer("Layer");
layer.setFrequency(0.02f);
layer.setInterp(FastNoise.Interp.Quintic);
layer.setFractalOctaves(5);
layer.setFractalLacunarity(1.7f);
layer.setFractalGain(0.6f);
layer.setSeed(FastMath.nextRandomInt());
layer.setNoiseType(FastNoise.NoiseType.PerlinFractal);
//layer.setGradientPerturb(GradientPerturb.Fractal);
layer.setFractalType(FastNoise.FractalType.FBM);
layer.setGradientPerturbAmp(20);
return layer;
}
private void initNoise() {
layeredNoise = new LayeredNoise();
NoiseLayer red = createLayer();
layeredNoise.addLayer(red);
NoiseLayer green = createLayer();
layeredNoise.addLayer(green);
NoiseLayer blue = createLayer();
layeredNoise.addLayer(blue);
}
float noiseScale = 0.75f;
private void generateTexture() {
for (int x = 0; x < sizeX; x++) {
for (int y = 0; y < sizeY; y++) {
Vector3f f = new Vector3f(x * noiseScale, y * noiseScale, 0.5f);
f.x -= x;
f.y -= y;
f.z -= 0.5f;
layeredNoise.getLayers().get(0).getPrimaryNoise().GradientPerturbFractal(f);
layeredNoise.getLayers().get(1).getPrimaryNoise().GradientPerturbFractal(f);
layeredNoise.getLayers().get(2).getPrimaryNoise().GradientPerturbFractal(f);
// toy with this to increase the brightness.
float scale = 1.0f;
float r = Math.max(0, Math.min(1, layeredNoise.getLayers().get(0).getPrimaryNoise().GetNoise(f.x, f.y, f.z) * scale));
float g = Math.max(0, Math.min(1, layeredNoise.getLayers().get(1).getPrimaryNoise().GetNoise(f.x, f.y, f.z) * scale));
float b = Math.max(0, Math.min(1, layeredNoise.getLayers().get(2).getPrimaryNoise().GetNoise(f.x, f.y, f.z) * scale));
ColorRGBA color = new ColorRGBA(r, g, b, 1.0f);
textureRaster.setPixel(x, y, color);
}
}
}
}
Edit: I noticed a bug. Iâve updated the code here.