Effect help

I’m pulling my hair out trying to find a simple effect.

Basically im rendering shadows to a white rendertarget. The shadows are black with 0 Alpha.

I’m hoping to find an effects file where i can modify all black pixels to have a calculated alpha (passed in by a float)

So if i pass in an alpha value of 0.1f, all black pixels should have 10% alpha.

If anyone could help I would be majorly grateful.

So i also need to invert the colours on the shadowMask (From white to black and black to White, there is only 2 colours on the shadowmask). So far ive got this. The colours are getting inverted, but no matter what i put the alpha value at i’m not getting alpha through.

Also, RGB values, are they simply between 0 and 1?

Thanks

texture shadowMask;
sampler lightSampler = sampler_state { Texture = <shadowMask>; };

float4 PixelShaderFunction(float4 pos : SV_POSITION, float4 color1 : COLOR0, float2 coords: 
TEXCOORD0) : COLOR0
{
    float4 pixel = tex2D(lightSampler, coords);
	if(pixel.r < 0.5) 
{
	pixel.r = 1;
	pixel.b = 1;
	pixel.g = 1;
}
else if (pixel.r > 0.5) 
{
    pixel.r = 0;
	pixel.b = 0;
	pixel.g = 0;
	pixel.a = 1;
}
return pixel;
}

technique Technique1
{
pass Pass1
{
    PixelShader = compile ps_4_0_level_9_1 PixelShaderFunction();
}

}

how did you configure the blendstate? The BlendState is responsible of applying the alpha to the target - and of course the rendertarget should have an alpha channel as well (SurfaceFormat)

yes, you handle color values in 0-1 range in the shader (but in reality it’s byte components in vertexdeclaration)

I have used Transparency on the render target before (I am changing the way i do shadows)

I’m currently using
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);

Any ideas? Thanks for your help

Try BlendState.NonPremultiplied

Okay so i got it to work. I had to make the RGB values for black have a value of 0.5. Giving them straight 0 would not allow any alpha to come through and would be dead black.

texture shadowMask;
sampler lightSampler = sampler_state { Texture = <shadowMask>; };

float4 PixelShaderFunction(float4 pos : SV_POSITION, float4 color1 : COLOR0, float2 coords: 
TEXCOORD0) : COLOR0
{
float4 pixel = tex2D(lightSampler, coords);
if(pixel.r < 0.5) 
{
	pixel.r = 1;
	pixel.b = 1;
	pixel.g = 1;
		
}
else if (pixel.r > 0.5)  
{
    pixel.r = 0.5;
	pixel.b = 0.5;
	pixel.g = 0.5;	
	pixel.a = 0.8;
	
}
return pixel;
}

technique Technique1
{
pass Pass1
{
    PixelShader = compile ps_4_0_level_9_1 PixelShaderFunction();
}
}

I’m a little confused thoguh. I’m not using “pos” or “color1” from the PixelShaderFunction, however as soon as i take the parameters out of the method constructor it does not work.

My other question is, at the moment i need to draw this from one render target to another render target to apply this effect. Is there a way that i can apply this effect to the current render target. Using shadowEffect.CurrentTechnique.Passes[0].Apply(); still requires me to a draw call to another rendertarget.

BlendState.AlphaBlend assumes premultiplied alpha. That means, that every color is expected to be premultiplied by the alpha value. That’s why I sugessted to use BlendState.Nonpremultiplied. Which ises Source.Alpha instead of Source.One etc

If you want to copy a rendertarget to another (or process the contents inbetween) you have to set the source rendertarget as texture, and the target rendertarget as target - you then draw a fullscreen quad (or a fullscreen sprite in SpriteBatch) - this is regularily done for postprocessing effects like blurring the whole screen or fading out etc

Awesome ill try that.

So is there a way of running an effects pass on a rendertarget without drawing it to another target.

So have the effect process the current render target.

no because the output is not deterministic on the GPU (sampling) - you would get weird results, that’s why it’s a limitiation that you cannot set a current rendertarget as texture

1 Like

No worries thanks heaps for your help