• Advertisement
Sign in to follow this  

Alpha blend mystery

This topic is 966 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

 

So I am having a little trouble alpha blending two ground textures in order to "paint" alpha values in my homegrown engine level editor. I am using hlsl and direct3d9. The problem is that the alpha values seem to be taking BUT are only visible when the camera is very close to the texture in game. I have included two pictures that show the issue.

 

This is my pertinent hlsl code

//LWSurface layers
int layers;
texture layerOne;
texture layerTwo;

sampler LayerOneTexture =
sampler_state
{
    Texture = <layerOne>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

sampler LayerTwoTexture =
sampler_state
{
    Texture = <layerTwo>;
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

void psLWSurface(float4 iNorm : TEXCOORD0,
                 float2 iUV : TEXCOORD1,
                 float2 iDepth : TEXCOORD2,
                 out float4 mapColor : COLOR0,
                 out float4 mapNorm : COLOR1,
                 out float4 mapDepth : COLOR2,
                 out float4 mapIdentity: COLOR3)
{    

    float4 layerOne = tex2D(LayerOneTexture, iUV);

    if(layers == 1)
    {
        mapColor = layerOne;
    }
    else if(layers == 2)
    {        
        //Sample second layer
        float4 layerTwo = tex2D(LayerTwoTexture, iUV);

        //Alpha blend the two layers
        float4 blendResult;

        blendResult.a = layerTwo.a + (1.0f - layerTwo.a) * layerOne.a;
        blendResult.rgb = (1.0f / blendResult.a) * (layerTwo.a * layerTwo.rgb + (1.0f - layerTwo.a) * layerOne.a * layerOne.rgb);    

        mapColor = blendResult;
    }

    //Normal map
    //Transform to range [0, 1] due to X8R8G8B8 texture format. Only holds unsigned data.
    mapNorm.xyz = 0.5f * (normalize(iNorm) + 1.0f);
    mapNorm.w = 1.0f;

    //Depth map
    mapDepth.xyz = (iDepth.x / iDepth.y);
    mapDepth.w = 1.0f;

    mapIdentity.xyzw = dsObjectIdentity;

}

technique LWSurface
{
    pass p0
    {
        VertexShader = compile vs_3_0 vsFill();
        PixelShader = compile ps_3_0 psLWSurface();
    }
}

And in the engine I have hardcoded a test value for the alpha of the second texture just until I can get this probem solved

            D3DLOCKED_RECT textureData;
            _layers[layer].layer->LockRect(0, &textureData, 0, 0);

            unsigned* bytePointer = (unsigned*)textureData.pBits;

            for (int y = 0; y < desc.Height; y++)
            {
                for (int x = 0; x < desc.Width; x++)
                {
                    //Alpha channel
                    ((byte*)&bytePointer[x])[3] = 50;
                }

                // 32bpp == 4 bytes and pitch may not be == width * 4
                bytePointer += textureData.Pitch >> 2;
            }

            _layers[layer].layer->UnlockRect(0);

The textures are Dynamic and 32byte A8R8G8B8.

 

Thank you for taking the time.

 

 

 

Share this post


Link to post
Share on other sites
Advertisement

I think Jihodg is on the right track. Your code that's hardcoding a test value for texture two's alpha is only modifying the top mip.

 

If the lower mips are already generated, then they will still be opaque. Try regenerating the lower mips after hardcoding that transparency, or modify your code so that you iterate through all the mips and hardcode an alpha value.

Share this post


Link to post
Share on other sites

Well after running the program through pix and looking at the mip chain, both of you are correct. Thank you for the help.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement