Skip to content

Coloured Lights

zomb_676 edited this page Nov 14, 2022 · 13 revisions

Coloured lights water

Do you want a colored light, want smooth lighting and render thousands of lights with good performance? Add your own point lights!


How to use

For non-modders, you can add lighting to your blocks via configuration files. All lights will be compiled in the chunk info while such blocks placed.

{
  "LightBlock": [
    {
      "block": "minecraft:sea_lantern",
      "r": 34,
      "g": 255,
      "b": 200,
      "a": 255,
      "radius": 7
    },
    {
      "block": "minecraft:redstone_lamp",
      "state": {
        "lit": true
      },
      "r": 255,
      "g": 165,
      "b": 13,
      "a": 255,
      "radius": 10
    }
  ],
}

You can use it to add blocks that emit colored light, light color, and light radius. Isn't that easy?

NOTE: Very not recommended add lights for blocks (e.g. grass block) / fluids (e.g. water, lava) generated in large numbers in the world. Because in order to ensure good performance on any graphics card, we limited the lights count to 2048, and any lights more that will not be rendered.


Java Addon

When you need more advanced lights, for example you want different blockstates to emit different light, or you want to add moving light such as adding light for an entity, etc. You can do this through the Java API.

BlockState Predicate:

see LightManager.INSTANCE.registerBlockLight(Block block, BiFunction<BlockState, BlockPos, ColorPointLight.Template> supplier)
the BlockPos parameter allows you to access data in BlockEntity via Minecraft.getInstance().level

@SubscribeEvent
public void clientSetup(FMLClientSetupEvent e) {
    e.enqueueWork(()->{
       /**
       * register colored light for a block.
       * @param block block
       * @param supplier light supplier from a BlockState
       */
        LightManager.INSTANCE.registerBlockLight(CAMPFIRE_BLOCK.get(), state, pos -> {
            if (state.getValue(CampfireBlock.LIT)) {
                ColoredFireBlock.FireColor color = state.getValue(FIRE_COLOR);
                return new ColorPointLight.Template(color.radius, color.colorVale);
            }
            return null;
        });
        LightManager.INSTANCE.registerBlockLight(Blocks.SOUL_LANTERN, state -> new ColorPointLight.Template(8, 0xff74F1F5));
    });
}

Create a Light Source:

A more flexible approach is to create a light source and manage and maintain it yourself. You could modify its color, radius, position, and life cycle at any time.

LightManager.INSTANCE.addLight

/**
 * Create and add a new PointLight. Have to maintain instances yourself.
 * @param pos position
 * @param color colored
 * @param radius radius
 * @param uv whether the light will be limited by lightmap uv/light level or not
 * @return instance created. null -- if no more available space.
 */

@Nullable
public ColorPointLight addLight(Vector3f pos, int color, float radius);

When you modify light's attributes, you have to call ColorPointLight.update() to update it. Call ``ColorPointLight.remove()to remove a light source. There is still a field calledenable` in the return type `ColorPointLight`, no need to call `update` after changing the field

Note: Modder should always manage their lights carefully. Make sure to remove useless lights!!!!


item dynamic light held by players

player dynamic light

How to use

For non-modders, you can add item dynamic light to your item via configuration files.

{
  "LightItem": [
    {
      "item_id" : "minecraft:torch",
      "r": 255,
      "g": 253,
      "b": 85,
      "a": 255,
      "radius": 7
    }
  ]
}

NOTE: the light is just a visual effect , no actual block light level.


Java Addon

When you need more advanced lights, for example, you want to make an item that has to enable/disable state. etc. You can do this through the Java API. what's more, you can make your light radius affected by the stack count

BlockState Predicate:

see LightManager.INSTANCE.registerBlockLight(Block block, BiFunction<BlockState, BlockPos, ColorPointLight.Template> supplier)
the BlockPos parameter allows you to access data in BlockEntity via Minecraft.getInstance().level

@SubscribeEvent
    public void clientSetup(FMLClientSetupEvent e) {
        e.enqueueWork(() -> {
            /**
             * register dynamic light for items held by players.
             * @param item the item used for register
             * @param function supplier light supplier from an ItemStack
             */
            LightManager.INSTANCE.registerItemLight(Items.TORCH, (itemStack ->
                    new ColorPointLight.Template(/*radius*/itemStack.getCount() / 10 + 6, DyeColor.YELLOW.getMaterialColor().col)
            ));
        });
    }

Create a Light Source:

A more flexible approach is to create a light source and manage and maintain it yourself. You could modify its colour, radius, position, enable ,and life cycle at any time.

LightManager.INSTANCE.addPlayerItemLight

/**
 * @param pos position
 * @param color color
 * @param radius radius
 * @param playerUUID the specified player's UUID
 * @return instance created. null -- if no more available space. control enable/disable yourself
 */

@Nullable
public ColorPointLight addPlayerItemLight(Vector3f pos, int color, float radius, UUID playerUUID);

Call ColorPointLight.remove() to remove a light source.
There is a field called enable in the return type ColorPointLight, no need to call update after changing the field
The uv field is not applied to this situation

Note: Modder should always manage their lights carefully. Make sure to remove useless lights!!!!