Monday, 13 April 2020

Item Rendering [1.14.4+]

Rendering items is a bit complicated because there are a number of different places they can be seen:
  • In the Inventory (also in the Speedbar overlay) – referred to in Vanilla code as a GUI item (graphical user interface) "gui"
  • Equipped (held in the player’s hand) – in first person view ("firstperson") or third person view ("thirdperson").
  • Dropped (on the ground "ground")- contained within an EntityItem
  • On a player's head (helmet inventory slot)- "head"
  • In a picture frame ("fixed")– contained within an EntityItemFrame
In addition to this,
  • Most Items which are also Blocks are rendered in 3D (eg TNT), which uses a rendering model generally the same as the Block.  This type of item is usually an ItemBlock.
  • If fancy graphics are enabled, 2D Items have thickness when dropped and also slowly rotate.
  • There are several flags which affect the display of items such as bobbing and rotation when dropped.
  •  ItemStack (multiple items/blocks) render with a number in the GUI overlay and as a pile of minicubes when dropped.

The pictures below show these various different renders:

Item (Pickaxe) and 3D Block (TNT) rendered into the GUI ("gui")

 Fancy graphics enabled.
GUI items (red): Item (pickaxe),  3D Block (TNT), 2D Block (Bed), multiple blocks (Dirt)
Equipped Item (pickaxe blue circle);
Dropped Item/EntityItems (purple):  Item (Pickaxe), 3D Block (TNT), 2D Block (Bed), multiple blocks rendered as minicubes (Dirt)

Fancy graphics disabled.
 Dropped Item/EntityItems (yellow):  Item (Pickaxe), 2D Block (Bed)

Equipped Item - first person view: 3D block (TNT)

Equipped item - third person view: 3D block (TNT)

Items rendered in frames - rendered as per EntityItem: Item (pickaxe), 2D Block (bed), 3D Block (TNT)
Minecraft deals with all these different situations as follows:
  1. Each item has a JSON Item Model file which defines the model used for rendering the item.  This falls into one of several categories:
    a) The model uses one of the 3D block models as a base; or
    b) A "2D" model (with optional thickness) is generated from an item texture (see ItemModelGenerator for the vanilla code which does it); or
    c) for a number of predefined hard-coded items (chests, compass, clock, banner, skull), the rendering is hard-coded in render classes.
  2. The JSON model also defines an ItemCameraTransform for one or more of the different ways an item might be viewed (i.e "gui", "firstperson", "thirdperson", "head", "fixed", "ground").  Each ItemCameraTransform consists of translation, rotation, and scaling information, which is used to position and size the item correctly when rendered in a particular view.
This link describes the structure of the JSON Item Model file (see the Item Models section halfway down).

Further information

The appearance of an item can be modified by code in a number of ways:
  1. Autogenerated (2D items) are built up in layers: the JSON file can specify a texture for layer0, another texture for layer1, and so on.  See example of the spawn egg below. Layers 0 - 4 are permitted in the code, although vanilla models use at most layer0 and layer1.  During auto-generation, the "tintIndex" flag for each quad within a layer is set to the layer number; for example the spawn egg consists of two layers as shown below.  When the item is rendered, layer 0 is rendered first, then layer1, then layer2, etc.  Item.getColorFromItemStack(stack, layer) is called to determine what the colour multiplier for each layer should be.  This allows a single item model to be rendered with a variety of different colours, the best example being spawn eggs and potions.  
  2. If Item.hasEffect() is true (typically because it is enchanted) then an animated "glint" effect (called "foil" in the vanilla code) is rendered over the top.
  3. When rendering in the GUI, the number of items and the item damage bar are added as an "overlay".  Item.showDurabilityBar() and Item.getDurabilityForDisplay() are useful for controlling the appearance of the damage bar.
  4. In the first person view, the position of the player's arm and hence the item are modified. 
  5. The item appearance can be animated when it is being held by a player.
File:excerpt from item/spawn_egg.json
    "parent": "builtin/generated",
    "textures": {
        "layer0": "items/spawn_egg",
        "layer1": "items/spawn_egg_overlay"    },

The most interesting vanilla classes to look at for Item Rendering are
  1. ItemRenderer (various methods to render items in different views)
  2. ItemStackTileEntityRenderer for the hard-coded rendering of TileEntityChest, TileEntityBanner, TileEntitySkull

More information

Wiki on item models

No comments:

Post a Comment