Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I wanted to try rendering to multiple render targets as a first step to deferred shading, but I'm getting somewhat peculiar behavior where the contents of all render targets are the same as the first one.

So far all the render targets have the same format.

The relevant snippets from the shaders are:

//geometry rendering
struct PS_OUT {
    float4 diff : SV_TARGET0;
    float4 norm : SV_TARGET1;
    float4 spec : SV_TARGET2;
    float4 uv   : SV_TARGET3;
};

PS_OUT PS(PS_IN input)
{
    PS_OUT output;
    output.diff = mytexture.Sample(mysampler, input.uv);
    output.norm = input.normal;
    output.spec = float4(input.pos.xyz, 1);
    output.uv = float4(input.uv, 0, 1);
    return output;
}


//"compositing" with fullscreen quad
Texture2D diff;
Texture2D norm;
Texture2D spec;
Texture2D uv;
SamplerState mysampler;


PS_IN VS(VS_IN input)
{
    PS_IN output ;
    output.pos = float4(input.pos,1);
    output.uv = float4(input.uv, 1, 1);
    return output;
}

float4 PS(PS_IN input) : SV_TARGET
{
    float4 diffuse = diff.Sample(mysampler, input.uv.xy);
    float4 normal = norm.Sample(mysampler, input.uv.xy);
    float4 specular = spec.Sample(mysampler, input.uv.xy);
    float4 uvw = uv.Sample(mysampler, input.uv.xy);

    return normal;
}

Sorry for the long post.

Now, the weird part is, if I return any of the sampled colors alone, like for example the normal, the first G-Buffer "channel" gets drawn to the screen instead. (Even if the normal channel is the only one I sample).

However, if I return this instead: 0.0001*diffuse + 1.0*normal + 0.0001*specular + 0.0001*uvw then it does return the actual normal channel.

This 0.000*diffuse + 1.0*normal + 0.000*specular + 0.000*uvw however results in just the diffuse being drawn again.

There are no Info or Warning or Error messages from the debug layer, turning the debug layer off doesn't change anything either.

Could the HLSL compiler possibly be optimizing the Sample calls away since the result is not used, and then removing the texture objects alltogether since they are not sampled from?

PS, if you think seeing how I create and assign the render targets etc will help, I will add it. I just didn't want to make the post any longer.

share|improve this question
add comment

1 Answer

up vote 3 down vote accepted

Could the HLSL compiler possibly be optimizing the Sample calls away since the result is not used, and then removing the texture objects alltogether since they are not sampled from?

Yes, this is exactly what it will do. Shader compilers are very aggressive about optimizing away unused code, parameters, and objects.

If you're binding the textures by index in your C++ code (e.g. diffuse to texture 0, normal to texture 1, etc.) that would explain this behavior. When diff is not used, the shader compiler will likely assign norm to texture 0.

There are two ways to fix this. You could provide explicit bind points (registers) in your HLSL, like:

Texture2D diff : register(t0);
Texture2D norm : register(t1);
Texture2D spec : register(t2);
Texture2D uv : register(t3);

This tells the compiler to always assign norm to texture 1, even if diff is unused, for example.

Or, you could use the D3D11 shader reflection API (or the Effects 11 API, if you're using it) to look up the shader parameters by name; then you can find out which bind point the compiler assigned to each texture parameter, and bind the correct texture to that register.

share|improve this answer
    
Yes, I have an array of ID3D11ShaderResourceView* gbuffer_rv[4] that I bind with PSSetShaderResources(0, 4, gbuffer_rv). Specifying the registers in the shader seems to be the easier, quicker fix for now. Thank you! –  melak47 May 16 '12 at 19:07
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.