先上图

1,初始化时,创建混合状态
D3D10_BLEND_DESC blendDesc = { 0 };
blendDesc.AlphaToCoverageEnable = false;
blendDesc.BlendEnable[0] = true;
blendDesc.SrcBlend = D3D10_BLEND_SRC_ALPHA;
blendDesc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
blendDesc.BlendOp = D3D10_BLEND_OP_ADD;
blendDesc.SrcBlendAlpha = D3D10_BLEND_ONE;
blendDesc.DestBlendAlpha = D3D10_BLEND_ZERO;
blendDesc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
blendDesc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
md3dDevice->CreateBlendState(&blendDesc, &mTransparentBS);
2,渲染时绑定到管线
mWVP = mWavesWorld * mView * mProj;
mfxWVPVar->SetMatrix((float*)&mWVP);
mfxWorldVar->SetMatrix((float*)&mWaves);
mfxTexMtxVar->SetMatrix((float*)&waterTexMtx);
mfxDiffuseMapVar->SetResource(mWaterMapRV);
mfxSpecMapVar->SetResource(mDefaultSpecMapRV);
pass->Apply(0);
md3dDevice->OMSetBlendState(mTransparentBS, blendFactors, 0xffffffff);
mWaves.draw();
3,在shader中,进行alpha混合,(这里指rgb的混合,不包含alpha值的混合)
ps..
float alpha = gDiffuseMap.Sample(gTriLinearSam, pIn.texC0 ).a;
clip(alpha - 0.25f);
....
return float4(litColor, alpha);
4,之所以用到了tex0和tex1,是因为在c++程序中,纹理扩展了,但是alpha值不要扩展(否则不能保持alpha通道与水体深度之间的对应关系)
在shder中,
vOut.texC0 = vIn.texC;
vOut.texC1 = mul(float4(vIn.texC, 0.0f, 1.0f), gTexMtx);
在c++中
D3DXMATRIX S;
D3DXMatrixScaling(&S, 5.0f, 5.0f, 1.0f);
D3DXMATRIX landTexMtx = S;
mfxTexMtxVar = mFX->GetVariableByName("gTexMtx")->AsMatrix();
mfxTexMtxVar->SetMatrix((float*)&landTexMtx);
5,裁剪
函数clip(x)只能在Ps中使用,意思是x<0的像素都要被干掉
clip(alpha - 0.25f);
也就是alpha<0.25的像素都不处理
本文详细介绍了在DirectX中实现透明效果的全过程,包括混合状态的初始化、渲染时的管线绑定、Shader中的alpha混合处理、纹理扩展技巧以及裁剪操作。通过具体的代码示例,展示了如何设置D3D10_BLEND_DESC、应用纹理变换矩阵和资源,以及在Pixel Shader中进行alpha裁剪。
929

被折叠的 条评论
为什么被折叠?



