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 have set up an 'Order Independent Transparency' method for drawing my transparent objects.

The algorithm can be simplified as follows:

DrawOpaqueObjects() DrawTransparentObjects()

Drawing the transparent objects uses the following render target setup:

        colourAccumulation = new RenderTarget2D(
            game.GraphicsDevice,
            game.GraphicsDevice.PresentationParameters.BackBufferWidth,
            game.GraphicsDevice.PresentationParameters.BackBufferHeight,
            false,
            SurfaceFormat.Rgba64,           // 16 bit floating point texture (required for alpha blending caculations)
            DepthFormat.None
            );

        depthComplexity = new RenderTarget2D(
            game.GraphicsDevice,
            game.GraphicsDevice.PresentationParameters.BackBufferWidth,
            game.GraphicsDevice.PresentationParameters.BackBufferHeight,
            false,
            SurfaceFormat.Rgba64,           // 16 bit floating point texture (required for alpha blending caculations)
            DepthFormat.None
            );

The transparent objects are combined with another render target texture that all the opaque objects are drawn to before hand:

        scene = new RenderTarget2D(
            graphicsDevice,
            graphicsDevice.PresentationParameters.BackBufferWidth,
            graphicsDevice.PresentationParameters.BackBufferHeight,
            false,
            SurfaceFormat.Color,
            DepthFormat.Depth16,        // Requires a depth format for objects to be drawn correctly (e.g. wireframe model surrounding model)
            0,
            RenderTargetUsage.PreserveContents
            );

They are combined as follows:

PixelShaderOutput PixelShaderFunction(VertexShaderOutput input)
{
PixelShaderOutput output;

// Background colour 'Cbg'
float4 BackgroundColour = tex2D(BackgroundSampler, input.TextureCoordinates.xy);

float4 SumColour = tex2D(Texture0Sampler, input.TextureCoordinates.xy);

// [Depth complexity]
// • Each time a pixel is written by the transparent object it adds 1 to the value [float4(1, 1, 1, 1)]
// • This is why a render target with 16-bits per channel is required (SurfaceFormat.Rgba64)
float n = tex2D(Texture1Sampler, input.TextureCoordinates.xy).r;

// If no transparent pixel has been drawn at this location, return the background colour
if (n == 0.0)   
{
    output.Colour = BackgroundColour;

    return output;
}

SumColour = Upscale(SumColour);
n = Upscale(n);

// Average colour 'C'
float3 AvgColour = SumColour.rgb / SumColour.a;

// Average alpha based on depth complexity 'A'
float AvgAlpha = SumColour.a / n;

// T = (1 - A) ^ n
float T = pow(abs(1.0 - AvgAlpha), n);

// [Weighted Average Formula]
// • Cdst = (C * A * (1 - (1 - A)^n) / A) + Cbg * (1 - A)^n
// • Cdst = (C * A * (1 - T) / A) + Cbg * T
// • Cdst = C * (1 - T) + Cbg * T;
output.Colour.rgb = AvgColour * (1 - T); 
output.Colour.rgb += BackgroundColour.rgb * T;
output.Colour.a = 1;

return output;
}

The problem is that all transparent objects are never obscured by the opaque objects drawn before hand as denoted by the yellow circle in the following picture:

Transparent Depth Problem

The depth test has to be disabled for the transparent objects but it is enabled for the opaque.

Why is this incorrect effect occurring?

share|improve this question

1 Answer 1

up vote 2 down vote accepted

You want depth testing enabled (so that opaque objects block transparent objects), but you want depth write disabled (so that transparent objects don't update the depth buffer, and don't occlude each other).

depthState.DepthBufferEnable = true; 
depthState.DepthBufferWriteEnable = false; 
share|improve this answer
    
That's the same as 'DepthStencilState.DepthRead'. I have tried that before but it makes no difference when combining the scene render target with the transparent objects render target. –  user1423893 Jul 21 '12 at 15:13

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.