While using the 8yr old Deferred Rendering tutorial, tex2D always returns white

Hey all,
This is my first ever post in the great land the monogame forum. Hi! I’ve been a super long time xna/monogame lurker though.

I have recently tried to follow this crazy old tutorial written for XNA 2 about deferred lighting.
Catalinzima Deferred Rendering

I have been able to render out the Gbuffer, with the color, normal, and depth render targets. I’m onto part 2, directional lighting, and I’ve hit a snag. The basic idea is that you send the 3 targets making up the G buffer to the DirectionalLight .fx shader, along with the light details for some directional light. Then you use tex2D to sample the color,normal, and depth targets to figure out what each pixel should look like lit. (I’m also pretty new with shaders in general). Anyway, the shader from the tutorial still compiles fine, but it doesn’t do anything. I just get a sad empty screen.

I took a look, and simplified the pixel shader to run some sanity checks. I figured that I would just make the directionalLight effect act a pass through for the color target, to at least ensure that texture data was coming through correctly. Here is where the snag happened. The tex2D(color_sampler, input.TexCoord) always returns float4(1,1,1,1).

And I don’t know why.
Okay, here is some code to get my point across.

Here is the shader (with my silly sanity check modification)

//direction of the light
float3 lightDirection;
//color of the light 
float3 Color;
//position of the camera, for specular light
float3 cameraPosition;
//this is used to compute the world-position
float4x4 InvertViewProjection;
// diffuse color, and specularIntensity in the alpha channel
texture colorMap;
// normals, and specularPower in the alpha channel
texture normalMap;
texture depthMap;
sampler colorSampler =sampler_state
	Texture = (colorMap);
	AddressU = Wrap;
	AddressV = Wrap;

sampler depthSampler = sampler_state
	Texture = (depthMap);
	AddressU = CLAMP;
	AddressV = CLAMP;
	MagFilter = POINT;
	MinFilter = POINT;
	Mipfilter = POINT;
sampler normalSampler = sampler_state
	Texture = (normalMap);
	AddressU = CLAMP;
	AddressV = CLAMP;
	MagFilter = POINT;
	MinFilter = POINT;
	Mipfilter = POINT;

struct VertexShaderInput
	float3 Position : POSITION0;
    float4 Color : COLOR0;
	float2 TexCoord : TEXCOORD0;
struct VertexShaderOutput
	float4 Position : SV_POSITION;
	float2 TexCoord : TEXCOORD0;
    float4 Color : COLOR0;
float2 halfPixel;
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
	VertexShaderOutput output;
	output.Position = float4(input.Position, 1);
	//align texture coordinates
	output.TexCoord = input.TexCoord - halfPixel;
	output.Color = float4(1, 0, 0, 1);
	return output;

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
	float2 tex = input.TexCoord;

        // here, I am just showing that the tex.xy is actually correct, and trying to set the blue channel to match something 
        // from the sampled colorSampler.
	float4 color = float4(tex.xy, 0, 1);
	color.b = tex2D(colorSampler,tex).r;
	return float4(color.rgb, 1);


technique Technique1
	pass Pass1
#if SM4
		VertexShader = compile vs_4_0_level_9_1 VertexShaderFunction();
		PixelShader = compile ps_4_0_level_9_1 PixelShaderFunction();

#elif SM3

		VertexShader = compile vs_3_0 VertexShaderFunction();
		PixelShader = compile ps_3_0 PixelShaderFunction();

		VertexShader = compile vs_2_0 VertexShaderFunction();
		PixelShader = compile ps_2_0 PixelShaderFunction();



and here is where I’m calling it in C#

            //_device.Textures[1] = _colorRT;

            //DirectionalLightEffect.Parameters["InvertViewProjection"].SetValue(Matrix.Invert(view * projection));

                new Rectangle(0,-1,1,1), Color.Blue);

and finally, here is a screen capture of what I see.
Here are the quadrant labels
topleft - color topright - normal
bottomleft - depth bottomright - output of directional light shader

Any help would be greatly appreciated. Thanks in advance.
Also, hello forums!

edit - here is the code for initializing the render targets

// initialize the deferred RTs
            var bbWidth = device.PresentationParameters.BackBufferWidth;
            var bbHeight = device.PresentationParameters.BackBufferHeight;
            _colorRT = new RenderTarget2D(device, bbWidth, bbHeight, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8); // TODO watch out for depth format, its shifty... 
            _normalRT = new RenderTarget2D(device, bbWidth, bbHeight, false, SurfaceFormat.Color, DepthFormat.None); // TODO watch out for depth format, its shifty... 
            _depthRT = new RenderTarget2D(device, bbWidth, bbHeight, false, SurfaceFormat.HalfSingle, DepthFormat.None); // TODO watch out for depth format, its shifty... 
            _halfPixel = new Vector2(.5f / bbWidth, .5f / bbHeight);

Found a work around. I guess I don’t understand SpriteBatch very well.
Instead of drawing the directional light with the sprite batch, I got a quad renderer, and just rendered a box manually with
GraphicsDevice.DrawIndexedPrimitives or whatever.
That worked.


SpriteBatch sets the drawn texture as the first texture of the effect, maybe that’s your error? Here’s the actual rendering code: https://github.com/mono/MonoGame/blob/develop/MonoGame.Framework/Graphics/SpriteBatcher.cs#L244

Also, SpriteBatch should handle te half pixel offset for you.

That was probably it, yeah. If another system is playing with the shader parameters, then yeah, its all for not.
Thanks for the response!

I did the Same thing this week! Great tutorial really!

The half pixel thing is not relevant any more by the way, that was a dx9 oddity

Here is some links for better lighting models than the standard phong/lambert ones.