🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Issues with alpha blending (DirectX 11)

Started by
2 comments, last by _WeirdCat_ 3 years, 1 month ago

Hi, I'm having trouble with alpha blending in my engine. As you can see, the tree infront occludes the tree behind it. Why is this happening? I'm pretty sure this was working before but now this is it how it behaves. This can be fixed by changing the position of the trees but obviously this is not desirable especially with many blended meshes in the scene.

Secondly, meshes that are drawn with alpha blending enabled are not drawn to render targets above 0:

As you can see the two trees are not drawn to the sunray render target, meaning they do not occlude the rays. When I add a non alpha blended mesh to the scene, the rays are occluded as normall:

Here is the relevant code for how I draw alpha blended meshes:

	// normal meshes
	for (int i = 0; i < meshes.size(); i++) {
			// draw mesh

		}
	}


	// alpha meshes
	m_D3D->TurnOnAlphaBlending();
	for (int i = 0; i < blended_meshes.size(); i++) {
			// draw mesh
		}	
	}
	m_D3D->TurnOffAlphaBlending();

Methods for enabling/disabling blending:

void sfD3D::TurnOffAlphaBlending()
{
	float blendFactor[4];


	// Setup the blend factor.
	blendFactor[0] = 0.0f;
	blendFactor[1] = 0.0f;
	blendFactor[2] = 0.0f;
	blendFactor[3] = 0.0f;

	// Turn off the alpha blending.
	m_deviceContext->OMSetBlendState(m_alphaDisableBlendingState, blendFactor, 0xffffffff);

	return;
}
void sfD3D::TurnOnAlphaBlending()
{
	float blendFactor[4];


	// Setup the blend factor.
	blendFactor[0] = 0.0f;
	blendFactor[1] = 0.0f;
	blendFactor[2] = 0.0f;
	blendFactor[3] = 0.0f;

	// Turn on the alpha blending.
	m_deviceContext->OMSetBlendState(m_alphaEnableBlendingState, blendFactor, 0xffffffff);

	return;
}

Blend state description:

blendStateDescription.RenderTarget[0].BlendEnable = TRUE;
		blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
		blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
		blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
		blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
		blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
		blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
		blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f;

Thanks for your help!

Advertisement

Visual Studio has some good graphics debugging integration so you can view individual draw calls and state.

I'd guess you have depth write still enabled, and that the tree in front was drawn first. It wrote the depth values, and then when you draw the 2nd tree it is failing the depth test and the pixels discarded.

Additionally because drawing alpha blended layers (a,b) and (b,a) give different results, you do need to draw alpha blended objects from back to front anyway, so your “alpha meshes” loop should sort them.

Its due the fact tree that is closer is rendered first, to overcome this you can write depth data to a texture leaving there only data that is full opaque so you will be able to discard only fully covered fragments.

Some kind of shadowmapping

This topic is closed to new replies.

Advertisement