-
Notifications
You must be signed in to change notification settings - Fork 0
How Colours Work
Only the hue of a specified colour is used. Every colour is scaled until its brightest channel is full, so #884422 and #FF8844 are equivalent. Range and intensity come from the block's own light level, as in vanilla.
One consequence is worth stating plainly: a saturated hue always costs luminance. Retaining the brightest channel and scaling the other two down is what makes a colour read as a colour, so a deep blue lamp appears dimmer than a white one at the same light level. This is the tint behaving as specified rather than a fault in emissive textures.
colorIntensity scales how far every colour departs from white before that happens. Below 1 washes towards white, above 1 deepens, 0 leaves every light white.
A colour is quantised to 4 bits per channel relative to its own brightest channel, giving 16 levels each. Light shows no visible banding at that resolution, but two colours differing by less than roughly 7% of the brightest channel quantise to the same value.
For a placed block, the first source to produce an answer wins.
- Coloured light disabled. Every light is white and nothing below is consulted.
-
A cycling palette entry, if
animatedLightColorsis enabled. See cycling colours. - A Java provider registered for the block. Most recently registered first, then catch-all providers. See Java API.
- Substitution for a block whose light belongs to something it holds: a copycat glows the colour of its material, a Create placard the colour of the item on it, a wall lantern the colour of the lantern rather than its bracket. The steps below then run against the held block.
- A fixed palette entry, from the mod's own vanilla file or from any resource pack or mod that ships one. See Resource pack colours.
-
Derivation from the block's texture, if
deriveColorFromTextureis enabled and nothing above matched. -
A warm torch glow,
#FF914D, identical to the colour thewarmkeyword produces.
Substitution at step 4 is also applied before the cycle lookup at step 2, so a copycat whose material has a cycling entry cycles. The provider at step 3 is consulted with the block as placed, before any substitution.
Every light-emitting vanilla block has a palette entry at step 5, so steps 6 and 7 apply to modded blocks only.
A block with no entry has its colour measured from its own texture. The procedure is deliberately narrow, since a confident wrong answer is worse than a plain one.
Locating the emissive sprite. Averaging the whole texture fails on the common case of a caged lamp: a metal cage can be both brighter and more saturated than the bulb it surrounds, so no pixel statistic separates them. Instead the block is baked twice, once as placed and once with a single blockstate property set to the value that leaves it darkest, lit first and then whichever remaining property lowers its light level furthest. A property need not be a switch: a display whose brightness comes from a redstone signal is compared against the same block unpowered. The sprites present in the lit model and absent from the dim one are the emissive part. A block whose light level no single property lowers, or one whose two models use identical sprites, falls back to the model's particle texture.
Measuring it. Each opaque texel is weighted by chroma rather than brightness and averaged in linear space. Brightness weighting washes out pale blocks such as froglights, whose whitest texels dominate; chroma weighting lets the identifying colour drive the result while a genuinely grey block still averages grey. Saturation is then pushed away from the result's own luminance by a factor of 2.5, and the result normalised.
Refusals. An averaged colour with less than 5% chroma before that boost is treated as white, since a 1% tint in grey metal would otherwise become a visible hue. The missing texture, which is what an invisible block with no model resolves to, is treated as white rather than the saturated magenta its checkerboard averages to.
Disabling deriveColorFromTexture replaces this step with the warm glow at step 7. The palette still applies, so soul lanterns remain blue and froglights pastel.
| Setting | Default | Effect |
|---|---|---|
enableColoredLight |
off | Master switch, covering every lighting mode including VEIL. Disables itself while a shaderpack is loaded and returns when one is unloaded. |
colorIntensity |
1.0 | How far a colour departs from white. 0 leaves every light white. |
colorfulCandles |
on | Dyed candles glow the colour of their wax. Off gives every candle a warm flame, by dropping the entries whose condition is colorful_candles. |
deriveColorFromTexture |
on | Whether step 6 runs at all. |
animatedLightColors |
on | Whether cycling colours move. Off holds each at the average of its own colours. |
All five apply immediately, without a world reload. They live in config/contraptionlights-client.toml, and in Sodium's Video Settings where Sodium is installed.
Coloured light is not restricted to blocks in the world. It applies to block entities, particles, held items, entities lit through LambDynamicLights, contraptions, Create kinetics and other Flywheel-rendered geometry, and blocks inside a Sable physics contraption. The resolution order above governs all of them, with three exceptions: a block riding a Create contraption resolves from its saved data rather than a live block entity, a light coming from an entity or from an item resolves from entity and item entries, and a light with no block behind it uses behaviour entries.