Jump to content
  • Advertisement
Sign in to follow this  

Blending two images together.

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

Im trying to Subtract a image with blending. I made a image(brick wall) with a alpha channel(black and white image..vines)

so it is one image. Is this right. ?

Here is my code

D3D11_BLEND_DESC myBlend = { 0 };

	myBlend.AlphaToCoverageEnable = false;
	myBlend.ransparentDesc.IndependentBlendEnable = false;

	myBlend.RenderTarget[0].BlendEnable = true;
	myBlend.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
	myBlend.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
	myBlendRenderTarget[0].BlendOp = D3D11_BLEND_OP_SUBTRACT;
	myBlend.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
	myBlendRenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
	myBlend.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	myBlend.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
	HR(md3dDevice->CreateBlendState(&myBlend &BLENDTEST));

The alpha channel is not being subtracted from the image image. It should be a brick wall with vines.

 

What is wrong with my code?

Edited by terryeverlast

Share this post


Link to post
Share on other sites
Advertisement

You want to render a wall and on top of it vines which are masked by the alpha channel ?

Then you need to first render the wall (solid) and alpha-blend (not substract) the vines. Try something like this:

	myBlend.RenderTarget[0].BlendEnable = true;
	myBlend.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
	myBlend.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
	myBlendRenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
	myBlend.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
	myBlendRenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
	myBlend.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	myBlend.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
	HR(md3dDevice->CreateBlendState(&myBlend &BLENDTEST));

Share this post


Link to post
Share on other sites

That blend makes the image transparent. The alpha(vines) is the transparent part.

 

I need something like this in the image.

 

 

2e5tpiv.jpg

 

 

 

One of my question is. Do I load the brick wall with that alpha into one image?

 

I loaded the brick wall as the rgb, and the vines as the alpha channel with the DxTex.exe.

 

My book says this.

 

Suppose that we want to Subtract the source pixels with the destination pixels. To do this, set the source blend factor to D3D11_BLEND_ONE, the destination blend factor to D3D11_BLEND_ONE, and the blend operator to D3D11_BLEND_OP_SUBTRACT.
 

 

 

Share this post


Link to post
Share on other sites

what happens if you load the vines as RGBA instead?

 

I'm using a similar blend state to you, except that all my textures are RGBA and it all works fine...

Share this post


Link to post
Share on other sites

I combined the brick with the vines with the tool "DirectX Texture Tool" and changed the surface format to "Four CC 8-bit DXT5"  and loaded the alpha onto the the texture.

 

This is right?

Share this post


Link to post
Share on other sites

Your problem is, that your vine value is in the alpha channel solely, because you cannot use only the alpha channel as all color components in fixed-function blending.

 

I can think of these solutions:

- Actually put vines into (grayscale) separate texture. Then, render the brick tex in a first pass and the vines in a second one with the same geometry and blendOp=BLEND_OP_REV_SUBTRACT, srcBlend=BLEND_ONE, dstBlend=BLEND_ONE

 

- Do blending in the Pixel Shader instead. There you can extract the alpha channel and subtract it from the other color components. If you have to render the vines in an extra pass, just use BLEND_OP_REV_SUBTRACT and output (a, a, a) in the Pixel shader, where a is the alpha value of the texture.

 

Hope i could help.

Edited by iSmokiieZz

Share this post


Link to post
Share on other sites

I really don't want to use the pixel shader to do this. I want to use the first option.(Multipass texturing)

 D3DX11_TECHNIQUE_DESC techDesc;
	activeTech->GetDesc( &techDesc );
    for(UINT p = 0; p < techDesc.Passes; ++p)
    {
		md3dImmediateContext->IASetVertexBuffers(0, 1, &mBoxVB, &stride, &offset);
		md3dImmediateContext->IASetIndexBuffer(mBoxIB, DXGI_FORMAT_R32_UINT, 0);

				
		// Restore default blend state
		
		// Draw the box.
		world = XMLoadFloat4x4(&mBoxWorld);
		worldInvTranspose = MathHelper::InverseTranspose(world);
		worldViewProj = world*view*proj;

		Effects::BasicFX->SetWorld(world);
		Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
		Effects::BasicFX->SetWorldViewProj(worldViewProj);
		Effects::BasicFX->SetTexTransform(XMMatrixIdentity());
		Effects::BasicFX->SetMaterial(mBoxMat);
		Effects::BasicFX->SetDiffuseMap(mDiffuseMapSRV6);
		
		md3dImmediateContext->OMSetBlendState(TransparentBS, blendFactor, 0xffffffff);
		activeTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);
		Effects::BasicFX->SetDiffuseMap(mDiffuseMapSRV7);
		activeTech->GetPassByIndex(p)->Apply(1, md3dImmediateContext);
		md3dImmediateContext->DrawIndexed(mBoxIndexCount, mBoxIndexOffset, mBoxVertexOffset);
		md3dImmediateContext->OMSetBlendState(0, blendFactor, 0xffffffff);
		
				
    }

	HR(mSwapChain->Present(0, 0));
}

I tried that, but not working

Edited by terryeverlast

Share this post


Link to post
Share on other sites

Well the principle of multipass rendering is that you set some drawing information (blend state, texture maps/DiffuseMap, Transformation), render a geometry (DrawIndexed), set some other draw information and render the geometry again.

You don't really need Effect passes for that. Just set a different texture and blendstate, then render the geometry. Do this twice.

0. Set transformation, VBs and IBs. (Btw: 16Bit / R16 Index Bufers are often enough and save half of the data)

1. Set opaque blend state (BlendEnable=FALSE) and your brick texture

2. DrawIndexed()

3. Set "transparent" BS (srcBlend=ONE, dstBlend=ONE, blendOp=BLEND_OP_REV_SUBTRACT) and your vines texture

4. DrawIndexed()

Share this post


Link to post
Share on other sites

Got a change but not the exact thing I need

 

here is what I got

 

1073laq.jpg

 

I see the alpha with some brown from the bricks..but where is the bricks?

 

The image should be like

 

2e5tpiv.jpg

// Draw the box.
		world = XMLoadFloat4x4(&mBoxWorld);
		worldInvTranspose = MathHelper::InverseTranspose(world);
		worldViewProj = world*view*proj;

		Effects::BasicFX->SetWorld(world);
		Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
		Effects::BasicFX->SetWorldViewProj(worldViewProj);
		Effects::BasicFX->SetTexTransform(XMMatrixIdentity());
		Effects::BasicFX->SetMaterial(mBoxMat);
		Effects::BasicFX->SetDiffuseMap(mDiffuseMapSRV6);
		
		md3dImmediateContext->OMSetBlendState(TransparentBS, blendFactor, 0xffffffff);
		
		md3dImmediateContext->DrawIndexed(mBoxIndexCount, mBoxIndexOffset, mBoxVertexOffset);
		Effects::BasicFX->SetDiffuseMap(mDiffuseMapSRV7);
		md3dImmediateContext->OMSetBlendState(TransparentBS2, blendFactor, 0xffffffff);
		activeTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);
		md3dImmediateContext->DrawIndexed(mBoxIndexCount, mBoxIndexOffset, mBoxVertexOffset);

here is my blend code

D3D11_BLEND_DESC transparentDesc = { 0 };
	transparentDesc.AlphaToCoverageEnable = false;
	transparentDesc.IndependentBlendEnable = false;

	transparentDesc.RenderTarget[0].BlendEnable = false;
	transparentDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
	transparentDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
	transparentDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_SUBTRACT;
	transparentDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
	transparentDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
	transparentDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	transparentDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
	HR(md3dDevice->CreateBlendState(&transparentDesc, &TransparentBS));


	


	transparentDesc.RenderTarget[1].BlendEnable = true;
	transparentDesc.RenderTarget[1].SrcBlend = D3D11_BLEND_ONE;
	transparentDesc.RenderTarget[1].DestBlend = D3D11_BLEND_ONE;
	transparentDesc.RenderTarget[1].BlendOp = D3D11_BLEND_OP_SUBTRACT;
	transparentDesc.RenderTarget[1].SrcBlendAlpha = D3D11_BLEND_ONE;
	transparentDesc.RenderTarget[1].DestBlendAlpha = D3D11_BLEND_ZERO;
	transparentDesc.RenderTarget[1].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	transparentDesc.RenderTarget[1].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
	HR(md3dDevice->CreateBlendState(&transparentDesc, &TransparentBS2));
Edited by terryeverlast

Share this post


Link to post
Share on other sites

You have to create separate Blend states, not use the RenderTarget[] array in the blend desc. Also your blend desc is wrong for the second pass. See my last post. Your have to render the vines with BlendOp=BLEND_OP_REV_SUBTRACT (which is different from BLEND_OP_SUBTRACT), or render the vines first, then the bricks with BLEND_OP_SUBTRACT.

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!