Skip to content

Understanding: Multi Sprite Faces

grondag edited this page Jun 13, 2019 · 1 revision

What

JMX enables face definitions with two sprites. The two sprites share the same geometry, colorIndex, and tag value, but uv coordinates, color and lighting can be different.

This feature is ideal for borders and decals. Implementing something like a "glowing ore" block becomes very simple. Dual textures can make models that employ colorized greyscale textures appear less "flat" by adding a detail overlay with a contrasting color. Creative model artists will find other uses beyond these.

Example

Multi-Sprite Example

Why

These same effects can be achieved by specifying faces twice. So why have this feature at all? There are several reasons:

  1. Model specification is more concise - geometry is only specified once. The intention is more clear and mistakes involving mismatched geometry are less likely.

  2. Renderers that support sprite depth can avoid duplicate face culling checks. Both faces can be checked at the same time. (JMX quads are baked into Mesh objects, and cull face is a per-quad property in meshes.)

  3. Quad Transformers - a feature that will be added to JMX - can operate on both quads at the same time and use sprite depth to distinguish one quad from another. But this only works if the renderer supports quads with multiple sprite depth.

  4. Renderer implementations can avoid the overhead of translucency blending and/or sorting with translucent overlays if the base layer is known to be a solid texture. Currently, only Canvas does this.

Limitations

The Fabric Renderer API allows for the existence of multi-sprite renderers by including a spriteIndex parameter on methods related to sprites. However, support for multiple sprites in Indigo is currently disabled.

FREX introduces full support for multiple sprite layers and Canvas currently supports a maximum sprite depth of three.

Because of this inconsistency, JMX operates different depending on which renderer is active:

  • Indigo: JMX emits two quads when multi-sprite faces are specified. The two quads share the same tag, colorIndex and geometry but will have different render materials if material specifications are different.

  • Canvas: JMX emits a single quad with a material that includes information for both sprites.

Implications

Generally, this works fine. However, Quad Transformers (work-in-progress feature) running on Indigo will not be able to identify different sprite layers using the spriteIndex parameter. (SpriteIndex will always be 0.) Similarly, tag and colorIndex will always be the same.

This limitation is important for something like a connected textures quad transformer that needs to alter only one sprite layer.

Currently there are two workarounds:

  1. Avoid this feature and specify multiple faces. Tag can then be used by quad transforms to reliably identify targets. However, renderers will not be able to optimize overlay rendering. (See cautions, below.)

  2. Use a material attribute that varies by sprite index as a signal to the quad transformer. For example, disableColorIndex is often irrelevant and could serve this purpose. The transformer can change the material value at time of transformation if needed. This workaround will require special-case handling in the transformer implementation, typically relying on Frex.isAvailable()

Cautions

A translucent-layer sprite on top of a solid-layer sprite is the most versatile overlay pattern. However it does create a small amount of overhead on the Indigo default renderer because the translucent sprite must be sorted based on player view position and blended with the solid/cutout layers in a separate pass.

This overhead is not significant for machine blocks or decorative accent blocks, but translucent overlays could create noticeable lag or FPS drops on older hardware when used in very large numbers. For example, a PC that struggles to render ice/water biomes or scenes containing a large number of stained glass blocks will also struggle when very many translucent overlay sprites are visible.

Canvas avoids the need for overlay sorting by blending the sprites in a fragment shader but not all users will want to or be able to use Canvas. A future version of Indigo or another vanilla-based renderer could also optimize by not sorting overlay quads when it is not necessary.

For now, recommenced practices is to avoid using overlays for terrain blocks that occur in large numbers. Using overlays for ores, machines and decorative accent blocks should generally offer acceptable performance.

Clone this wiki locally