Sunday 28 December 2014

Transparent blocks [1.8]

There are two types of transparency in Minecraft - see the picture below.
The first type is "cutout" transparency, where each texel is either fully opaque or fully transparent.
The second type is "translucent" transparency, where you can see a "blend" of the ice block and the blocks behind it.


1-CUTOUT

Rendering a block with "cutout" transparent sections (eg a block of glass) is relatively straightforward.

Firstly, you need to create an image which has an alpha channel (a mask which indicates the transparent parts of the image).  There are a number of programs around which can do transparency (alpha channel) properly, a good free one is GIMP.  The image for block glass looks something like this.

BlockGlass texture - "CUTOUT" transparency - the hashed texels are transparent (alpha channel value < 10%)
Secondly, your block needs to render in the CUTOUT or CUTOUT_MIPPED layer.  See here for more information.

You can then render your block using a standard model.  For example, if the numbered cube from the texturing example is modified so that each face has an alpha channel where the white sections are made transparent:


Some important things to note:
  • You can only see faces which point in your direction.  Any faces which are pointing the other way (eg faces 2 and 0 in the pictures above) are not visible until you walk to the other side of the block (as per faces 4 and 5 above).
  • You need to override isOpaqueCube() to return false, otherwise the adjacent faces of adjacent blocks won't be rendered properly, for example see below.  For more information on the various effects of isOpaqueCube, see here.
isOpaqueCube returns true - grass under the block is not rendered
  • The transparency is either on or off - a pixel is either fully transparent or fully opaque.  For exampe - if your alpha channel has 50% transparency, it will be treated as opaque.  The threshold is 10%.

2-Translucent

Minecraft renders translucent blocks in the TRANSLUCENT layer.  The picture below shows the difference between ice rendered as TRANSLUCENT (left) or SOLID (right)

Ice rendered in TRANSLUCENT layer (left) or SOLID layer (right).

If our example cube is converted to have a striped alpha channel on the "2" face, i.e. from top to bottom 0%, 25%, 50%, 75%:
then it renders as follows in the two different transparency layers:
CUTOUT render (left) vs TRANSLUCENT render (right)
The key difference is that TRANSLUCENT renders 25%, 50%, 75% transparency as partially transparent, whereas CUTOUT renders anything above 10% as fully opaque, and anything less as fully transparent.

You can make blocks rendered in the TRANSLUCENT layer look the same as SOLID or CUTOUT if you have to, by choosing appropriate alpha channel values.  It is now possible to have blocks which render in multiple layers- see Block.canRenderInLayer().

If multiple transparent blocks are placed next to each other, the internal faces are all visible (the two "4" faces in the picture below).  This is different from (for example) glass and ice, where these "internal faces" are not shown.
Minecraft achieves this using the shouldSideBeRendered() method.  For example - BlockGlass overrides shouldSideBeRendered(), and returns false if the adjacent block is also a glass block.  (see BlockBreakable.shouldSideBeRendered()).
BlockGlass.shouldSideBeRendered(): left = vanilla code; right = overridden to always return true







2 comments:

  1. How do you actually do this? Do you have any code?

    ReplyDelete
  2. Yes there is example code here
    https://github.com/TheGreyGhost/MinecraftByExample
    For example MBE03 uses CUTOUT.

    ReplyDelete