Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Changing the Hue of a Sprite  (Read 13002 times)

0 Members and 1 Guest are viewing this topic.

Weeve

  • Jr. Member
  • **
  • Posts: 87
  • C++ Programmer (Intermediate), 3D Artist (Skilled)
    • View Profile
    • Email
Changing the Hue of a Sprite
« on: February 01, 2013, 02:38:16 am »
Since sf::Sprite.SetColor() is only for editing current color values, should I manually edit the pixels of the image each time, then reload them into the Sprite, or should I have three separate images of the different hues, and swap to a different image when needed, and use SetColor() to modify the color values? I would like the most efficient method, and I don't mind low level work, I'm used to it :-)

also, if I do end up writing a SetHue() function for a sf::Sprite, would sfml integrate it for me, so that I can avoid code bloat?
Long live rapid project development! -- Kestrel3D Game-Engine nearing completion

thePyro_13

  • Full Member
  • ***
  • Posts: 156
    • View Profile
Re: Changing the Hue of a Sprite
« Reply #1 on: February 01, 2013, 03:57:46 am »
Try using something like this HSL colour class(from the sfml github wiki)

getColour() from the sprite, convert it into a HSL colour object, modify the hue, and then convert it back.

The github code comes with functions to convert back and forth between HSL colour objects and sfml colour objects.

Weeve

  • Jr. Member
  • **
  • Posts: 87
  • C++ Programmer (Intermediate), 3D Artist (Skilled)
    • View Profile
    • Email
Re: Changing the Hue of a Sprite
« Reply #2 on: February 01, 2013, 04:27:29 am »
Mmk, am going manual pixel edit route, then, and the colors don't have to be more accurate than 10/255, so I will  do something similar to HSL, but alot cheaper in computations :-) ty for recommendation to go manual route
Long live rapid project development! -- Kestrel3D Game-Engine nearing completion

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Changing the Hue of a Sprite
« Reply #3 on: February 01, 2013, 08:11:13 am »
That was not a recommendation to edit pixels manually at all, he said to use setColor -- but with the helper functions of the wiki so that you can work with HSL instead of RGB.

I don't see why you would have to edit pixels manually since you have a function that changes the overall color of the sprite for free.
Laurent Gomila - SFML developer

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
Re: Changing the Hue of a Sprite
« Reply #4 on: February 01, 2013, 04:54:06 pm »
Quote
so I will  do something similar to HSL, but alot cheaper in computations :-) ty for recommendation to go manual route

My class can work well for preprocessing of images (else it will be painfully slow), but as Laurent said, you can perfectly use it with sf::Color and try to experiment your way to the desired outcome. However if you want full control over the hue change you can perfectly use a hue shifting shader. There's plenty in the net and the algorithm is the same, what changes is the mainly the notation of it.

If you know GLSL you can even make your own by looking at the source of the conversions, that way it can work in a more intuitive way and have it work fast in repeated run-time.
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

Weeve

  • Jr. Member
  • **
  • Posts: 87
  • C++ Programmer (Intermediate), 3D Artist (Skilled)
    • View Profile
    • Email
Re: Changing the Hue of a Sprite
« Reply #5 on: February 01, 2013, 05:39:55 pm »
so if I use setColor(), since its a RGB subtraction of the images color, and not a hue function, how would that work? for instance, if I use SetColor(255,0,0) on a blue object, I then have a black/white object, since the original object had no red in it.

I thought his reccomendation was to use GetColor() initially to find the current hue?

the implementation I was thinking of was to loop through the pixels one time, and seperate out the amount of non grey color, and change the non grey color to my desired RGB, as it would save all of the computations to HSL, where accuracy matters little, but speed is a slight concern  :) .Which is basically what HSL does, except dumbed down to save a few computations, that I shouldn't be worried about in the first place, but for some reason am (function only runs 10 times a second, about)
Long live rapid project development! -- Kestrel3D Game-Engine nearing completion

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
Re: Changing the Hue of a Sprite
« Reply #6 on: February 01, 2013, 05:45:14 pm »
The problem is that when you modify the image you have to re-bind the texture, and that takes more time than image processing. That is what actually makes it slow. The shader approach works around that.

I dislike the getColor/setColor approach because the default color of a sprite is white, which may or may not have saturation and therefore doesn't matter if you change the hue. To actually make a change you need to do lots of trial and error with the color filter, and probably only one image will get some benefit from that. The shader is the standard and best way of doing things fast.

Moreover, you can program your shader to skip unnecessary computations anyway.
« Last Edit: February 01, 2013, 08:07:01 pm by masskiller »
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

Weeve

  • Jr. Member
  • **
  • Posts: 87
  • C++ Programmer (Intermediate), 3D Artist (Skilled)
    • View Profile
    • Email
Re: Changing the Hue of a Sprite
« Reply #7 on: February 01, 2013, 06:02:13 pm »
Sfml has shaders? it should be interesting learning about shaders then ;D
Long live rapid project development! -- Kestrel3D Game-Engine nearing completion

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
Re: Changing the Hue of a Sprite
« Reply #8 on: February 01, 2013, 07:49:49 pm »
sf::Shader from 2.0 has support for both Fragment and Vertex shaders written in GLSL.
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

Ancurio

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: Changing the Hue of a Sprite
« Reply #9 on: February 01, 2013, 10:21:44 pm »
Try using something like this HSL colour class(from the sfml github wiki)

getColour() from the sprite, convert it into a HSL colour object, modify the hue, and then convert it back.

The github code comes with functions to convert back and forth between HSL colour objects and sfml colour objects.

I tried the algorithm in the link above, and the results were horrendous. I would show you screenshots if I still had them,
but somehow for me it didn't work out at all.

I ended up using this (first answer) shader to draw the whole texture into a second render texture, and use that instead.
I think using a hue shift shader on each draw call is way too expensive though..

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
Re: Changing the Hue of a Sprite
« Reply #10 on: February 02, 2013, 03:28:19 am »
How did you use it? When I created the class I tested it many times and it worked fine with sf::Image and the console output of the values were mostly correct. The algorithm isn't mine, I took it from another website, but in per-pixel color shifting there were no issues after debugging. Also note that the formula is quite hard to follow, I had tons of hard to track errors when I first programmed it.
« Last Edit: February 02, 2013, 03:38:53 am by masskiller »
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

Ancurio

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: Changing the Hue of a Sprite
« Reply #11 on: February 02, 2013, 09:35:37 pm »
I don't remember that well, maybe I even used it wrong? All I did was something along

for each pixel x, y do
    sf::Color c = image.getColor(x, y)
    HSL hsl = TurnToHsl(c);
    hsl.Hue += some_shift;
    c = hsl.TurnToRGB();
    image.setColor(x, y, c);
end

Ah, now I remember that some macro epsilon wasn't set. It looked like some sort of float comparison tolerance, so I set it to a very low number (0.0001 or something). Maybe that was the reason? Anyway, it's good to know you wrote that code, maybe I'll come back at you for some support =P (I will need to do image manipulation in software soon).
« Last Edit: February 02, 2013, 09:37:09 pm by Ancurio »

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
Re: Changing the Hue of a Sprite
« Reply #12 on: February 03, 2013, 02:17:06 am »
It depends on what you want to do with the image and the image itself. For example there are cases where shifting the hue does nothing or nearly nothing (gray and near gray colors) as they have little to no saturation. In a colorful image it actually has a purpose to shift the hue for color purposes. In the case you want to colorize an image a set in stone saturation helps get more consistent results.

Most of my tests when I first programmed it were with color codes and plain colored images, and since they turned fine after extensive debugging I just uploaded the class and forgot about it. I'm gonna make a more extensive testing of the algorithm with more complex images and see if I get odd results.

Here's the original algorithm written in pseudo-code:

http://www.easyrgb.com/index.php?X=MATH&H=18#text18
http://www.easyrgb.com/index.php?X=MATH&H=19#text19

The raw formula came from wikipedia's entry on HSL and HSV, but it's rather confusing unless you are really into pure math notations.

Quote
I set it to a very low number (0.0001 or something). Maybe that was the reason?

The EPSILON is fine as a low number because it's precisely for float comparison, so there should be no problems with it unless the EPSILON value wasn't defined.

Edit: After checking for more algorithms I found a very interesting one, which uses an approach similar to YUV coloring to convert it. If it turns out to be more effective or efficient I'll change the class to use that. Here's the link if you're interested.

http://www.quasimondo.com/archives/000696.php
« Last Edit: February 03, 2013, 02:37:43 am by masskiller »
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Re: Changing the Hue of a Sprite
« Reply #13 on: February 03, 2013, 07:08:27 pm »
Wow the last link looks very intersting! If you happen to find the time to investigate if it's more efficient then the "normal" method, then I would be interested in the results too!

Ancurio

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: Changing the Hue of a Sprite
« Reply #14 on: February 03, 2013, 10:30:42 pm »
It depends on what you want to do with the image and the image itself. For example there are cases where shifting the hue does nothing or nearly nothing (gray and near gray colors) as they have little to no saturation. In a colorful image it actually has a purpose to shift the hue for color purposes. In the case you want to colorize an image a set in stone saturation helps get more consistent results.

Most of my tests when I first programmed it were with color codes and plain colored images,and since they turned fine after extensive debugging I just uploaded the class and forgot about it. I'm gonna make a more extensive testing of the algorithm with more complex images and see if I get odd results.

My use case is almost exclusively hue shifting of normal, multi-colored images,
to get new variations and "looks" out of them.
An example would be to take an image of a flower bouquet and use hue shifting to
get interesting new flower colors, while keeping each flower's differences.