Hi,
I’m trying to generate a procedural texture based on a heightmap and a collection of images that have a low, optimal, and high value. Where the final image is a blending of these textures depending on the height of the heighmap. I’m having a bit of a brain fart though as how to best get the colors. Here is the class as it stands now, please note the commented section in createTexture() as this is where my main problem lies…
package monkey.texture;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import monkey.locale.external.AbstractHeightMap;
public class ProceduralTexture {
private ImageIcon proceduralTexture;
private AbstractHeightMap heightMap;
private ArrayList textureList;
private int size;
public ProceduralTexture(AbstractHeightMap heightMap) {
textureList = new ArrayList();
this.heightMap = heightMap;
this.size = heightMap.getSize();
}
public void createTexture() {
BufferedImage img = new BufferedImage(size,size,
BufferedImage.TYPE_INT_RGB);
float red = 0.0f;
float green = 0.0f;
float blue = 0.0f;
for(int x = 0; x < size; x++) {
for(int z = 0; z < size; z++) {
for(int i = 0; i < textureList.size(); i++) {
//0 to 1 scalar, how much to use.
float scalar =
getTextureScale(heightMap.getTrueHeightAtPoint(x,z), i);
//red += texture(i)'s red value * scalar;
//green += texture(i)'s green value * scalar;
//blue += texture(i)'s blue value * scalar;
}
//set img's (x,z) pixel to (red,green,blue).
//red = green = blue = 0
}
}
//create ImageIcon proceduralTexture from img.
}
public void addTexture(ImageIcon image, int low, int optimal, int high) {
BufferedImage img = new BufferedImage(image.getIconWidth(),
image.getIconHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D)img.getGraphics();
g.drawImage(image.getImage(), null, null);
g.dispose();
TextureTile tile = new TextureTile();
tile.highHeight = high;
tile.optimalHeight = optimal;
tile.lowHeight = low;
tile.imageData = img;
textureList.add(tile);
}
public ImageIcon getImageIcon() {
return proceduralTexture;
}
private float getTextureScale(int height, int tileIndex) {
TextureTile tile = (TextureTile)textureList.get(tileIndex);
if(height < tile.optimalHeight && height > tile.lowHeight) {
return ((float)(height - tile.lowHeight)) /
(tile.optimalHeight - tile.lowHeight);
} else if(height > tile.optimalHeight && height < tile.highHeight) {
return ((float)(tile.highHeight - height)) /
(tile.highHeight - tile.optimalHeight);
} else if(height == tile.optimalHeight) {
return 1.0f;
} else {
return 0.0f;
}
}
private class TextureTile {
public BufferedImage imageData;
public int lowHeight;
public int optimalHeight;
public int highHeight;
}
}
I’m handling everything as BufferedImages right now, but if there is a better way to go about it, please by all means let me know.