[SOLVED] Sprite Edge Aliasing Trouble

Before I begin, let me say that I am a long time user of Monogame. I love the software and the open source community that came together to produce it. For everyone who contributed to monogame, thanks a million. You rule.

Down to business. I’ve been working on a 2d action platforming game for about a year and a half now. At the current stage of my game I am using Monogame 3.5 for Windows.Using MGCB and Inkscape I’ve hashed out a basic level editor that turns out rendered images and compiles them for use with monogame. The abridged version of this:
-In inkscape, I draw and mark each layer as a decoration
-With inkscape’s python extensions I create a response file for mgcb to consume
-Inkscape then spits out the marked layers as .pngs
-Inkscape’s python ap then calls mgcb.exe to process the images and create a level file

This process was working great until I tried getting more detailed with theimages I was rendering. Here’s a couple of pictures of the culprits.

This is a rendering of a plant decoration for my game.

Here’s the plant in-game.

Not quite the same thing. There are visble artifacts on the plant and the surrounding boulders as well. Images only get you so far, everybody likes details: I render the bush as a .png and then the response file that consumes the .png will look something like this.

/platform:Windows
/outputDir:C:\Users\Connor\Documents\Visual Studio 2013\Projects\CodeQuartz\CodeQuartz\Content\bin\DesktopGL
/intermediateDir:C:\Users\Connor\Documents\Visual Studio 2013\Projects\CodeQuartz\CodeQuartz\Content\obj\DesktopGL
/importer:TextureImporter
/processor:TextureProcessor
/build:layer240-0.png
/build:layer100-0.png
/build:layer470-0.png
/build:layer60-0.png

Where layer240-0.png would be our plant rendering. The processor parameters for the texture are left at the default, which means I am working with a premultiplied alpha. The plant (as well as the rest of the decorations) are drawn with premultiplied blend mode. I have tried playing around with the alpha blending settings as well as color keying with more or less the same result. If anybody has any hints or ideas of what might be going on, please let me know. Thanks in advance.

The reason for that fringing is that when exporting the image, Inkscape is blending the green into the white background at the same time it is reducing the alpha to zero. You can see that on your rocks as well.

In your image, the RGB colours need to extend beyond the edges of the leaves and leave the alpha channel to define the shape and anti-aliasing of the leaves. How to do this in Inkscape I have no idea. Photoshop can edit the RGB and alpha channels separately, but I use a free image editor called Pixelformer that allows easy editing of RGB and alpha channels separately, then export as PNG for the content pipeline to build into textures.

1 Like

Hey, thanks for the snappy response. Thought I’d mention, the .png of the plant that I uploaded is the actual image in the game, alpha channel and all. Also, the white background isn’t actually from inkscape either, that is just me clearing the render target with white every frame. I have made the background everything from blue to purple and ended up with the same wrong edge color in all of the sprites.

This is not a MonoGame rendering issue. Can you upload the PNG of the plant somewhere so I can take a look? I still think the RGB channels in the PNG contain white in the transparent areas and the edges of the green are blended into the white.

@TheFamedClock Just a hunch, Mipmapping stuff? what is your content building setup? your method is alien to me so just umm going through the hoops might work I think… try the manual method perhaps? good luck though…

EDIT:

Another thing, Power of 2^ perhaps? 96x69px… try 128x64 and see if it fixes anything… found this that might be helpful… Make better textures, optimising, 'power of two' and correct sizes : KatsBits TUTORIAL

I will upload a .png when I get back to work. Thank you very much for looking at this for me.

Sounds like a few things to try. Though I don’t know why mipmapping would be used, I never make reference to it. Powers of two is a optimization for the way textures are loaded in graphics cards, not really applicable here.

@TheFamedClock - I’ve just had a look at the plant image in the first post and opened it up in “Paint.net” - it looks ok to me as an image.

Also, the white background isn’t actually from inkscape either, that is just me clearing the render target with white every frame.<<

Maybe if you could supply the actual code where your drawing the background, rocks, plants someone might spot something in there that is wrong. Have you tried drawing the plant directly to the spritebatch rather than a rendertarget to see if that is different?

1 Like

@KonajuGames Hey, you were asking for the plant to be uploaded somewhere. Here’s the plant on imgur. http://imgur.com/CuJjzm6

@Harag You were asking about some code. All of the drawing for this takes place in my decoration class, which is just a wrapper around a texture2D and a Rectangle. After a few layers of abstraction, the texture is loaded into a dictionary:

textures.Add(Content.Load<Texture2D>(texture));

and then passed into the decoration constructor from a level class here:

decorations.Add(new Decoration(new DecorationVertices(textures[decoration.textureIndex], decoration.dimensions)));

Here is the body of the draw call:

camera.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied, SamplerState.AnisotropicClamp, null, null, null, camera.view);
                camera.spriteBatch.Draw(texture, rectangle.Location.ToVector2(), Color.White);
camera.spriteBatch.End();

I don’t think that I’m doing anything too crazy with the drawing here. I’ve tried an alpha blendstate as well with worse results. Like KonajuGames said, I imagine this must be a way that inkscape is handling the way that alpha is being stored on the edges of .pngs I am loading. Thoughts?

The image TheFamedClock uploaded is ok.
Here it is with a white background:

and with a black one:

So it’s no background-bleeding issue.

@TheFamedClock what are your settings in the content pipeline?
One of my textures for example has these settings:

I’m not using the content pipeline, I’m using MGCB.exe with all default values. Though I just discovered that the content project is clearing the bin directory every game start, so instead of using the compiled .xnb files it is using the .png version. This may have something to do with the bleeding. I’m going to see if that is the problem here.

Having looked at the texture, it does look ok. The RGB values do extend beyond the alpha edge and are not blended with the RGB in the transparent area. So that is ok.

MGCB is the tool that implements most of the content pipeline. What I did notice is that by default all textures are converted to premultiplied alpha, but you are rendering using BlendState.NonPremultiplied. That is not going to work properly. BlendState.NonPremultiplied is for textures where the PremultiplyAlpha property is set to False or for textures loaded through Texture2D.FromStream().

1 Like

I would think again…

Read that link I sent you for a refresher of why ^2 is relevant here… I think it is what is causing your issue…

1 Like

@KonajuGames Switching the blend mode to alpha over makes the problem worse, but I think this is because my game is loading actual images instead of compiled assets. The Content Pipeline is clearing all of my .xnb every run, so that could be why everything is breaking.

@MrValentine It appears that the images being loaded are not being resized to a power of 2 like you suggested. After I get the compiled assets to load properly I’ll let you know how your suggestion works.

1 Like

After much dicking around in the bin folder, I loaded the proper .xnb instead of the .png and the alpha blend started working properly. Thanks everyone for your help.

2 Likes

still stick to ^2 images, otherwise you will have artefacts and poor performance as the system has to fill in the missing space…

Good going, and sharing the fix helps, mark [SOLVED]

1 Like

I’m still keen to find out why it was showing the fringing when loaded straight from PNG and rendered using BlendState.NonPremultiplied on Windows OpenGL.

1 Like

Does the content pipeline append the missing pixels? if so then it is outputting a ^2 image removing any blending or blurring in the final image…

It does not change the dimensions of the input file in any way by default. There are options to make it POT (Power Of Two), but they’re not on by default.

I don’t understand what this means.

I mean the effect of adding the missing pixels avoids a renderer adding them and thus reshaping or stretching pixels… see that link I posted earlier…