I recently implemented a prelighting renderer for my XNA voxel engine, but there is now a weird alpha blending glitch. When I render to the light map, I set the graphics device's blend state to additive (though in the pixel shaders for each light I output an opaque color). When I finally render the world, I set the device's blend state to opaque, I only deal with the RGB components of colors in the shaders, and I again output an opaque color. However, the light map and the final rendering both somehow have transparency.
Edit: I believe the problem with the final rendering is caused by the light map's transparency issues. If a pixel appears to be semi-transparent in the light map, then it will appear as so in the final rendering because of how the final color is calculated.
Here is a picture of the rendered world (there is a blue directional light and a red point light at the player's position):
Here is a picture of the light map (different seed, but you get the idea):
Here is my directional light pixel shader (the point light one is similar, but [obviously] with point light calculations):
float4 PSFunc( VSOutput input ) : COLOR0
{
// extract information
float2 coords = GetTexCoords( input.LPosition );
float4 normal = ( tex2D( normalSampler, coords ) - 0.5 ) * 2.0;
// calculate the lighting value
float3 lighting = clamp( -dot( normalize( lightDirection ), normal.xyz ), 0.0, 1.0 ) * lightColor;
return float4( lighting, 1.0 );
}
Finally, here is my pixel shader that combines texture and lighting values:
float4 PSFunc( VSOutput input ) : COLOR0
{
// extract lighting info (TPosition is the world position in the TEXCOORD0 channel)
float2 coords = ProjectToScreen( input.TPosition ) + GetHalfPixel();
float3 light = tex2D( lightSampler, coords );
light += ambientColor; // ambientColor is a float3
// calculate final color
float3 tex = tex2D( spriteSampler, input.UV ).rgb;
return float4( tex * diffuseColor * light, 1.0 );
}
Note: I do use the sprite batch to render the text, but I have a graphics state class that allows me to push and pop states (rasterizer, blend, depth-stencil, etc.), so I use that to preserve states when drawing with the sprite batch.