I'm using SpriteBatch to draw a Texture2D on the screen and was wondering how I could manipulate the the images opacity? Anyone know the best way in accomplishing this?
Assuming you are using XNA 4.0 with premultiplied alpha. In your spritebatch.draw multiply the color by a float, 0.5f for 50% transparency, and draw as you would normally. If you are not using premultiplied alpha I suggest you do for performance reasons and its more intuitive after you get used to it.
Example:
_spriteBatch.Draw(texture, location, Color.White * 0.5f);
Edit:
Also make sure you set your blend state to BlendState.AlphaBlend, or another blend state that supports alpha and is not NonPremultiplied.
Example:
_spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
Just use color as new Color(RGBA); where:
R is Red
G is Green
B is Blue
A is Alpha
For instance:
new Color(100, 100, 100, 100);
Related
I'm having trouble setting up blending in Metal. Even when starting with the Hello Triangle example provided by Apple, using the following code
pipelineStateDescriptor.colorAttachments[0].blendingEnabled = YES;
pipelineStateDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorZero;
pipelineStateDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorZero;
and the fragment function
fragment float4 fragmentShader(RasterizerData in [[stage_in]]) {
return float4(in.color.rgb, 0);
}
the triangle still draws completely opaque. What I want to achieve in the end is blending between two shapes by using different blending factors, but I thought I would start with a simple example to understand what is going on. What am I missing?
sourceAlphaBlendFactor and destinationAlphaBlendFactor are to do with constructing a blend for the alpha channel. i.e. they control the alpha that will be written into your destination buffer, which will not really be visible to you. You are probably more interested in the RGB that is written into the frame buffer.
Try setting values for sourceRGBBlendFactor and destinationRGBBlendFactor instead. For traditional alpha blending set sourceRGBBlendFactor to MTLBlendFactorSourceAlpha and set destinationRGBBlendFactor to MTLBlendFactorOneMinusSourceAlpha
Can anyone suggest why my low opacity painting does this weird blending, while the SketchBookX app does it perfect?
In both images attached the vertical strokes on the left are done at full opacity, the strokes on the right are done at low opacity. The top image is mine and as you can see the strokes on the right at low opacity turn a orange-red color and don't blend/mesh with the full opacity strokes. But the SketchBookX app blends perfectly and maintains the same color.
I'm using glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) and have tried many variations with no luck, so I'm starting to think there are other things that are giving me this problem.
Do I need to handle this problem in the fragment shader? I currently have this,gl_FragColor = color * rotatedTexture; I'm using PNGs for brush textures.
UPDATE: Im getting the same results without using a texture. gl_FragColor = color;
I want it to be like mixing ink, not like mixing light :)
I'm using GLKit for an iPad app. With this code I setup blending:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
It works fine, but when I try to get a screenshot the blend mode seems wrong. It doesn't matter if I use GLKit's snapshot or glReadPixels.
This is what I get when working with the app:
And this is the screenshot:
Do I have to change the Blend Mode or something before I make the screenshot? And if so, to what?
The problem you are having lies most likely in how the image is generated from the RGBA data. To solve this you will need to skip the alpha channel when creating CGImage with kCGImageAlphaNoneSkipLast or have the correct alpha values in the buffer in the first place.
To explain what is going. Your GL buffer consists of RGBA values but only RGB part is used to present it but when you create the image you use the alpha channel as well, thus the difference. How it comes to this is very simple, lets take a single pixel somewhere in the middle of the screen and go through its events:
You clear the pixel to any color you want
You overwrite the pixel (all 4 channels RGBA) with a solid color received from the texture for instance (.8, .8, .8, 1.0)
You draw a color over that pixel with some smaller alpha value and try to blend it, for instance (.4, .4, .4, .25). Your blend function says to multiply the source color with the source alpha and the destination with 1 - source alpha. That results in (.4, .4, .4, .25)*.25 + (.8, .8, .8, 1.0)*.75 = (.7, .7, .7, .76)
Now the result (.7, .7, .7, .76) is displayed nicely because your buffer only presents the RGB part resulting in seeing (.7, .7, .7, 1.0) but when you use all 4 components to create the image you also use the .76 alpha value which is further used to blend the image itself. Therefor you need to skip the alpha part at some point.
There is another way: As you can see in your case there is really no need to store the alpha value to the render buffer at all as you never use it, in your blend function you only use source alpha. Therefore you may just disable it using glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE), this also means you need to clear the alpha value to 1.0 (glClearColor(x,x,x,1.0))
I'm just starting game development and I thought a game like Tank wars or Worms would be nice.
The hardest part I can think of so far is making the terrain destructible and I want to know how it's done before doing the easy parts.
I thought that explosion could have a mask texture which could be scaled for different weapons. Then using that mask I should make underlying terrain transparent (and optionally draw a dark border).
(source: mikakolari.fi)
How do I achieve that?
Do I have to change the alpha value pixel by pixel or can I use some kind of masking technique? Drawing a blue circle on top of the terrain isn't an option.
I have versions 3.1 and 4.0 of XNA.
This tutorial is what you are searching:
http://www.riemers.net/eng/Tutorials/XNA/Csharp/series2d.php
Capter 20: Adding explosion craters
In short:
You have 2 textures: 1 Color Texture (visible), 1 Collision Texture (invisible)
You substract the explosion image from your collision texture.
To get the dark border: expand the explosion texture and darken the color in this area.
Now you generate a new Color Texture (old color - collison = new color).
This is a difficult question to answer - because there are many ways you could do it. And there are pros and cons to each method. I'll just give an overview:
As an overall design, you need to keep track of: the original texture, the "darkness" applied, and the "transparency" applied. One thing I can say almost for sure is you want to "accumulate" the results of the explosions somewhere - what you don't want to be doing is maintaining a list of all explosions that have ever happened.
So you have surfaces for texture, darkness and transparency. You could probably merge darkness and transparency into a single surface with a single channel that stores "normal", "dark" (or a level of darkness) and "transparent".
Because you probably don't want the dark rings to get progressively darker where they intersect, when you apply an explosion to your darkness layer with the max function (Math.Max in C#).
To produce your final texture you could just write from the darkness/transparency texture to your original texture or a copy of it (you only need to update the area that each explosion touches).
Or you could use a pixel shader to combine them - the details of which are beyond the scope of this question. (Also a pixel shader won't work on XNA 4.0 on Windows Phone 7.)
You should Make a new Texure2D with the Color of desired pixels.Alpha = 0.
Color[] bits = new Color[Texture.Width * Texture.Height];
Texture.GetData(bits);
foreach(Vector2D pixel in overlapedArea)
{
int x = (int)(pixel.X);
int y = (int)(pixel.Y);
bits[x + y * texture.Width] = Color.FromNonPremultiplied(0,0,0,0));
}
Texture2D newTexture = new Texture2D(texture.GraphicsDevice, texture.Width, texture.Height);
newTexture.SetData(bits);
Now replace the new Texture2D with the Last Texture and you're good to go!
For more code about Collision, or changing texture pixels color go to this page for codes:
http://www.codeproject.com/Articles/328894/XNA-Sprite-Class-with-useful-methods
How can I alphablend only certain parts of a texture in DX 9?
For example, layers in Photoshop (or any other photo editing program that supports layers).
You can draw something in a layer (background filled with alpha), then place the layer over the original image (draw the texture on the screen) which leads to the original image + ONLY the things I drew in the layer.
Yes, I know my english is not very "shiny".
Thank you very much, in advance!
P.S. The background of my texture IS filled with alpha.
So you have setup the alpha on the texture you wish to overlay such that 0 is transparent (ie shows whats underneath) and 1 is opaque (ie shows the overlay texture)?
If so then you just need to set up a a simple blend mode:
pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
Make sure you draw the background first! Also note that values between 0 and 1 represent a linear interpolation between background and the overlay texture.