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

Add hue traits #12399

Merged
merged 13 commits into from
Mar 22, 2024
Merged

Add hue traits #12399

merged 13 commits into from
Mar 22, 2024

Conversation

oyasumi731
Copy link
Contributor

Objective

Fixes #12200 .

Solution

I added a Hue Trait with the rotate_hue method to enable hue rotation.
Additionally, I modified the implementation of animations in the animated_material sample.


Changelog

  • Added a Hue trait to bevy_color/src/color_ops.rs.
  • Added the Hue trait implementation to Hsla, Hsva, Hwba, Lcha, and Oklcha.
  • Updated animated_material sample.

Migration Guide

Users of Oklcha need to change their usage to use the with_hue method instead of the with_h method.

Copy link
Contributor

Welcome, new contributor!

Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨

@TrialDragon TrialDragon added C-Enhancement A new feature A-Rendering Drawing game state to the screen labels Mar 10, 2024
Copy link
Contributor

@pablo-lua pablo-lua left a comment

Choose a reason for hiding this comment

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

I have just some comments here. But everything else looks fine, thanks for tackling this!

crates/bevy_color/src/color_ops.rs Outdated Show resolved Hide resolved
/// Return a new version of this color with the hue channel set to the given value.
fn with_hue(&self, hue: f32) -> Self;

/// Return the hue of this color (0.0 - 360.0).
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// Return the hue of this color (0.0 - 360.0).
/// Return the hue of this color [0.0, 360.0].

Copy link
Contributor

Choose a reason for hiding this comment

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

At the same time, I think we shouldn't keep the interval here. What if we find a colorspace that for some reason will go by another interval?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Certainly, it's not guaranteed that the range of hue values will fit within this range in every color space.
Thank you for your comment!

Copy link
Contributor

@MiniaczQ MiniaczQ Mar 11, 2024

Choose a reason for hiding this comment

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

I think the range here should be consistent across all hue implementations, hence defined here.
The implementations need to perform mapping from a predefined range to their hidden representation.

Let's say you have a color that uses [0, 1] and another that uses [0, 360].
You are refactoring your code from one to the other,
suddenly the .rotate_hue(0.5) which used to work 'stops' working.
It's influence decreased from 1/2 rotation to 1/720 rotation.

I personally like [0, 1] range, but [0, 360] or [0, 2pi] will work just fine.
If there is a consistent value range for current implementors, we should probably go with that.
([0, 360] seems to be it)

Copy link
Contributor

@pablo-lua pablo-lua Mar 11, 2024

Choose a reason for hiding this comment

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

Yeah, I agree that we don't have many colorspaces out there with some odd behavior, but at the same time, this trait is made to be generic, and I think that should reflect on docs

Copy link
Contributor

Choose a reason for hiding this comment

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

Generic implies consistent behavior across implementations, so a consistent range should be in place.
Having read the PR now, all existing colorspaces are consistent so this behavior (and docs) is not necessary yet at the very least

oyasumi731 and others added 2 commits March 12, 2024 00:41
Co-authored-by: Pablo Reinhardt <126117294+pablo-lua@users.noreply.github.com>
Comment on lines 33 to 42
let mut i = 0;
for x in -1..2 {
for z in -1..2 {
commands.spawn(PbrBundle {
mesh: cube.clone(),
material: materials.add(Color::WHITE),
material: materials.add(Color::hsl((i as f32 * 2.345) * 100.0 % 360.0, 1.0, 0.5)),
transform: Transform::from_translation(Vec3::new(x as f32, 0.0, z as f32)),
..default()
});
i += 1;
Copy link
Contributor

@MiniaczQ MiniaczQ Mar 11, 2024

Choose a reason for hiding this comment

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

Not important, but you can use the rotate_hue and a cool property of rotating by golden ratio here for showcase:
(aka golden angle)

// Not a stable f32 constant yet
const PHI: f32 = 1.6180339;

let mut c = Color::hsl(0.0, 1.0, 0.5);
for x in -1..2 {
  for z in -1..2 {
    // Pbr spawning
    c = c.rotate_hue(PHI);
  }
}

this also declutters the random color calculations

Copy link
Contributor Author

@oyasumi731 oyasumi731 Mar 12, 2024

Choose a reason for hiding this comment

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

As you suggested, rotating at a constant ratio makes for a smarter implementation indeed. I rotated it at the golden angle to ensure that the colors of adjacent materials diverge!
8fde8f6

/// Return a new version of this color with the hue channel rotated by the given degrees.
fn rotate_hue(&self, degrees: f32) -> Self {
let degrees = degrees.rem_euclid(360.);
self.with_hue((self.hue() + degrees) % 360.)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not call .rem_euclid() on the result after the addition?

@pablo-lua pablo-lua added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Mar 16, 2024
@alice-i-cecile
Copy link
Member

@oyasumi731 I've done my best to resolve merge conflicts: going to try and merge this :) If it fails, please clean up my changes and get CI passing and then ping me to retry the merge.

auto-merge was automatically disabled March 19, 2024 16:01

Head branch was pushed to by a user without write access

@oyasumi731
Copy link
Contributor Author

@alice-i-cecile Thank you.
I fixed the CI errors, so please merge again.

@alice-i-cecile
Copy link
Member

Thank you very much :) I really appreciate when authors are able to fix up things like that for us.

@alice-i-cecile alice-i-cecile added this pull request to the merge queue Mar 21, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 21, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Mar 22, 2024
Merged via the queue into bevyengine:main with commit 0950348 Mar 22, 2024
26 checks passed
@oyasumi731 oyasumi731 deleted the add-hue-traits branch March 23, 2024 16:02
@BD103 BD103 added the A-Color Color spaces and color math label May 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Color Color spaces and color math A-Rendering Drawing game state to the screen C-Enhancement A new feature S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add hue rotation traits
7 participants