Jump to content
  • Advertisement
Sign in to follow this  
brekehan

AlphaBlendAdd

This topic is 3490 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

My alpha blending is not correct. I am not sure what to use. Am I doing my alpha blend state incorrectly? My Result: 1 of 3 the flare images they privided (it has no alpha channel): What I think the problem is:
BlendState SrcAlphaAdd
{
   BlendEnable[0]           = TRUE;
   SrcBlend                 = SRC_ALPHA;
   DestBlend                = ONE;
   BlendOp                  = ADD;
   SrcBlendAlpha            = ONE;
   DestBlendAlpha           = ONE;
   BlendOpAlpha             = ADD;
   RenderTargetWriteMask[0] = 0x0F;
};

Thier code:
 foreach (Flare flare in flares)
            {
                // Compute the position of this flare sprite.
                Vector2 flarePosition = lightPosition + flareVector * flare.Position;

                // Set the flare alpha based on the previous occlusion query result.
                Vector4 flareColor = flare.Color.ToVector4();

                flareColor.W *= occlusionAlpha;

                // Center the sprite texture.
                Vector2 flareOrigin = new Vector2(flare.Texture.Width,
                                                  flare.Texture.Height) / 2;

                // Draw the flare.
                spriteBatch.Draw(flare.Texture, flarePosition, null,
                                 new Color(flareColor), 1, flareOrigin,
                                 flare.Scale, SpriteEffects.None, 0);
            }

            spriteBatch.End();

My code:
//--------------------------------------------------------------------------------------
// File: LensFlare.fx
//
//--------------------------------------------------------------------------------------

#include "EffectPool.fxh"

matrix world                 : World;
matrix worldInverseTranspose : WorldInverseTranspose;

//-------------------
// Diffuse Variables
//
// Diffuse Color can be a single color or sampled from a texture

float4    diffuseColor    = float4(1.0f, 1.0f, 1.0f, 1.0f);
Texture2D diffuseTexture;

SamplerState samplerLinear
{
   Filter = MIN_MAG_MIP_LINEAR;
   AddressU = Wrap;
   AddressV = Wrap;
};

//////// CONNECTOR DATA STRUCTURES ///////////

struct VS_IN_OCCLUSION
{
   float4 position : POSITION;
};

struct PS_IN_OCCLUSION
{
   float4 position : SV_POSITION;
};

struct VS_IN_TINT
{
   float4 position : POSITION;
   float2 texCoord : TEXCOORD;
};

struct PS_IN_TINT
{
   float4 position : SV_POSITION;
   float2 texCoord : TEXCOORD;
};

//////////// STATES ///////////////

BlendState SrcAlphaBlend
{
   BlendEnable[0]           = TRUE;
   SrcBlend                 = SRC_ALPHA;
   DestBlend                = INV_SRC_ALPHA;
   BlendOp                  = ADD;
   SrcBlendAlpha            = ONE;
   DestBlendAlpha           = ONE;
   BlendOpAlpha             = ADD;
   RenderTargetWriteMask[0] = 0x0F;
};

BlendState SrcAlphaAdd
{
   BlendEnable[0]           = TRUE;
   SrcBlend                 = SRC_ALPHA;
   DestBlend                = ONE;
   BlendOp                  = ADD;
   SrcBlendAlpha            = ONE;
   DestBlendAlpha           = ONE;
   BlendOpAlpha             = ADD;
   RenderTargetWriteMask[0] = 0x0F;
};

BlendState OcclusionAlphaBlend
{
   BlendEnable[0]           = FALSE;
   RenderTargetWriteMask[0] = 0x00;      // Write no colors
};

DepthStencilState OcclusionDepthStencil
{
   DepthEnable              = TRUE;
   DepthWriteMask           = ZERO;
   DepthFunc                = Less;
   StencilEnable            = FALSE;
};

//--------------------------------------------------------------------------------------
// Vertex Shaders
//--------------------------------------------------------------------------------------

//--------------------------------------------------------------------------------------
// Transforms positions
// 
PS_IN_OCCLUSION VS_Occlusion( VS_IN_OCCLUSION input )
{
   PS_IN_OCCLUSION output = (PS_IN_OCCLUSION)0;
   
   // Transform the incoming model-space position to projection space
   matrix worldViewProjection = mul( mul(world, view), projection);
   output.position            = mul( input.position, worldViewProjection);

   return output;
}

//--------------------------------------------------------------------------------------
// Transforms positions and copies texture coordinates
//
PS_IN_TINT VS_Tint( VS_IN_TINT input )
{
   PS_IN_TINT output = (PS_IN_TINT)0;
   
   // Transform the incoming model-space position to projection space
   matrix worldViewProjection = mul( mul(world, view), projection);
   output.position            = mul( input.position, worldViewProjection);
   
   // Copy the texture coordinate
   output.texCoord = input.texCoord;

   return output;
}

//--------------------------------------------------------------------------------------
// Pixel Shaders
//--------------------------------------------------------------------------------------

//--------------------------------------------------------------------------------------
// Colors the object with the diffuse color
//
float4 PS_Occlusion( PS_IN_OCCLUSION input ) : SV_Target
{  
   return diffuseColor;
}

//--------------------------------------------------------------------------------------
// Colors the object with the diffuse color multiplied by the texture color
//
float4 PS_Tint( PS_IN_TINT input ) : SV_Target
{  
   return diffuseColor * diffuseTexture.Sample(samplerLinear, input.texCoord);
}

//--------------------------------------------------------------------------------------
// Techniques
//--------------------------------------------------------------------------------------

//--------------------------------------------------------------------------------------
//
//
technique10 OcclusionQuery
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS_Occlusion() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS_Occlusion() ) );
        
        SetBlendState( OcclusionAlphaBlend, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF);
        SetDepthStencilState( DefaultDepthStencil, 0);
    }
}

//--------------------------------------------------------------------------------------
//
//
technique10 RenderGlow
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS_Tint() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS_Tint() ) );
        
        SetBlendState( SrcAlphaBlend, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF);
        SetDepthStencilState( DefaultDepthStencil, 0);
    }
}

//--------------------------------------------------------------------------------------
// Renders an object at 100% opacity, with no lights or shadows
//
technique10 RenderFlare
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS_Tint() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS_Tint() ) );
        
        SetBlendState( SrcAlphaAdd, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF);
        SetDepthStencilState( DefaultDepthStencil, 0);
    }
}

   D3DXVECTOR2 flareVector = screenCenter - lightPosition;
   
   // Bind the input layout
   m_device.IASetInputLayout(m_flareInputLayout);
   m_device.IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);

   // Bind the vertex buffers
   ID3D10Buffer * buffers[2] = {m_positionBuffer->GetD3DBuffer(), 
                                m_texCoordBuffer->GetD3DBuffer()};
   
   UINT strides[2] = {GetStride(m_positionBuffer->GetContentType()),
                      GetStride(m_texCoordBuffer->GetContentType())};
   
   UINT offsets[2] = {0, 
                      0};
   
   m_device.IASetVertexBuffers(0,
                               2,
                               buffers, 
                               strides, 
                               offsets);

   for( std::vector<Flare>::iterator it = m_flares.begin(); it != m_flares.end(); ++it)
   {
      // Set the world matrix and material
      D3DXMATRIX matScale;
      D3DXMATRIX matTranslation;
      D3DXMATRIX world;

      D3DXVECTOR2 flarePosition = lightPosition + flareVector * it->m_position;
      D3DXMatrixScaling(&matScale, it->m_scale, it->m_scale, 1.0f);
      D3DXMatrixTranslation(&matTranslation, flarePosition.x, flarePosition.y, 0.0f);
      D3DXMatrixMultiply(&world, &matScale, &matTranslation);

      D3DXCOLOR flareColor = it->m_color;
      flareColor.a = m_occlusionAlpha; 
      m_flareMaterial->SetFloat4("diffuseColor", static_cast<D3DXVECTOR4>(flareColor));
      m_flareMaterial->SetTextureName("diffuseTexture", it->m_textureName);
      
      try
      {
         m_effect->SetWorldMatrix(world);
         m_effect->SetMaterial(*m_flareMaterial);
      }
      catch(BaseException & e)
      {
         throw e;
      }

      // Apply the pass
      m_flarePass->Apply();

      // Draw the flare
      m_device.Draw(4, 0);
   }

Share this post


Link to post
Share on other sites
Advertisement
Blending is draw order dependent.

Your blending code and state configuration seems fine, note that one flare (I assume it is a flare!) in the middle appears to be blended correctly and the rest have errors.

Your code references:

SetDepthStencilState( DefaultDepthStencil, 0);

What is DefaultDepthStencil??

The common way to avoid this for particle systems is to enable Z-Test but disable Z-Write. Like your occlusion d/s state I think. Have a go with that configuration instead.


hth
Jack

Share this post


Link to post
Share on other sites
Quote:
Original post by jollyjeffers
Blending is draw order dependent.

Your blending code and state configuration seems fine, note that one flare (I assume it is a flare!) in the middle appears to be blended correctly and the rest have errors.

Your code references:

SetDepthStencilState( DefaultDepthStencil, 0);

What is DefaultDepthStencil??

The common way to avoid this for particle systems is to enable Z-Test but disable Z-Write. Like your occlusion d/s state I think. Have a go with that configuration instead.


hth
Jack


My default depth state is in my effect pool. It just uses what the docs told me was the default. I put it there to reset state in case other effects had changed the state. This is something I assume I have to do.


shared DepthStencilState DefaultDepthStencil
{
DepthEnable = TRUE;
DepthWriteMask = All;
DepthFunc = Less;
StencilEnable = FALSE;
StencilReadMask = 0xFF; // DEFAULT_STENCIL_READ_MASK
StencilWriteMask = 0xFF; // DEFAULT_STENCIL_WRITE_MASK
FrontFaceStencilFail = Keep;
FrontFaceStencilDepthFail = Keep;
FrontFaceStencilPass = Keep;
FrontFaceStencilFunc = Always;
BackFaceStencilFail = Keep;
BackFaceStencilDepthFail = Keep;
BackFaceStencilPass = Keep;
BackFaceStencilFunc = Always;
};





The one in the middle is glow. It is rendered with regular alpha blending and default depth state. However, the glow texture file they provided doesn't have any black like the flare files do. The glow, when I open it is photoshop, is just a white splotch on a transparent background. The glow file doesn't have an alpha channel in photoshop, but I don't know what it does when something is on a transparent background and there is no alpha channel...I have no idea what the actual color value photoshop writes for transparent, without an alpha channel, is.

I tried again, using the other depth state as you suggested and got this result:


The depth state got rid of the black outline, but I don't know why they are showing up as really thick white circles instead of somewhat thin, colored ones.

Here are all thier image files for reference:

glow


flare 1


flare 2


flare 3


Here is a link to what the effect is supposed to look like.

Share this post


Link to post
Share on other sites
Yay! I finally got it.
Ends up, my biggest problem was the diffuseColor. As I was translating XNA to DX10 I had cut and pasted the color values, which were UINTs. Well, D3DXCOLOR is 4 floats. So they were 255 times too large.

Here is the result:


Now I wonder if there is a way to make it look more star like. Do you guys think that looks like a star or should some of the image files be recreated?

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!