Joined: February 18th, 2007, 1:28 pm Posts: 598 Location: Mother's basement
RS Name:Nightgunner5 RS Status: P2P
Clan Name:Bits and Bytes
I've been very interested in the way RuneScape's terrain textures work. I heard on an RSBandBUpdate! that there are no images, only noise plus a special mathematical formula. So far, I've made something that looks very similar to the Grand Exchange's tiled floor using nothing but Simplex noise and some algebra.
tile-0-gray.png tile-0-blue.png (looks like the wizard in Ardougne's floor to me) tile-1-gray.png
Code:
TileTextureGenerator gen; BufferedImage img; gen = new TileTextureGenerator(0); img = gen.render(0, 0, 512, 512, 4, Color.GRAY); ImageIO.write(img, "png", new File("tile-0-gray.png")); img = gen.render(0, 0, 512, 512, 4, new Color(0x9DCBE3)); ImageIO.write(img, "png", new File("tile-0-blue.png")); gen = new TileTextureGenerator(1); img = gen.render(0, 0, 512, 512, 4, Color.GRAY); ImageIO.write(img, "png", new File("tile-1-gray.png"));
public abstract class AbstractTextureGenerator { private final long seed;
public AbstractTextureGenerator(long seed) { this.seed = seed; }
protected final Random getSeed() { return new Random(seed); }
protected final SimplexOctaveGenerator getNoise(Random seed, int octaves) { return new SimplexOctaveGenerator(seed, octaves); }
public final BufferedImage render(int x, int y, int width, int height, int step, Color base) { BufferedImage image = new BufferedImage(width * step, height * step, BufferedImage.TYPE_INT_RGB); int r = base.getRed(); int g = base.getGreen(); int b = base.getBlue();
byte[] tones = generate(x, y, width, height, step);
for (int i = 0; i < width * step; i++) { for (int j = 0; j < height * step; j++) { image.setRGB(i, j, getRGB(r, g, b, tones[i * width * step + j])); } }
return image; }
// Doesn't work very well, if at all. public final BufferedImage render3D(Color base, int width, int height, double cameraX, double cameraY, double cameraZ, double pitch, double yaw, double scale) { BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); if (cameraZ <= 0) { return image; }
int r = base.getRed(); int g = base.getGreen(); int b = base.getBlue();
for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { double tx = x / scale - cameraX; double ty = y / scale - cameraY; double tz = -cameraZ; double distance; double angle;
image.setRGB(x, y, getRGB(r, g, b, getTone(transformedX, transformedY))); } }
return image; }
private int getRGB(int r, int g, int b, byte tone) { int t = tone; if (tone < 0) { tone += 256; } tone -= 128; return (Math.min(Math.max(r + tone, 0), 255) << 16) | (Math.min(Math.max(g + tone, 0), 255) << 8) | (Math.min(Math.max(b + tone, 0), 255)); }
public final int transformRGB(int rgb, byte tone) { rgb = rgb & 0xffffff; return getRGB(rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff, tone); } protected final int mod(int n, int m) { return ((n % m) + m) % m; } protected final double mod(double n, double m) { return ((n % m) + m) % m; }
public abstract byte getTone(double x, double y); protected abstract byte[] generate(int x, int y, int width, int height, int step); }
public class TileTextureGenerator extends AbstractTextureGenerator { public static final int TILE_SIZE = 128; private final SimplexOctaveGenerator noise; private final SimplexOctaveGenerator dirty; private final SimplexOctaveGenerator dirt; private final SimplexOctaveGenerator color;
public TileTextureGenerator(long seed) { super(seed); Random r = getSeed(); color = getNoise(r, 1); dirty = getNoise(r, 1); dirt = getNoise(r, 8); dirt.setScale(1 / 16.0); noise = getNoise(r, 8); noise.setScale(1 / 32.0); }
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum