How to draw a spritebatch without Color? - xna

I'm drawing a Texture2D like this
//background_texture is white in color
spritebatch.Draw(content.Load<Texture2D>("background_texture"),
new Rectangle(10, 10, 100, 100),
Color.Red)
The texture is white; however, on screen it's displayed as red.
Why is the draw method requiring a Color?
How does one simply draw the texture, and only the texture without having Color.something distort the graphic?

take a look at the documentation here:
http://msdn.microsoft.com/en-us/library/ff433986.aspx
you want to try Color.White, that additional parameter of a color typically refers to a tint, while a white "tint" should display the sprite without a tint

Color.White does not change the color of your image. Use
spritebatch.Draw(content.Load<Texture2D>("background_texture"),
new Rectangle(10, 10, 100, 100),
Color.White);
Instead of Color.Red, which applies a tint.
Note: Be careful. Intellisense will want to make this Color.Wheat, so be sure to type the first 3 letters before you hit space.

Color.White is uneccesary because in default sprite shader it looks like this:
PixelShader....
{
....
return Texture * Color;
}
Where color is Color that is given from Vertex shader defined by that Color in spritebatch.Draw... if it would be null, black, it would create invisible sprites. Whole point is that by this you set vertex color of each vertex that is used as multiplicative to texture you set for sprite.

Related

SceneKit shader modifier is not modifying the geometry's position

I am trying to apply a simple shader modifier to move the position of the cube. The regular diffuse color of the cube is a light blue, but with this modifier is does turn red, so I know the shader modifier is working (somewhat). However, the cube remains in the center of the screen at the position (0,0,0), so the position is not being modified by the shader modifier. Any ideas?
Here is the code
let modifier = """
_surface.diffuse = float4(1,0,0,1);
_surface.position = float3(10.0,0.0,0.0);
"""
cube.geometry?.shaderModifiers = [SCNShaderModifierEntryPoint.surface : modifier]
The magenta tint is SceneKit's way to indicate that a shader has failed to compile.
_surface.position = float3(10.0,0.0,0.0);
Looking at SCNShadable.h we see that SCNShaderSurface's position is a float4, not a float3.

Alpha masks bounding box transparency clashing / overwriting with other alpha masks. XNA

Above is an example of my problem. I have two alpha masks that are exactly the same, just a circle white gradient with transparent background.
I am drawing to a RenderTexture2D that is rendered above the screen to creating lighting. It clears a semi transparent black color, and then the alpha masks are drawn in the correct position to appear like lights..
On their own it works fine, but if two clash, like the below "torch" against the blue glowing mushrooms, you can see the bounding box transparency is overwriting the already drawn orange glow.
Here is my approach:
This is creating the render target:
RenderTarget2D = new RenderTarget2D(Global.GraphicsDevice, Global.Resolution.X+4, Global.Resolution.Y+4);
SpriteBatch = new SpriteBatch(Global.GraphicsDevice);
This is drawing to the render target:
private void UpdateRenderTarget()
{
Global.GraphicsDevice.SetRenderTarget(RenderTarget2D);
Global.GraphicsDevice.Clear(ClearColor);
// Draw textures
float i = 0;
foreach (DrawableTexture item in DrawableTextures)
{
i += 0.1f;
item.Update?.Invoke(item);
SpriteBatch.Begin(SpriteSortMode.Immediate, item.Blend,
SamplerState.PointClamp, DepthStencilState.Default,
RasterizerState.CullNone);
SpriteBatch.Draw(
item.Texture,
(item.Position - Position) + (item.Texture.Size() / 2 * (1 - item.Scale)),
null,
item.Color,
0,
Vector2.Zero,
item.Scale,
SpriteEffects.None,
i
);
SpriteBatch.End();
}
Global.GraphicsDevice.SetRenderTarget(null);
}
I have heard about depth stencils etc.. and I feel like I have tried so many combinations of things but I am still getting the issue. I haven't had any troubles with this while building all the other graphics in my game.
Any help is greatly appreciated thanks! :)
Ah, this turned out to be a problem with the BlendState itself rather than the SpriteBatch. I had created a custom BlendState "Multiply" which I picked up online that was causing the issue.
"whats causing" the problem was the real question here.
This was the solution to get my effect without "overlapping":
public static BlendState Lighting = new BlendState
{
ColorSourceBlend = Blend.One,
ColorDestinationBlend = Blend.One,
AlphaSourceBlend = Blend.Zero,
AlphaDestinationBlend = Blend.InverseSourceColor
};
This allows the textures to overlap, and also "subtracts" from the "darkness" layer. It would be easier to see if the darkness was more opaque.
I have answered this just incase some other fool mistakes a blend state problem with the sprite batch itself.

Change texture transparency at runtime on MonoGame

I am very new with MonoGame library.
I load a texture from .xnb file
_background = content.Load<Texture2D>(_backgroundKey);
and then i want to change it transparancy(alpha) at the runtime.
Oh i found how to do it myself
spriteBatch.Draw(texture, position, sourceRect, Color.White * 0.5f, .......);
This line of code will draw the texture at half transparency.
You can change the opacity of a texture by using a (semi-)transparent color in the draw call:
spriteBatch.Draw(texture, position, new Color(Color.Pink, 0.5f);
The values range from 0 (completely transparent) to 1 (completely opaque). Color has a lot of different constructors, so you can also pass a byte (0-255) instead of a float, which will result in the same thing.

Issue with transparency while drawing with RenderToSurface

I am facing issue while drawing semitransparent object with RenderToSurface(While it working file when i am drawing object direct on device). Issue is when i m drawing a object with Alpha value 50% on RenderToSurface, and when i am drawing surface to device then transparency of object is not valid. My code is as follow.
[code] RenderingSurface.BeginScene(RenderTexture.GetSurfaceLevel(0), view);
_device.Clear(ClearFlags.Target| ClearFlags.ZBuffer, Color.FromArgb(0, Color.Black), 1.0f, 0);
using (Sprite s = new Sprite(_device))
{
s.Begin(SpriteFlags.DoNotSaveState);
s.Draw(ObjecTexture, new Microsoft.DirectX.Vector3(0, 0, 0), new Microsoft.DirectX.Vector3(0, 1, 0), Color.White.ToArgb());
s.End();
}
RenderingSurface.EndScene(Filter.None);
RenderSurface have same shape with 50% tranparency.
Code to Draw Surface.
_device.BeginScene();
_device.Clear(ClearFlags.Target | ClearFlags.ZBuffer | ClearFlags.Stencil, BackgroundColor, 1, 0);
using (Sprite s = new Sprite(_device))
{
s.Begin(SpriteFlags.DoNotSaveState);
s.Draw(RenderTexture, new Microsoft.DirectX.Vector3(0, 0, 0), new Microsoft.DirectX.Vector3(0, 1, 0), Color.White.ToArgb());
s.End();
}
Make sure your RenderSurface render target is created with a PixelFormat that has an alpha channel (A8R8G8B8 rather than X8R8G8B8).
Also, when rendering in the render target, make sure the resulting alpha is being written to the surface using the right blend mode render states for the alpha channel. Please note that blend modes for alpha (AlphaDestinationBlend, AlphaSourceBlend, ...) and colors (DestinationBlend, SourceBlend, ...) are different; make sure you set both.

XNA Alpha Blending to make part of a texture transparent

What I am trying to do is use alpha blending in XNA to make part of a drawn texture transparent. So for instance, I clear the screen to some color, lets say Blue. Then I draw a texture that is red. Finally I draw a texture that is just a radial gradient from completely transparent in the center to completely black at the edge. What I want is the Red texture drawn earlier to be transparent in the same places as the radial gradient texture. So you should be able to see the blue back ground through the red texture.
I thought that this would work.
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteBlendMode.None);
spriteBatch.Draw(bg, new Vector2(0, 0), Color.White);
spriteBatch.End();
spriteBatch.Begin(SpriteBlendMode.None);
GraphicsDevice.RenderState.AlphaBlendEnable = true;
GraphicsDevice.RenderState.AlphaSourceBlend = Blend.One;
GraphicsDevice.RenderState.AlphaDestinationBlend = Blend.Zero;
GraphicsDevice.RenderState.SourceBlend = Blend.Zero;
GraphicsDevice.RenderState.DestinationBlend = Blend.One;
GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add;
spriteBatch.Draw(circle, new Vector2(0, 0), Color.White);
spriteBatch.End();
GraphicsDevice.RenderState.AlphaBlendEnable = false;
But it just seems to ignore all my RenderState settings. I also tried setting the SpriteBlendMode to AlphaBlend. It blends the textures, but that is not the effect I want.
Any help would be appreciated.
What you're trying to to is alpha channel masking.The easiest way is to bake the alpha channel using the content pipeline. But if for some reason you want to do it at runtime here's how (roughly) using a render target (A better and faster solution would be to write a shader)
First create a RenderTarget2D to store and intermediate masked texture
RenderTarget2D maskRenderTarget = GfxComponent.CreateRenderTarget(GraphicsDevice,
1, SurfaceFormat.Single);
Set the renderTarget, and device state
GraphicsDevice.SetRenderTarget(0, maskRenderTarget);
GraphicsDevice.RenderState.AlphaBlendEnable = true;
GraphicsDevice.RenderState.DestinationBlend = Blend.Zero;
GraphicsDevice.RenderState.SourceBlend = Blend.One;
Set the channels to write to the R, G, B channels and draw the first texture using a sprite batch
GraphicsDevice.RenderState.ColorWriteChannels = ColorWriteChannels.Red | ColorWriteChannels.Green | ColorWriteChannels.Blue;
spriteBatch.Draw(bg, new Vector2(0, 0), Color.White);
Set channels to alpha only, and draw the alpha mask
GraphicsDevice.RenderState.ColorWriteChannels = ColorWriteChannels.Alpha;
spriteBatch.Draw(circle, new Vector2(0, 0), Color.White);
you can now restore the render target to the back buffer and draw your texture using alpha blending.
maskedTexture = shadowRenderTarget.GetTexture();
...
Also don't forget to restore the state:
GraphicsDevice.RenderState.ColorWriteChannels = ColorWriteChannels.All;
...

Resources