31 color blending modes (WIP OpenGL version)

Game development specific discussions.
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

31 color blending modes (WIP OpenGL version)

Post by paul doe »

In conversation with another forum member, he asked in this thread how he could perform some color effects he needed for his game.
mrToad wrote:Using openGL in freebasic I am able to adjust RGB values before drawing a texture, using glColor4ub. This is fine but the trouble is when I would like to maintain the brightness of the image but simply tint it more blue or red for example. Using this function the image is darkened when reducing the values from 255. I poked around but couldn't find a function in GL for it, and I don't know how to write one. The application would be to brighten an image beyond normal and also tint it a color.
So, I coded a little demo to show him how this is done in plain FB.

https://github.com/glasyalabolas/fb-layer-modes

Image

You can think of it as 'pixel shaders' coded in FB. The blitter is used in pretty much the same way as FB PUT statement, and works in 32-bit and 64-bit FB.
There are 2 files: 'layer modes.bas' contains the demo showing all blending modes available thus far. For best results, compile with fbc -gen gcc -Wc -O3. Use '1' and '2' to cycle between blending modes, 'q' and 'w' to increase the 'param' parameter (it does different things depending on the mode), and '+' / '-' to change the opacity of the source image. With the arrow keys you can move the image to put it in a different place in the background to see how the blending interacts (I chose that image because it has regions with high/low brightness and saturations).

And the 'benchmark.bas' file contains simple benchmarking code to test the blitter against the same functionality by the FB PUT statement. I would like to know the results you get (I haven't tried with 32-bit GCC, for example), and under which conditions (compiler switches).

@mrToad: I hope that it's useful. On another post I'll show you how you can code different effects. Experiment with it yourself, of course ;) If you want some effect that isn't covered here, we can code it and add it to the library of blending modes.

Have fun!
Paul

UPDATE 2017/12/8: Refactored the OpenGL version, so now it's a little less rushed =D Added the 'addition' blending mode. More to follow.
UPDATE 2017/12/5: The OpenGL version can be downloaded from here:

https://github.com/glasyalabolas/fb-shaders-demo

Only the 'alpha' mode is supported for now. Will add the rest soon.
UPDATE 2017/11/15: Made all blending modes not alter the alpha channel (they weren't supposed to touch it). Modified the 'bmTint' blending mode to accept a struct rather than 3 isolated parameters. It now uses a parameter to add or substract the tint color from the image. Not that anybody cares, of course.
UPDATE 2017/11/14: Corrected 'bmTint' blending mode as it was not honoring the 'opacity' parameter.
Last edited by paul doe on Dec 08, 2017 3:41, edited 8 times in total.
mrToad
Posts: 430
Joined: Jun 07, 2005 23:03
Location: USA
Contact:

Re: 31 color blending modes

Post by mrToad »

Hey I care! This code is sweet.

But I am a bit shocked at the results. Why are mine so much lower than yours? [resolved in his reply] Also I'm curious about what makes the large difference between 32 and 64. [the difference is mainly in using GCC, although there is indeed a difference in GCC 32 vs 64]

EDIT (more detailed results):

running: i7 1.6GHz Q 720

32-bit fbc -s gui
FB PUT ~81 BPS
blendedBlit ~76 BPS

64-bit fbc -s gui
FB PUT ~85 BPS
blendedBlit ~94 BPS

32-bit fbc -s gui -gen gcc -Wc -O3
FB PUT ~220 BPS
blendedBlit ~320 BPS

64-bit fbc -s gui -gen gcc -Wc -O3
FB PUT ~330 BPS
blendedBlit ~425 BPS
Last edited by mrToad on Nov 30, 2017 19:10, edited 6 times in total.
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: 31 color blending modes

Post by paul doe »

Yo! Long time no see =D

Your box specs?
The large difference between 32 and 64 is the compiler (32 uses GAS by default). Have you tried with 32-bit GCC? Should give results similar to that of the 64-bit versions.

Had any luck implementing/integrating this with OpenGL? If not, tell me and I can post the GL version in this thread. What functionality should I implement, so you will be able to integrate it with your framework?
Last edited by paul doe on Nov 30, 2017 14:33, edited 1 time in total.
dafhi
Posts: 1640
Joined: Jun 04, 2005 9:51

Re: 31 color blending modes

Post by dafhi »

great demo!

300, 373 (blended)
fb32 -O 3
core i5 4210u (2014) - This laptop's been somewhat of a dream
Last edited by dafhi on Nov 30, 2017 14:34, edited 1 time in total.
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: 31 color blending modes

Post by paul doe »

dafhi wrote:great demo!

300
fb32 -O 3
core i5 4210u (2014) - This laptop's been somewhat of a dream
Hi, dafhi

Well, lucky you ;)

You know, this is weird. I now get on the order of 150 with FB Put, and 190 with the blitter (so my results are now more in line with yours, mrToad). Either I was smoking something hard when I wrote the code, or there's more going on under the hood of my box.

EDIT: I'm terribly sorry, guys. Those results were taken with the 'star.tga', which is an image included in the files that is 101x171, while the benchmark was using the '99605.tga' image, which is 537x600. As you can see, there's an enormous difference, and I didn't update the comments to account for the change. Well, that is embarrasing, to say the least :blush:
mrToad
Posts: 430
Joined: Jun 07, 2005 23:03
Location: USA
Contact:

Re: 31 color blending modes

Post by mrToad »

That makes much more sense, paul doe, glad you figured that out! No worries. I have i7 1.6GHz Q 720. I am pleased to see the difference with GCC even in 32 bit, you were right.
paul doe wrote:Had any luck implementing/integrating this with OpenGL? If not, tell me and I can post the GL version in this thread. What functionality should I implement, so you will be able to integrate it with your framework?
Appreciate your offer. I did try to think of a reasonable way to implement your blend modes with my engine and the pipeline GL, and it would be a bit hackish. My game scenes are composed of several layers rendered in realtime by GL. The effect would have to be applied to all of them, but remember this has to be done pre-upload to hardware. I would have to literally render everything down, including your blend, and then upload final image to hardware. Not as fast, makes less sense in using GL at all, so I decided I'll have to leave those blends out or learn some real GL - pixel shaders. But I'm toying around with battle system and sound effects so I've been lazy to do that. :D

You do have me itching to learn though. I woke up at 5:45 AM to get some extra time for my project, but by the time I finally had enough coffee and woke up, I had to go to work :D
Last edited by mrToad on Dec 02, 2017 16:41, edited 1 time in total.
dafhi
Posts: 1640
Joined: Jun 04, 2005 9:51

Re: 31 color blending modes

Post by dafhi »

alpha blend is familiar territory .. bmAlpha is worth upgrading

Code: Select all

  opacity = (opacity * src.a)shr 8
  return ( ( _
    (        src  And &Hff00ff) * opacity + _
    (        dst  And &Hff00ff) * (255-opacity) ) And &Hff00ff00)Shr 8 Or ( _
    ( (src Shr 8) And &Hff00ff) * opacity + _
    ( (dst Shr 8) And &Hff00ff) * (255-opacity) ) And &HFF00FF00
mrToad
Posts: 430
Joined: Jun 07, 2005 23:03
Location: USA
Contact:

Re: 31 color blending modes

Post by mrToad »

I have updated my original results using 4 methods (32/64 and gcc/gas)
Good results on all for me, except 32 GAS. Thanks this was fun and I learned something.

Edit: If you did have a demo on GL pixel shading, that would be... well, I think too much to ask for. At least until I put some work into it myself. But I wouldn't stop you ! :)
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: 31 color blending modes

Post by paul doe »

dafhi wrote:alpha blend is familiar territory .. bmAlpha is worth upgrading
I knew you knew XD

Funny, I stopped using bit masks because they were too slow. Looks like this is not the case with GCC, time to update my knowledge, thanks.
You know, I've seen many ways to do alpha compositing, but hadn't seen anything like yours. Care to comment the code a little?
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: 31 color blending modes

Post by paul doe »

mrToad wrote:Edit: If you did have a demo on GL pixel shading, that would be... well, I think too much to ask for. At least until I put some work into it myself. But I wouldn't stop you ! :)
I imagine you won't ;)

I'm currently doing a little (old) research, and came across this thread, from 2011: Easy GL2D (new question regarding texture binding)
I'll see if you can get by with almost (ideally none) changes to your existing code to update the lib a little. You see, once you have the GL blitter, you don't need to rewrite anything in the client side (your application, that is), you simply write different shaders for the effects.
As my code currently stands, the texture binding changes a little, and of course the way to render isn't nearly as straightforward as it was back then, but you'll soon get accustomed to it.

I'll download EasyGL2D again (don't know where it went on my machine), look at the code and see if it can be updated a little. You're only doing blits with GL2D, I assume?
dafhi
Posts: 1640
Joined: Jun 04, 2005 9:51

Re: 31 color blending modes

Post by dafhi »

I learned about bit masking from http://stereopsis.com/doubleblend.html

Code: Select all

/'
  Alpha blend using bit masks to merge red and blue into "one" operation.
  Green and Alpha are combined in their own sequence.
 
  red and blue combined:
  dst = ((dst and &HFF00FF) * a + (src and &HFF00FF) * (255 - a)) shr 8
 
  This blend uses the definition:  back * a + fore * (1 - a),
  which I've found to outperform  'back + a * (fore - back)'
  
  - dafhi
'/

function bmAlpha( byref src as RGBAColor, byref dst as RGBAColor, byval opacity as ubyte = 255, byval param as any ptr = 0 ) as uint32
  opacity = (opacity * src.a) shr 8
'	return( rgba( _
'		dst.r + opacity * ( src.r - dst.r ) shr 8 , _
'		dst.g + opacity * ( src.g - dst.g ) shr 8 , _
'		dst.b + opacity * ( src.b - dst.b ) shr 8 , _
'		dst.a + opacity * ( src.a - dst.a ) shr 8 ) )
  return ( ( _
    (        src  And &Hff00ff) * opacity + _
    (        dst  And &Hff00ff) * (255-opacity) ) And &Hff00ff00)Shr 8 Or ( _
    ( (src Shr 8) And &Hff00ff) * opacity + _
    ( (dst Shr 8) And &Hff00ff) * (255-opacity) ) And &HFF00FF00
end function
mrToad
Posts: 430
Joined: Jun 07, 2005 23:03
Location: USA
Contact:

Re: 31 color blending modes

Post by mrToad »

paul doe wrote:I imagine you won't ;)
Especially after you see similar-topic messages from 2011 LOL. You never know, I might just do it within the next 7 years.
paul doe wrote:I'm currently doing a little (old) research, and came across this thread, from 2011: Easy GL2D (new question regarding texture binding)
I'll see if you can get by with almost (ideally none) changes to your existing code to update the lib a little. You see, once you have the GL blitter, you don't need to rewrite anything in the client side (your application, that is), you simply write different shaders for the effects.
That sounds pretty sweet.
paul doe wrote:As my code currently stands, the texture binding changes a little, and of course the way to render isn't nearly as straightforward as it was back then, but you'll soon get accustomed to it.
I'm sure I could integrate it once I figure it out.
paul doe wrote:I'll download EasyGL2D again (don't know where it went on my machine), look at the code and see if it can be updated a little. You're only doing blits with GL2D, I assume?
Screen setup, basic lines and shapes, flip/rotate/stretch, adjusting rgb values, and making use of some of the built-in blend modes like additive, but I assume that's nothing too extraordinary. So as pixels are placed individually to the screen, they will just have to have some math applied to them (for stretching, rotation, etc) before blitting them? And I suppose they are still blitted from the texture stored on the card? It's just a pixel-by-pixel render rather than putting them on a quad and blitting all at once?
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: 31 color blending modes

Post by paul doe »

dafhi wrote:I learned about bit masking from http://stereopsis.com/doubleblend.html
You know, now that I see the link, searching in my archive I see that I had that same page in it. Funny I didn't paid any attention to it at that time LOL

Thanks for sharing!
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: 31 color blending modes

Post by paul doe »

mrToad wrote:Screen setup, basic lines and shapes, flip/rotate/stretch, adjusting rgb values, and making use of some of the built-in blend modes like additive, but I assume that's nothing too extraordinary. So as pixels are placed individually to the screen, they will just have to have some math applied to them (for stretching, rotation, etc) before blitting them? And I suppose they are still blitted from the texture stored on the card? It's just a pixel-by-pixel render rather than putting them on a quad and blitting all at once?
Yep, something like that. In fact, you have to supply OpenGL the matrices for doing all that. You see, the modern pipeline empowers you to do incredibly cool stuff rather easily, while at the same time making simple stuff (like blitting a quad to screen) seem overly complicated. The flexibility does have its cost in complexity, but when you look at it in retrospective you realize that there's no better way to do it. Current-gen GPUs are optimized for bulk rendering, and the way you have to structure your data to upload it to the card accounts for this.

Just a little more time, I'm almost finished. I didn't have much time to code these days, so when I finish we will talk extensively about the way modern cards render stuff to the screen. Until then, have a look at this page, and see if you can make something out of it. It will help you immensely to understand the code of the GL blitter, and also give you a rough idea of how you have to set up the rendering of your app.

I've had a look at EasyGL2D7, and found that you'll be able to integrate it with your render code, but you'll probably have to make significant changes to it. I'll post the code, and you decide if it's worth trying or not. See you later.
mrToad
Posts: 430
Joined: Jun 07, 2005 23:03
Location: USA
Contact:

Re: 31 color blending modes

Post by mrToad »

paul doe wrote:The flexibility does have its cost in complexity, but when you look at it in retrospective you realize that there's no better way to do it.
Yes I get the feeling that is true. It seems to go in harmony with the whole idea of game-making in general (and other things in life), for me at least... Go to the lowest level if you want the most control and the best results. I know there are lines to be drawn, where effort and time needed is too much to be worth it, and that differs for everyone, but I may just be able to do this thing, perhaps as your inspiration and help affords. :)
paul doe wrote:Current-gen GPUs are optimized for bulk rendering, and the way you have to structure your data to upload it to the card accounts for this. [...] so when I finish we will talk extensively about the way modern cards render stuff to the screen.
Interesting... I look forward to it.
paul doe wrote:I've had a look at EasyGL2D7, and found that you'll be able to integrate it with your render code, but you'll probably have to make significant changes to it. I'll post the code, and you decide if it's worth trying or not. See you later.
I'm taking a look at the link already. Was EasyGL2D7 a typo? I don't have any 7 :D Definitely looking forward to this as well. Don't mind making changes. I don't think it will effect the current scripts or other engine code I have, that's the only thing I was concerned about. Even if so, the changes might only be here and there.
Post Reply