Skip to content

ColorPicker: Add an intensity slider to all modes for HDR#103583

Merged
Repiteo merged 1 commit into
godotengine:masterfrom
beicause:color-picker-add-intensity
May 27, 2025
Merged

ColorPicker: Add an intensity slider to all modes for HDR#103583
Repiteo merged 1 commit into
godotengine:masterfrom
beicause:color-picker-add-intensity

Conversation

@beicause

@beicause beicause commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

Close #99366

This PR adopts a relatively simple approach, without storing extra intensity field in Color class.

Adds an intensity slider and limit the max value of RGB to 1 in ColorPicker raw mode. Intensity is inferred from raw RGB and may change after switch color mode. The final color is calculated as color * pow(2, intensity).

Also keep the hex LineEdit always visiable and switch it to code if RGB exceeds the valid range.

Edit:

Depends on #102240 to allow greater values.

Edit:
Now the intensity slider is added to all modes and should work.
I modified the ColorMode and ColorPickerShape so that they only handle colors which the intensity has not been applied.

@allenwp

allenwp commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

From looking at this, it appears that the intensity slider is the exposure stops (log2/pow2). So an intensity of 0 is +0 stops, which uses the RGB values as-is.

If my understanding is correct, I think this is a little confusing to users who are not familiar with stops. Even though I'm used to working in stops, I was still a bit confused and assumed the intensity slider was simply a multiplier on the RGB values -- This meant that I expected an intensity of 1.0 to result in no modification of the RGB values. (But this is not the case because this is actually +1 stops, not a 1.0 intensity multiplier).

I think having the + or - indicator on the value would help distinguish that this is stops and not an intensity multiplier. Also, the label should read "stops" or something like that, ideally. Here's an example of how photoshop shows this sort of slider:

image

@beicause beicause force-pushed the color-picker-add-intensity branch from 6be098d to 4d01943 Compare March 4, 2025 18:19
@beicause

beicause commented Mar 4, 2025

Copy link
Copy Markdown
Contributor Author

pow 2 is better than multiplier as it's easier to control the appearence of glow. Unity's intensity slider also uses pow 2. If we want to allow negative intensity, more works need to be done.

@allenwp

allenwp commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

pow 2 is better than multiplier as it's easier to control the appearence of glow. Unity's intensity slider also uses pow 2. If we want to allow negative intensity, more works need to be done.

My apologies, I did not mean to suggest it should be a multiplier. The functionality should definitely be in stops, as implemented in the PR. I only brought up intensity multiplier because the current GUI of this PR makes me think this is how it behaves (even though it doesn't behave that way).

@allenwp

allenwp commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

If we want to allow negative intensity, more works need to be done.

I don't think this is strictly needed, but allowing negative stops is very much a standard convention for this sort of a slider, as shown in the Photoshop example I posted.

@beicause beicause force-pushed the color-picker-add-intensity branch from 4d01943 to b56102d Compare March 4, 2025 19:24
@beicause

beicause commented Mar 4, 2025

Copy link
Copy Markdown
Contributor Author

Added support for negative intensity.
When the HDR threshold of the glow is below 1.0 , adjust the intensity to negative makes sense.

@beicause

beicause commented Mar 4, 2025

Copy link
Copy Markdown
Contributor Author

#102240 adds get_allow_geater for sliders. After that, I think the max value of intensity can be 4 for common use.

@allenwp

allenwp commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

#102240 adds get_allow_geater for sliders. After that, I think the max value of intensity can be 4 for common use.

I was also thinking about whether having the slider max at +6.0 or +4.0. I believe +6.0 is nice because it results in 0.0 being placed in the center of the GUI, which gives a pleasant appearance that reinforces that a value of 0.0 is "neutral" (as in, makes no difference to the colour value). But I agree that in practice, the user shouldn't need to go higher than +4.0...

@allenwp

allenwp commented Mar 4, 2025

Copy link
Copy Markdown
Contributor

Added support for negative intensity. When the HDR threshold of the glow is below 1.0 , adjust the intensity to negative makes sense.

This looks great to me, thank you!

Is it possible to use the prifix property on the spinbox to add a + symbol when intensity > 0? Or maybe there is another way to achieve this sort of number formatting?

@fire fire added the usability label Mar 4, 2025
@beicause beicause force-pushed the color-picker-add-intensity branch from b56102d to c515505 Compare March 5, 2025 15:23

@allenwp allenwp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My review of the code was not very thorough, but the user experience of this PR looks great to me, now that the intensity slider extends to negative stops and the +/- signs are shown on the intensity value.

Thanks!

@beicause beicause force-pushed the color-picker-add-intensity branch from c515505 to c7ba215 Compare March 6, 2025 12:29
@beicause

beicause commented Mar 6, 2025

Copy link
Copy Markdown
Contributor Author

I also colorize the sliders in the RAW mode, like RGB mode. At this point, I think the RAW mode and the RGB mode are similar, maybe we could remove the RAW mode and move the Intensity slider to the RGB mode?

@allenwp

allenwp commented Mar 6, 2025

Copy link
Copy Markdown
Contributor

maybe we could remove the RAW mode and move the Intensity slider to the RGB mode?

The power-user part of me likes this, but this would require giving users the option to input colour values in either 255 integer scale or 1.0 float scale in the RGB mode of the colour picker. This might make the RGB mode too cluttered and too much of a visual overload for users who are entirely new to game development and colour picking.

For the reasons of making it accessible to new users, maybe the current approach is fine...

That said, I do have some related thoughts...

My complaint is that RAW mode picks colours in gamma encoding rather than linear, but that's more of an issue with how the Color class stores data and there's no way that should be changed... But, maybe there should be an HDR mode that allows colour picking in linear encoding that handles encoding conversions for the user. This is actually the way that Photoshop behaves:

8-bit traditional sRGB colour picker:
image

32-bit HDR sRGB colour picker:
image

Notice how the HDR colour picker is entirely in linear encoding, which is different than the 8-bit traditional sRGB picker. In this way, maybe the intensity slider should exist in an HDR mode that allows selecting colours in linear encoding rather than being added to a RAW mode (like this PR's current state), since gamma encoded colours don't make sense when working in HDR.

(To be honest, I actually wanted this sort of behaviour before even looking at Photoshop -- I was pleasantly surprised that Photoshop behaved this way, and I think there is value in matching the behaviour of art tools like this...)

So after writing all of this it makes me wonder: maybe the RAW mode should be removed and a new (linear) HDR mode should be added with an intensity slider and automatic linear-to-gamma conversions. The intensity slider would not be added to RGB mode, but an option to input colour values in 1.0 float scale would be added to the RGB mode in a way that wouldn't overload new users with complexity...

(Please let me know if any of what I wrote is at all confusing and I can whip up a couple of mockups to describe what I'm suggesting be considered.)

@beicause beicause force-pushed the color-picker-add-intensity branch 2 times, most recently from 14a2df3 to be8dad9 Compare March 7, 2025 14:11

@Calinou Calinou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally, it works as expected.

I find the "stop count" UX more difficult to wrangle around when I want to set precise color values though, like Color(2, 0, 0):

image

It seems the exact stop count I need to use is a bit less than +2.31, so I can't enter the exact value due to rounding.

This could be alleviated if the raw color field wasn't read-only when it had Color() values and you could enter those directly.

@allenwp

allenwp commented Mar 8, 2025

Copy link
Copy Markdown
Contributor

Thanks for trying out linear/gamma conversions. I like how the colour bars for the sliders show how this is a linear encoding mode.

I believe that the alpha value also must have linear/gamma conversion, but someone please fact check me on this. My use case is setting up an unshaded material as follows:
- Visual shader
- Blend mode: Mix
- Unshaded: true
- ColorConstant Node attached to Albedo and Alpha

When blending, it seems that the blending is performed with gamma values, so an alpha of 0.5 (gamma) blends to colour values of 128/255 (gamma). So if you want control over this blending using linear values, you would need the automatic linear/gamma conversion for alpha, just like the colour channels. But then again... I could be making up a use case that nobody actually wants. I'm uncertain about if my suggestions for linear/gamma conversions will actually be valuable to many people or not.

Edit: oh, that's so weird: srgb_to_linear doesn't touch the alpha value. 🤔 I guess it makes sense to follow that behaviour, since it's likely that way through the rest of the engine 😔 Probably best to disregard everything I just wrote about linear representation of alpha...?

Additionally, with this behaviour, the "RAW" mode tab must be renamed to "HDR" because it is no longer a RAW editing mode. "RAW" suggests to the user that they are directly editing the raw values for Color that are stored in memory and that will be passed to scripted shaders, which is no longer what this colour picker mode does.

I believe that some users would still want the RAW editing mode, especially because script shaders with the source_color hint will always provide gamma encoded values. I still don't know what the best way to have a RAW mode is or if there is a clean way to integrate it into the RGB mode without making it feel too cluttered.

I hope that all of this isn't bloating the colour picker too much. It is something that's packed in every default export template, if I'm not mistaken, and so any changes will affect all games/apps that use it...

@QbieShay

QbieShay commented Mar 8, 2025

Copy link
Copy Markdown
Contributor

Hey! I just checked it in engine and I'd like to bring forth 2 requests

  1. Can you add the intensity slider to all modes? I personally always use HSV when making VFX, and it'd be annoying to move between raw and HSV all the time
  2. I think the up and down arrow should increase the stops by one and not by 0.01

Other than that, everything is great! Thank you for working on this.

@beicause

beicause commented Mar 8, 2025

Copy link
Copy Markdown
Contributor Author
  1. Can you add the intensity slider to all modes? I personally always use HSV when making VFX, and it'd be annoying to move between raw and HSV all the time
  2. I think the up and down arrow should increase the stops by one and not by 0.01

I'm OK with these. I will try to acheive it then.

@beicause beicause force-pushed the color-picker-add-intensity branch from 5dac5a1 to 0d3dc41 Compare March 8, 2025 13:14
Comment thread scene/gui/color_mode.cpp Outdated
@beicause beicause force-pushed the color-picker-add-intensity branch 2 times, most recently from 8883083 to 198e764 Compare April 24, 2025 10:29
Comment thread scene/gui/color_picker.cpp Outdated
@beicause beicause force-pushed the color-picker-add-intensity branch from 198e764 to db6f4ac Compare April 24, 2025 16:37
@beicause beicause force-pushed the color-picker-add-intensity branch 2 times, most recently from 804be56 to ee88616 Compare April 26, 2025 08:11
@beicause

Copy link
Copy Markdown
Contributor Author

I have integrated #105729 into this PR in advance because I have sufficient bandwidth to do this now.

@beicause beicause force-pushed the color-picker-add-intensity branch 3 times, most recently from 4d0bb44 to fce71de Compare April 30, 2025 17:26
@akien-mga akien-mga requested a review from KoBeWi May 12, 2025 22:50
Comment thread scene/gui/color_mode.cpp Outdated
Comment thread scene/gui/color_mode.cpp Outdated
Comment thread scene/gui/color_picker.cpp Outdated
Comment thread scene/gui/color_picker.cpp Outdated
Add intensity slider to all color modes. Replace raw mode by linear mode, which uses linear color space.

When color is overbright, automatically switch hex text to script text. Allow executing expression in script text field to set color. Add the "script" icon to the default theme.
@beicause beicause force-pushed the color-picker-add-intensity branch from fce71de to 8a94092 Compare May 23, 2025 04:45
@beicause beicause changed the title ColorPicker: Add an intensity slider in raw mode for HDR ColorPicker: Add an intensity slider to all modes for HDR May 23, 2025
@Repiteo Repiteo merged commit 482dacc into godotengine:master May 27, 2025
20 checks passed
@Repiteo

Repiteo commented May 27, 2025

Copy link
Copy Markdown
Contributor

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add an HDR Color toggle and a separated slider for power

7 participants