"Crushed blacks" in custom lighting shader

Godot Version

4.7.beta1

Question

I’m working on a game with fully custom lighting, but am having an issue which search engines (including google AI search) have been absolutely useless with..

When there is little to no light, very dark colors (such as greys, dark blues, black) combine into one cohesive color: black

The related shader code is here:

EMISSION = ALBEDO * vec3(0.435, 0.43, 0.432) * ambient_lighting_amount;

The actual lighting code doesn’t matter, since the effect only happens when there is no light/very little light. The emission here is meant to give a baseline color (less than normal) to every pixel which does not come into contact with light

Some calculations to give you an idea as to why I am confused about this (ambient lighting amount being 0.4 since that’s my default for it):

EMISSION = vec(0.1, 0.1, 0.2) * vec3(0.435, 0.43, 0.432) * 0.4;

The above is a dark blue

EMISSION = vec(0.1, 0.1, 0.1) * vec3(0.435, 0.43, 0.432) * 0.4;

The above is a dark grey

EMISSION = vec(1.0, 0.5, 0.5) * vec3(0.435, 0.43, 0.432) * 0.4;

The above is a not-so-bright red, though much more color than the other colors above

Dark blue final Emission value: EMISSION = vec3(0.0174, 0.0172, 0.03456)

Dark grey final Emission value: EMISSION = vec3(0.0174, 0.0172, 0.01728)

Red final Emission value: EMISSION = vec3(0.174, 0.086, 0.0864)

Maybe this is just a mental block kind of thing and I’m being dumb, but, I feel like the b value for the dark blue is different enough from the b value of the dark grey to show a difference. The red’s values arent THAT much higher than the dark blue and dark grey (still 100ths place of the decimal, not even 10ths)

Would anyone have a suggestion? I’d prefer not to rely on another light source such as a directional light to mimic the sun, and would rather have some simpler and more performant baseline lighting to fit the artistic direction of my game

Those values provided as examples are on purpose. The gun shown in these 2 images has the same texture in both screenshots. One is directly in the lighting, the other, is facing away with no lighting. I do indeed expect the colors to be “flatter”, since there’s no NORMAL calculations for my EMISSIONcode..

But, on the handle of the gun, the vec3(0.0, 0.0, 0.0) black part of the handle looks absolutely no different from the dark greyblue part of the handle (similar values as the examples above). In the screenshot with light, you can clearly see this difference in the light, but in the dark, it blends in perfectly with the background of space

I’ve tried increasing the amount of EMISSION, ive tried clamping color values, everything just makes things brighter, not more “correct”

Will take any suggestions!

just to reiterate, i know that no lighting means no color, but this is a fully custom solution, and EMISSION aims to give a 'background/sky` color to the objects in the scene

Extra image to show what it looks like against the orange test plane. No light shining on the gun (at least of whats in view of the camera)

Play with tonemap options in world environment node.

thanks for the reply, that definitely changes the colors even though it’s custom lighting, but still about the same results (dark colors are “combined”)

even going off the deep end with exposure results in this:

actually surprising how much the non-dark colors change

Also as an extra bit of info, there’s no compression on the textures, all lossless due to small size, so that shouldnt be affecting colors here

Not sure I get where the problem is. Can you make a minimal example that clearly demonstrates the problem and post the complete shader code.

mmmm, through cleaning up the shader code to try to post a minimal example, i think i found the root of the issue. It felt like it was related to Emission since that’s what I was seeing, but the core of the issue is a floor + some averaging im doing to the specular lighting to achieve a toon look, removing the line which does that actually fixes the issue

thanks for the conversation :face_with_tongue: love when things work out like that haha

i might add “remove lines from a shader until the problem is visible” to my debugging toolkit

for anyone who sees this in the future from a lucky google search,

if you are implementing toon lighting using any form of floor(specular light * CONSTANT) / CONSTANT; to achieve controlled color banding, this is why your blacks are being crushed into a single color