www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - SDL2 texture blend help

reply Ivan Trombley <itrombley dot-borg.org> writes:
Experimenting with compositing images in SDL2, I get a dark edge 
around my textures. In the image below, you can see the top 
example where I composite the cyan image on top of the 
blue/magenta image looks correct but the bottom example, which is 
done using SDL_RenderCopy is not correct.

http://a4.pbase.com/o10/09/605909/1/166698494.lCoVTgcI.example.png

I tried premultiplying the the colors in the cyan image and 
setting the blend function as such...

   SDL_SetTextureBlendMode(texture, SDL_ComposeCustomBlendMode(
       SDL_BlendFactor.SDL_BLENDFACTOR_ONE,
       SDL_BlendFactor.SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
       SDL_BlendOperation.SDL_BLENDOPERATION_ADD,
       SDL_BlendFactor.SDL_BLENDFACTOR_ONE,
       SDL_BlendFactor.SDL_BLENDFACTOR_ONE,
       SDL_BlendOperation.SDL_BLENDOPERATION_ADD));

...but that produces the exact same thing.


Any SDL experts out there that can give me a clue?
Dec 10 2017
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Monday, 11 December 2017 at 04:57:44 UTC, Ivan Trombley wrote:
 Any SDL experts out there that can give me a clue?
I've used SDL quite a bit, but can't help with your specific problem. However, I suggest you try the new(ish) SDL forums for stuff like this. It's particularly off topic here. https://discourse.libsdl.org
Dec 10 2017
parent Ivan Trombley <itrombley dot-borg.org> writes:
On Monday, 11 December 2017 at 07:04:19 UTC, Mike Parker wrote:
 On Monday, 11 December 2017 at 04:57:44 UTC, Ivan Trombley 
 wrote:
 Any SDL experts out there that can give me a clue?
I've used SDL quite a bit, but can't help with your specific problem. However, I suggest you try the new(ish) SDL forums for stuff like this. It's particularly off topic here. https://discourse.libsdl.org
Thanks for the link.
Dec 10 2017
prev sibling next sibling parent Dmitry <dmitry indiedev.ru> writes:
On Monday, 11 December 2017 at 04:57:44 UTC, Ivan Trombley wrote:
 Experimenting with compositing images in SDL2, I get a dark 
 edge around my textures. In the image below, you can see the 
 top example where I composite the cyan image on top of the 
 blue/magenta image looks correct but the bottom example, which 
 is done using SDL_RenderCopy is not correct.
Won't this help? https://stackoverflow.com/questions/45781683/how-to-get-correct-sourceover-alpha-compositing-in-sdl-with-opengl
Dec 11 2017
prev sibling next sibling parent Dave Jones <dave jones.com> writes:
On Monday, 11 December 2017 at 04:57:44 UTC, Ivan Trombley wrote:
 Experimenting with compositing images in SDL2, I get a dark 
 edge around my textures. In the image below, you can see the 
 top example where I composite the cyan image on top of the 
 blue/magenta image looks correct but the bottom example, which 
 is done using SDL_RenderCopy is not correct.

 http://a4.pbase.com/o10/09/605909/1/166698494.lCoVTgcI.example.png

 I tried premultiplying the the colors in the cyan image and 
 setting the blend function as such...

   SDL_SetTextureBlendMode(texture, SDL_ComposeCustomBlendMode(
       SDL_BlendFactor.SDL_BLENDFACTOR_ONE,
       SDL_BlendFactor.SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
       SDL_BlendOperation.SDL_BLENDOPERATION_ADD,
       SDL_BlendFactor.SDL_BLENDFACTOR_ONE,
       SDL_BlendFactor.SDL_BLENDFACTOR_ONE,
       SDL_BlendOperation.SDL_BLENDOPERATION_ADD));

 ...but that produces the exact same thing.


 Any SDL experts out there that can give me a clue?
I dont know SDL but what your describing sounds like the cyan image already has premultiplied alpha and the blend operation is doubling down on that. Have you tried the above blend op without premultiplying the cyan image?
Dec 11 2017
prev sibling parent reply Ivan Trombley <itrombley dot-borg.org> writes:
It turns out that it's an issue with the color channels being in 
sRGB color space and the alpha channel being linear. I verified 
this by doing a software blend of the images and then doing 
another software blend using gamma corrected values.

There's a setting in opengl to correct for it, 
glEnable(GL_FRAMEBUFFER_SRGB), but I haven't tried this yet.
Dec 11 2017
parent reply Dmitry <dmitry indiedev.ru> writes:
On Tuesday, 12 December 2017 at 03:32:05 UTC, Ivan Trombley wrote:
 It turns out that it's an issue with the color channels being 
 in sRGB color space and the alpha channel being linear. I 
 verified this by doing a software blend of the images and then 
 doing another software blend using gamma corrected values.

 There's a setting in opengl to correct for it, 
 glEnable(GL_FRAMEBUFFER_SRGB), but I haven't tried this yet.
BTW, also you could use bleeding (for example, https://github.com/dmi7ry/alpha-bleeding-d )
Dec 11 2017
parent reply Ivan Trombley <itrombley dot-borg.org> writes:
On Tuesday, 12 December 2017 at 03:34:51 UTC, Dmitry wrote:
 On Tuesday, 12 December 2017 at 03:32:05 UTC, Ivan Trombley 
 wrote:
 It turns out that it's an issue with the color channels being 
 in sRGB color space and the alpha channel being linear. I 
 verified this by doing a software blend of the images and then 
 doing another software blend using gamma corrected values.

 There's a setting in opengl to correct for it, 
 glEnable(GL_FRAMEBUFFER_SRGB), but I haven't tried this yet.
BTW, also you could use bleeding (for example, https://github.com/dmi7ry/alpha-bleeding-d )
This isn't a scaling problem (which is totally solved by pre-multiplying the alpha with the colors BTW). This is a gamma correction problem which is solved only by converting the color values to linear color space before compositing and then converting the final pixel back to sRGB.
Dec 11 2017
parent reply Dmitry <dmitry indiedev.ru> writes:
On Tuesday, 12 December 2017 at 06:27:30 UTC, Ivan Trombley wrote:
 This isn't a scaling problem (which is totally solved by
Scaling is not a prerequisite for this problem.
 pre-multiplying the alpha with the colors BTW). This is a gamma
How did you this? Using editor or using shader? If shder, show the code. Can you share both images? I want to check.
 correction problem which is solved only by converting the color 
 values to linear color space before compositing and then 
 converting the final pixel back to sRGB.
Are you sure in that? Because what I see is typical alpha blending problem.
Dec 11 2017
parent reply Ivan Trombley <itrombley dot-borg.org> writes:
On Tuesday, 12 December 2017 at 07:12:07 UTC, Dmitry wrote:
 On Tuesday, 12 December 2017 at 06:27:30 UTC, Ivan Trombley 
 wrote:
 This isn't a scaling problem (which is totally solved by
Scaling is not a prerequisite for this problem.
 pre-multiplying the alpha with the colors BTW). This is a gamma
How did you this? Using editor or using shader? If shder, show the code. Can you share both images? I want to check.
 correction problem which is solved only by converting the 
 color values to linear color space before compositing and then 
 converting the final pixel back to sRGB.
Are you sure in that? Because what I see is typical alpha blending problem.
Here's the code that produces the correct results (exactly the same as GIMP): auto bk =IMG_Load(toStringz(folder ~ "/background.png")); auto fg =IMG_Load(toStringz(folder ~ "/image.png")); enum c = (1.0f / 255.0f); enum g = 2.2f; enum ig = (1.0f / 2.2f); immutable int x = (bk.w - fg.w) / 2; immutable int y = (bk.h - fg.h) / 2; auto dst = cast(ubyte*) bk.pixels + y * bk.pitch + x * 3; immutable size_t add = bk.pitch - fg.w * 3; auto src = cast(ubyte*) fg.pixels; const auto max = src + fg.h * fg.pitch; while (src < max) { const auto line = dst + fg.w * 3; while (dst < line) { immutable float a = c * src[3]; dst[0] = cast(ubyte)(((1 - a) * (dst[0] * c) ^^ g + a * (src[0] * c) ^^ g) ^^ ig * 255); dst[1] = cast(ubyte)(((1 - a) * (dst[1] * c) ^^ g + a * (src[1] * c) ^^ g) ^^ ig * 255); dst[2] = cast(ubyte)(((1 - a) * (dst[2] * c) ^^ g + a * (src[2] * c) ^^ g) ^^ ig * 255); src += 4; dst += 3; } dst += add; }
Dec 12 2017
next sibling parent Ivan Trombley <itrombley dot-borg.org> writes:
GIMP 2.9, that is.
Dec 12 2017
prev sibling parent reply Dmitry <dmitry indiedev.ru> writes:
On Tuesday, 12 December 2017 at 23:28:23 UTC, Ivan Trombley wrote:
 Here's the code that produces the correct results (exactly the 
 same as GIMP):
Share images you used, please.
Dec 12 2017
parent reply Ivan Trombley <itrombley dot-borg.org> writes:
On Wednesday, 13 December 2017 at 01:44:33 UTC, Dmitry wrote:
 On Tuesday, 12 December 2017 at 23:28:23 UTC, Ivan Trombley 
 wrote:
 Here's the code that produces the correct results (exactly the 
 same as GIMP):
Share images you used, please.
Background image: http://a4.pbase.com/o10/09/605909/1/166706859.XKZZCnSO.background.png Foreground image: http://a4.pbase.com/o10/09/605909/1/166706860.c1yD4VWp.image.png Composited through SDL: http://a4.pbase.com/o10/09/605909/1/166706869.wLt9RofY.sdl.png Composited in GIMP 2.9: http://a4.pbase.com/o10/09/605909/1/166706870.S01BIhVG.gimp.png When composited using the code I posted looks exactly like the GIMP 2.9 image.
Dec 12 2017
next sibling parent Ivan Trombley <itrombley dot-borg.org> writes:
Here's a page that describes the issue:
http://ssp.impulsetrain.com/gamma-premult.html
Dec 12 2017
prev sibling next sibling parent Dmitry <dmitry indiedev.ru> writes:
On Wednesday, 13 December 2017 at 03:03:09 UTC, Ivan Trombley 
wrote:
 Foreground image:
 http://a4.pbase.com/o10/09/605909/1/166706860.c1yD4VWp.image.png
Okay, I see. With this image it's obvious that it's not a just blending problem. But previous was look exactly as blending problem. Sorry that took your time.
Dec 13 2017
prev sibling parent reply =?UTF-8?Q?Martin_Dra=c5=a1ar?= <drasar ics.muni.cz> writes:
Dne 13.12.2017 v 4:03 Ivan Trombley via Digitalmars-d napsal(a):
 On Wednesday, 13 December 2017 at 01:44:33 UTC, Dmitry wrote:
 On Tuesday, 12 December 2017 at 23:28:23 UTC, Ivan Trombley wrote:
 Here's the code that produces the correct results (exactly the same
 as GIMP):
Share images you used, please.
Background image: http://a4.pbase.com/o10/09/605909/1/166706859.XKZZCnSO.background.png Foreground image: http://a4.pbase.com/o10/09/605909/1/166706860.c1yD4VWp.image.png Composited through SDL: http://a4.pbase.com/o10/09/605909/1/166706869.wLt9RofY.sdl.png Composited in GIMP 2.9: http://a4.pbase.com/o10/09/605909/1/166706870.S01BIhVG.gimp.png When composited using the code I posted looks exactly like the GIMP 2.9 image.
I am not sure, about the tool you use to view the images, but on my side (Firefox browser) the sdl and gimp output are very different. Maybe some gamma shenanigans going on? Maybe related to PNG Gamma correction...
Dec 13 2017
parent Ivan Trombley <itrombley dot-borg.org> writes:
On Wednesday, 13 December 2017 at 13:54:28 UTC, Martin DraĊĦar 
wrote:
 Dne 13.12.2017 v 4:03 Ivan Trombley via Digitalmars-d napsal(a):
 On Wednesday, 13 December 2017 at 01:44:33 UTC, Dmitry wrote:
 On Tuesday, 12 December 2017 at 23:28:23 UTC, Ivan Trombley 
 wrote:
 Here's the code that produces the correct results (exactly 
 the same
 as GIMP):
Share images you used, please.
Background image: http://a4.pbase.com/o10/09/605909/1/166706859.XKZZCnSO.background.png Foreground image: http://a4.pbase.com/o10/09/605909/1/166706860.c1yD4VWp.image.png Composited through SDL: http://a4.pbase.com/o10/09/605909/1/166706869.wLt9RofY.sdl.png Composited in GIMP 2.9: http://a4.pbase.com/o10/09/605909/1/166706870.S01BIhVG.gimp.png When composited using the code I posted looks exactly like the GIMP 2.9 image.
I am not sure, about the tool you use to view the images, but on my side (Firefox browser) the sdl and gimp output are very different. Maybe some gamma shenanigans going on? Maybe related to PNG Gamma correction...
Gamma is exactly the problem. A page back I posted some code that will overlay the image onto the background by converting the source and destination pixels to linear RGB, compositing them and then converting the final pixel back to sRGB for display. That code produces the same results as GIMP. Now I just need to figure out how to make GL_FRAMEBUFFER_SRGB (which is supposed to do the right thing in the GPU) work with SDL.
Dec 13 2017