Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate linear and sRGB uniform buffers in RD rendering backends #92444

Merged
merged 1 commit into from
May 31, 2024

Conversation

clayjohn
Copy link
Member

Fixes: #84989

We had a separate uniform set for sRGB vs linear versions of the uniform buffer. When turning on HDR_2D we would use the linear uniform set. Since the same material can be used in both a regular viewport and one with HDR_2D, we have to generate both sets.

Previously, we had one data array and one uniform buffer for both sets. That resulted in the sRGB version of the uniform set overwriting the values in the linear set and the shader effectively always using sRGB values.

This separates out the buffer so the two versions can co-exist.

Before: Note the difference between the version on the right and the one on the left
Screenshot from 2024-05-27 13-36-34
After: Note how the color is consistent now
Screenshot from 2024-05-27 13-35-51

@clayjohn clayjohn added this to the 4.3 milestone May 27, 2024
@clayjohn clayjohn requested a review from a team as a code owner May 27, 2024 20:44
Copy link
Contributor

@BastiaanOlij BastiaanOlij left a comment

Choose a reason for hiding this comment

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

Looks good to me, seems to be a sensible change.

@@ -100,8 +100,8 @@ class MaterialStorage : public RendererMaterialStorage {
HashMap<StringName, uint64_t> used_global_textures;

//internally by update_parameters_uniform_set
Vector<uint8_t> ubo_data;
RID uniform_buffer;
Vector<uint8_t> ubo_data[2]; // 0: linear buffer; 1: sRGB buffer.
Copy link
Contributor

Choose a reason for hiding this comment

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

I would use an enum for the buffer, its just clearer why we have two. Might be over kill.

Copy link
Member Author

Choose a reason for hiding this comment

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

Could you clarify where the Enum would go?

Do you mean you would create an enum just to establish the size of the Array?

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe what he means is making it clearer that 0 is Linear and 1 is sRGB through an Enum. Declared at the top of material.h like this:

enum BufferType {
	LINEAR = 0,
	SRGB = 1
};

Used as such (without the need of comments):

Vector<uint8_t> ubo_data[BufferType.LINEAR];
RID uniform_buffer[BufferType.SRGB];

I don't find it overkill, might save some headache for someone trying to guess which one is which in a later feature. But I think this ship has sailed since it has already been merged.

@clayjohn if this is welcome, let me know if I should make another PR with this minor change. It might be a good start for me to get used with contributions.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think it would be beneficial. Using enums hides what is actually happening. For example, your code will fail to compile (an array of size 0 doesn't work for the UBO array, the array needs to have 2 elements). Also, the uniform buffer RID array is also wrong since it also needs two elements.

It's really easy to make this kind of mistake when you hide the important values behind an enum.

That being said, enums can be really handy when you use them both to initialize the array and to index into the array. Doing something like:

LINEAR = 0 // use to index into the array
SRGB = 1 // use to index into the array
MAX = 2 // use to initialize the array

But in this case we index into the array with a boolean. So enums won't help.

IMO using enums here adds more complexity for no gain

@akien-mga akien-mga merged commit 138f334 into godotengine:master May 31, 2024
16 checks passed
@akien-mga
Copy link
Member

Thanks!

@Dowsley
Copy link
Contributor

Dowsley commented May 31, 2024

Tysm. This was quite a headache to figure out when enabling HDR. I can only imagine how many users couldn't find a workaround and simply decided not to use it.

@clayjohn clayjohn deleted the RD-srgb-uniform-buffer branch May 31, 2024 17:46
@@ -987,17 +989,17 @@ void MaterialStorage::MaterialData::free_parameters_uniform_set(RID p_uniform_se
}

bool MaterialStorage::MaterialData::update_parameters_uniform_set(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const HashMap<StringName, HashMap<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, bool p_use_linear_color, bool p_3d_material) {
if ((uint32_t)ubo_data.size() != p_ubo_size) {
if ((uint32_t)ubo_data[p_use_linear_color].size() != p_ubo_size) {
Copy link
Contributor

@Dowsley Dowsley Jun 2, 2024

Choose a reason for hiding this comment

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

@clayjohn I know the feature works because you reproduced so I'm just trying to learn here.

If ubo_data[0] is linear and ubo_data[1] is sRGB, why is the boolean p_use_linear_color used like this? When it's true, it evaluates to 1 and accesses the sRGB data. Which seems counter-intuitive given the name of the variable.

@JohnPandich
Copy link

JohnPandich commented Jul 27, 2024

Hey folks, I am running into a tricky edge-case that impacts usability. When using a viewport with "transparent_bg" set to true, the glow is removed with the background. Please let me know if you would like me to upload a project with the issue reproduced.

update: On second thought this is a completely separate issue and is accounted for here: #28141

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.

Using vec4 values in canvas_item shaders appear washed out when 2D HDR is active.
6 participants