In a game that I am currently developing I use textures with premultiplied alpha colors (the default in XNA 4). On that basis, I create hybrid blending textures, which means that I mix traditional color alphablending and additive blending in one texture.
Basically, this is achieved by creating textures that include pixels of solid (RGBA with A = 255), transparent (R'G'B'A with A < 255 and R' = R * A) and additive blending colors (R''G''B''A with A < 255 and R'' != R * A). Usually, pure additive blending assumes A = 0 but that is not required here. The textures are created in the game by a mathematical function.
Now the problem is that these textures work great in the game but there seems to be no software tool that is able to edit such textures. While the PNG format seems to be able to keep the color information intact, any attempt to edit or save such file destroys the colors. So far I tried Adobe Photoshop, Gimp, Corel Draw and Visual Studio 11.
What I ultimately want to do is load these textures in a software and edit them and possibly save them as DDS (creating mipmaps).
Related
I'm testing Sokol library (https://github.com/floooh/sokol) to create a simple game sample with lighting in OpenGL, D3D11 and Metal. I'm using shaders similar from LearnOpenGL tutorials (https://learnopengl.com/Lighting/Light-casters).
This is part of my frag shader:
vec3 lightDir = normalize(light.position - v_position);
float diff = max(dot(normal, lightDir), 0.0);
diffuse = vec3(1.0,1.0,1.0) * diff * vec3(texture(u_diffuse, v_uv));
The colors in ground aren't continuous, you can see the color layers (look red lines).
Here is another sample using PBR shaders. Again, color in ground is not continuous.
Why this happens? How can I create a perfect plane ground?
The "bands" you see just differ by 1 in one of the color channels. You are just reaching the actual limit of 8 bit per channel color precision, there is just no other presentable color in between these two bands. Depending on the display and display settings you use, it will be more or less perceptible.
There are 3 possible solutions:
The effects are especially visible because your floor is colored in one solid color. The human eye will be most sensitive to such changes (see also mach band effect). By adding some structure / texture to it, it won't be perceivable any more.
Use a display with more then 8 bit per channel of color precision. HDR Displays nowadays do allow 10 or more bits.
Apply some dithering to the image to conceal the visible bands. Ordered dithering with some bayer pattern can be easily implemented in a GLSL shader.
I am currently working on a freehand drawing application where I need to support multiple background textures. For example, a paper-like texture or an image. The drawing on both background textures should behave identically.
It works great when using one or the other texture as a starting point for the drawing, i.e. blend all incoming strokes directly with the background texture.
However, I want to take a different approach: Drawing all strokes to an initially transparent layer, then blending this layer with the selected background. This has the advantage that the drawing is independent and separated from the background. For example I could blend the whole drawing with a different background without having to blend all strokes with this background directly.
The problem is: Depending on the color of the transparent layer, the outcome of the blended image (background + "stroke layer") looks totally different. For example, with rgba values, setting the transparent layer to transparent white (1,1,1,0) yields much brighter colors than setting the layer to transparent black (0,0,0,0). This makes sense because we have to blend the strokes with the transparent color. What I basically want to have is a "neutral" transparency. The strokes on this transparent layer should interact only with the background image, not with the transparent layer. The transparent layer should only be used to store the drawn strokes.
My question: Is this somehow possible? I can't find a way to solve this. The problem is that the transparent layer (which is just a texture with a transparent color) must have a color and incoming strokes must be blended with this color. Is there a way to avoid this somehow?
I figured out how to do it:
For blending two transparent colors, the Porter-Duff algorithm can be used. It is described here for example. Blending destination and source color can be done this way:
inline float4 porter_duff_blending(float4 dest, float4 source) {
float alpha = source.a;
float inv_alpha = 1 - alpha;
float blend_alpha = alpha + inv_alpha * dest.a;
float4 blend_color = (1.0 / blend_alpha) * ((alpha * source) + (inv_alpha * dest.a * dest));
blend_color.a = blend_alpha;
return blend_color;
};
This allows to have the drawing in a separate transparent layer which can be applied to different backgrounds.
Having some issues with smooth alpha gradients in texture files resulting in bad banding issues.
I have a 2D XNA WP7 game and I've come up with a fairly simple lighting system. I draw the areas that would be lit by the light in a separate RenderTarget2D, apply a sprite to dim the edges as you get further away from the light, then blend that final lighting image with the main image to make certain areas darker and lighter.
Here's what I've got so far:
As you can see, the banding is pretty bad. The alpha transparency is quite smooth in the source image, but whenever I draw the sprite, it gets these huge ugly steps between colors. Just to check I drew the spotlight mask straight onto the scene with normal alpha blending and I still got the banding.
Is there any way to preserve smooth alpha gradients when drawing sprites?
Is there any way to preserve smooth alpha gradients when drawing sprites?
No, you cannot. WP7 phones currently use 16 bit color range system. One pixes got: 5 red bits, 5 blue, 6 green (humans see a wider spectrum of green color).
Found out that with Mango, apps can now specify that they support 32bpp, and it will work on devices that support it!
For XNA, put this line at the top of OnNavigatedTo:
SharedGraphicsDeviceManager.Current.PreferredBackBufferFormat = SurfaceFormat.Color;
For Silverlight add BitsPerPixel="32" to the App element in WMAppManifest.xml.
I have a PNG-Image with alpha values and need to reduce the amount of colors. I need to have no more than 256 colors for all the colors in the image and so far everything I tried (from paint shop to leptonica, etc...) strips the image of the alpha channel and makes it unusable. Is there anything out there that does what I want ?
Edit: I do not want to use a 8-bit palette. I just need to reduce the numbers of color so that my own program can process the image.
Have you tried ImageMagick?
http://www.imagemagick.org/script/index.php
8-bit PNGs with alpha transparency will only render alpha on newer webbrowsers.
Here are some tools and website that does the conversion:
free pngquant
Adobe Fireworks
and website: http://www.8bitalpha.com/
Also, see similar question
The problem you describe is inherent in the PNG format. See the entry at Wikipedia and notice there's no entry in the color options table for Indexed & alpha. There's an ability to add an alpha value to each of the 256 colors, but typically only one palette entry will be made fully transparent and the rest will be fully opaque.
Paint Shop Pro has a couple of options for blending or simulating partial transparency in a paletted PNG - I know because I wrote it.
I have sprites that when they overlap I would like them to 'add' their colors rgb values to (potentially) go white, the sprites also have changin alpha values which should remain unchanged. I've already tried using all the spritebatch options alphablend, additive etc...
Is this possible through spritebatch or will i need a shader?
Thanks,
Paul.
Using the Premultiplied Alpha scheme in XNA 4, you can do additive blending by having your texture drawn at 0 alpha. Because this means that there is 0 blocking done by the texture, and then the RGB is added to the pixels behind it, you get additive blending.
Just draw the texture with 0 alpha using the spritebatch mode 'Alphablend'. To lower the additivity, increase alpha. To make it less visible, lower RGB.
I highly suggest making sure any textures in your content have the option 'Premultiplied Alpha' ticked in their properties, if you use this.