Minecraft Wiki
Advertisement

Prior to Java Edition 1.5 snapshot 13w02a,[more information needed] the textures for animated blocks were generated on-the-fly using certain algorithms, rather than being defined image files.

In cases such as when the texture could not be loaded, dedicated placeholder textures would be loaded instead.

Blocks[]

Fire[]

This section of the article is empty. 
You can help by adding to it.

Nether portals[]

Due to the large number of Atan2 and Sine operations, all of the animation frames for the portal block are generated once at-startup, with each frame's data being stored in an array of all the frames.

To generate a frame of the Nether portal animation:

   Assume width = 16, height = 16, and frame_count = 32. Additionally, assume {hw, hh} = {width / 2, height / 2}, rounding down.
   for every frame, with frame_index being the iterator:
       for every pixel, with {x, y} being the iterators:
           let float n = 0
           
           // we repeat this twice to create two spirals. one rotating clockwise and another offset
           // to the top right of our position that rotates anti-clockwise. This is so the texture can
           // tile reasonably well (at this low resolution).
           
           repeat twice, with i being the iteration:
               let floats {spiral_x, spiral_y} = ({x, y} - (i * {hw, hh})) / {w, h} * 2.
               if {spiral_x, spiral_y} is less than -1, add 2. If greater or equal to 1, subtract 2
               
               let float mag = power(spiral_x, 2) + power(spiral_y, 2)
               
               let float out_spiral = atan2(spiral_y, spiral_x)
               
               // Normalize the frame's index into a 0-1 range, and then into an angle from 0-360 (as radians)
               // Mag is subtracted from this equation to cause the spiral arms to constrict with distance from the centre
               // (i * 2 - 1) will multiply out_spiral by -1 if i is 1.
               out_spiral += ((frame_index / frame_count * PI * 2) - (mag * 10) + (i * 2)) * (i * 2 - 1)
               
               // this will bring the results of the sine operation into the range of 0 to 1 rather than -1 to 1
               out_spiral = sin(out_spiral) * 0.5 + 0.5
               
               // make the intensity of the spiral's arms diminish with distance from the centre.
               out_spiral /= mag + 1
               
               // since we're generating two spirals, we divide by 2 so that the final range is 0 to 1 instead of 0 to 2.
               n += spiral / 2
           
           // make the spirals shimmer slightly at random
           n += random(0.0, 1.0) * 0.1
           
           let byte r = floor(n * n * 200 + 55)
           let byte g = floor(power(n, 4) * 255)
           let byte b = floor(n * 100 + 155)
           let byte a = b
           
           frames[frame_index].frame_data.rgba at {x, y} = {r, g, b, a}

Note that Minecraft performs almost all of its color calculations in linear space, and only applies gamma correction near the end of rendering. If your Nether portal's colors appear to be off, apply a gamma correction of 2.2.

Gears[]

Code which generates the frames of the gear texture can be found here.

The animation for gears was generated using two predefined image files - misc/gear.png for the rotating gear and misc/gearmiddle.png for the stationary center.

The animation, updated every game tick,[1] is rendered as a 16x16 texture like most other blocks. The resulting gear has 18.75 RPM.[1]

There are two different animations used for gears - one for clockwise rotation, and another for anticlockwise rotation, to allow for logical meshing. These are generated effectively identically, with the only difference being the direction of rotation; both start on the same frame, but cycle through them in the opposite direction.[1]

Fluids[]

Fluid textures are generated via 3-layer non-deterministic cellular automata, which modify the RGB and alpha values of the texture accordingly,[2] along with shifting of the texture to emulate flowing. Each layer is represented as an array of floats, each with 256 elements, corresponding to the 256 (16x16) texture pixels within the block.[2]

As can be seen when loading up a world with water or lava in view, the textures start as a solid color before the cellular automaton starts generating the texture.

Indexes which end up outside of the bounds of the texture reappear at the opposite respective side.[2]

For the purposes of explanation, the variables used have been named (arbitrarily) as attributes of a boiling pot of soup over a fire.[2] The first layer represents the flame_heat value (which can be either negative or positive), the second layer represents the pot_heat value and the third layer represents the soup_heat value.

Note that Java Edition and Bedrock Edition used different pseudorandom generators for generating all random numbers in the game (Java Edition using a LCG whereas Pocket Edition used a MT19937), which includes the random numbers used for water and lava. Due to being random, however, this likely has negligible visual impact.

Water[]

Still water[]

Adapted from https://github.com/UnknownShadow200/ClassiCube/wiki/MInecraft-Classic-lava-animation-algorithm#water

Every frame, for each position in the still water texture array, the respective values for soup_heat, pot_heat and flame_heat are calculated as detailed below:

  • Calculates a local_soup_heat equal to the sum of the 3x1 soup_heat neighborhood around the current element.
  • Calculates the new soup_heat as the sum of the local_soup_heat divided by 3.3F plus the pot_heat times 0.8F
  • Calculates the new pot_heat as the current pot_heat plus the flame_heat times 0.05. pot_heat is clamped to a minimum of 0.
  • Calculates the new flame_heat as the current flame_heat minus 0.1F.
    • However, there is a 0.05 in 1 random chance that flame_heat is set to 0.5.

Once the above arrays have been updated, for each pixel in the water texture, the color and alpha values are calculated based on soup_heat:

  • Calculates a color_heat as the soup_heat clamped between 0 and 1 inclusive.
  • Then it calculates the color components of the pixel as follows:
    • float red = 32 + color_heat^2 * 32
    • float green = 50 + color_heat^2 * 64
    • float blue = 255
    • float alpha = 146 + color_heat^2 * 50

The red, green and blue values are then converted to bytes and assigned to the texture accordingly.

Flowing water[]

This section is missing information about how the flowing texture was generated - presumably similarly to still water. 
Please expand the section to include this information. Further details may exist on the talk page.

In addition, the flowing water texture also uses a spatial translation to give the appearence of movement. This transformation moves the flowing water texture downwards by one pixel after a fixed amount of time,[more information needed] wrapping the bottom layer of the texture back to the top.

Lava[]

This section is missing information about c0.0.19a era lava. 
Please expand the section to include this information. Further details may exist on the talk page.

Still lava[]

Adapted from https://github.com/UnknownShadow200/ClassiCube/wiki/MInecraft-Classic-lava-animation-algorithm#lava

Every frame, for each position in the still water texture array, the respective values for soup_heat, pot_heat and flame_heat are calculated as detailed below:

  • Calculates a local_soup_heat equal to the sum of the 3x3 soup_heat neighborhood around the current element but offset vertically by colSin******* and offset horizontally by rowSin*********.
    • rowSin is 1.2 times the sign of an angle that starts at 0 and changes by 22.5 degrees every row.
    • colSin is 1.2 times the sign of an angle that starts at 0 and changes by 22.5 degrees every column.
  • Calculates a local_pot_heat equal to the sum of a 2x2 pot_heat neighborhood around the current pot_heat, with the current position being the upper left of the 2x2 neighborhood.
  • Calculates the new soup_heat as the sum of the local_soup_heat divided by 10 plus the local_pot_heat divided by 4 times 0.8.
  • Calculates the new pot_heat as the current pot_heat plus the flame_heat times 0.01***************. pot_heat is clamped to a minimum of 0.
  • Calculates the new flame_heat as the current flame_heat minus 0.06.
    • However, there is a 0.005 in 1 random chance that flame_heat is set to 1.5.

Once the above arrays have been updated, for each pixel in the lava texture, the color values are calculated based on soup_heat (alpha is always opaque for lava):

  • Calculates a color_heat as double the soup_heat clamped between 0 and 1 inclusive.
  • Then it calculates the color components of the pixel as follows:
    • float red = color_heat * 100F + 155F
    • float green = color_heat^2 * 255F
    • float blue = color_heat^4 * 128F

The red, green and blue values are then converted to bytes and assigned to the texture accordingly.

Flowing lava[]

Flowing lava uses the exact same texture as still lava, however there is also a spatial translation to give the appearence of movement. This transformation moves the lava texture downwards by one pixel after a fixed amount of time,[more information needed] wrapping the bottom layer of the texture back to the top.

Items[]

Clocks[]

To generate its appearances, the clock combined 2 textures, one being the actual clock, and the other being the dial.

The clock's texture could be changed without worrying about breaking the dial, as long as the transparency remained unaffected.[more information needed]

This texture combination allowed for clocks to be very precise, having 228 visually distinct frames. The animated texture approach, used in 1.5 onwards, is far less precise, with only 64 different frames.

Compasses[]

This section of the article is empty. 
You can help by adding to it.


References[]

Advertisement