# Low-resolution Procedural Textures With Minecraft Blocks

The techniques mathematicians and engineers use to approximate or simulate natural processes are fascinating. Fascinating because they increase our understanding of how the world works around us, and because they can often be used to solve seemingly unrelated problems. For example consider particle swarms which can be used to simulate flocks of birds or insects, but also can be used to quickly and iteratively optimize problems. L-systems can be used to simulate the growth of plants, but also can be used to create fractals not found in the botanical world.

Another popular technique we use to simulate nature is adding noise to synthetic textures in video games to increase the realism of objects. For example, the texture below could be a closeup of a grain of wood or marbling from a rock:

75 x 40 block rectangle texture

To generate a texture like this we start with a striped texture like a barber’s pole and than add turbulence, which is just another way of saying “Hey you, add a couple different layers of variously zoomed noise to the color value of each block!” Now when I say noise I am referring to a method of generating random values between 0 and 1 that takes the x and y coordinates of blocks as input. Of course some random values are better than others for generating textures.

Low zoom factor makes for a less smooth texture.

This is a 50 x 50 block shot of a texture which was generated using a method called Simplex noise. Simplex noise is a special type of noise first developed by Ken Perlin (of Perlin noise fame). We are using Simplex noise here because it is fast, the Bukkit API has already implemented it for us, and because it has the special property of creating visual artifacts of about the same size which lets us control it to for interesting results.

The results captured here are interesting, but since they were created in Minecraft there are some limitations–namely, we have a severely limited palette of colors. I choose to only use wool since the colors are solid and their internal IDs are contiguous; however, you could probably create some neat textures using all available Minecraft block types.

Wool Block IDs

In the pics above I only used 4 colors of wool: white, light gray, gray, and black. If you use all 16 wool colors you get textures like the one below:

Colored marble

Yet another colored marble

The code I used to create these textures is below. Copy and drop the file into your js-plugins folder to install it. All of the turbulence parameters should be tinkered with to experiment with the various textures you can make. Tinkering with the make_discrete function to change the palette is also fun.

 /* * usage: /js generate_texture(width, height) * * notes: comment out one of the blocks in the generate_texture method to get started * or play with the make_discrete function to get different colors. */ load(__folder + "core/scriptcraft.js"); function make_discrete(noise){ var val = parseInt(noise)+1; // uncomment below for grayscale /*if(val <= 4){ return "35"; } else if(val > 4 && val <= 8){ return "35:7" } else if(val > 8 && val <= 12){ return "35:8" } else{ return "35:15" }*/ // colored wool-scale return "35:" + Math.abs( parseInt(noise) + 1); } function turbulence(x, z, size){ var value = 0.0; var initialSize = size; while(size >= 1){ value += org.bukkit.util.noise.SimplexNoiseGenerator.getInstance().getNoise(x/size,z/size)*size; size /= 2.0; } return(8.0 * value / initialSize); } function generate_texture(w,h){ var d = new Drone(); var x0,z0; x0 = d.x; z0 = d.z; // adjust the params below to create different textures var xPeriod = 5.0; var yPeriod = 10.0; // increases the turbulence's effect var turbPower = 5.0; // smaller turbSizes zooms the texture in and larger turbSizes zooms out var turbSize = 256.0; var xyPeriod = 5.0; for(var x = x0; x < x0+w; x++){ d.chkpt("l0"); for(var z = z0; z < z0+h; z++){ /* uncomment one of the blocks below to start creating textures */ /* below examples are largely based off examples from http://lodev.org/cgtutor/randomnoise.html */ /* straight simplex noise */ /* var value = org.bukkit.util.noise.SimplexNoiseGenerator.getInstance().getNoise(d.x,d.z)*15; */ /* marbled texture */ /* var xyValue = x * xPeriod / h + z * yPeriod / w + turbPower * turbulence(x, z, turbSize) / 15.0; var value = 15 * Math.abs(Math.sin(xyValue * 3.14159)); */ /* wooden texture (doesn't generate rings though) */ /* var xValue = (x – h / 2) / h*1.0; var zValue = (z – w / 2) / w*1.0; var distValue = Math.sqrt(xValue * xValue + zValue * zValue) + turbPower * turbulence(x, z, turbSize) / 15.0; var value = 7.0 * Math.abs(Math.sin(2 * xyPeriod * distValue * 3.14159)); */ d.box(make_discrete(value)).right(); } d.move("l0").fwd(); } }

view raw
texture-fun.js
hosted with ❤ by GitHub