D3D中镜面反射效果实现

D3D中镜面反射效果实现

1:地板透明化注:透明物体最后画出
    g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE );
    g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA );
    g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);

2:画出反射对象注:一份顶点数据通过矩阵变换画出反射对象
 D3DXMATRIXA16 tmp;
 D3DXMatrixScaling(&tmp,1,-1,1);//通过放缩矩阵来实现倒影(或D3DXMatrixReflect(&tmp,&plane);)

3:Stencil Buffer 模板缓存启用Stencil Buffer保证转到地板下面时看不到实际存在的反射物体以免漏馅
镜面既要最先画又要最后画,那么画两遍,最先画时设置Aphha混合如下不改变后台缓存只是在模板缓存中标记镜面区域为1.
最先画地板时:
 //设置模板缓存
 g_pd3dDevice->SetRenderState(D3DRS_STENCILENABLE,true);
 g_pd3dDevice->SetRenderState(D3DRS_STENCILFUNC,D3DCMP_ALWAYS);
 g_pd3dDevice->SetRenderState(D3DRS_STENCILREF,0x1);
 g_pd3dDevice->SetRenderState(D3DRS_STENCILMASK,0xffffffff);
 g_pd3dDevice->SetRenderState(D3DRS_STENCILWRITEMASK,0xffffffff);
 g_pd3dDevice->SetRenderState(D3DRS_STENCILZFAIL,D3DSTENCILOP_KEEP);
 g_pd3dDevice->SetRenderState(D3DRS_STENCILFAIL,D3DSTENCILOP_KEEP);
 g_pd3dDevice->SetRenderState(D3DRS_STENCILPASS,D3DSTENCILOP_REPLACE);
 

 //绘制地板镜面
 g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
 g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
 g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ZERO);
 g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE);
绘制物体影像时启用模板缓存并对其函数状态进行设置:
     g_pd3dDevice->SetRenderState(D3DRS_STENCILENABLE,true);
     g_pd3dDevice->SetRenderState( D3DRS_STENCILFUNC,D3DCMP_EQUAL);
最后在渲染时照常:
    g_pd3dDevice->SetStreamSource( 0, obj.g_pVB, 0, sizeof(CUSTOMVERTEX) );
    g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
    g_pd3dDevice->SetIndices( obj.g_pIB );
    g_pd3dDevice->SetTexture( 0, g_pTexture[obj.textureID] ); //设置纹理
    g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,obj.numOfVertex,0,obj.numOfFace);
其中 g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,obj.numOfVertex,0,obj.numOfFace);这句话根据模板缓存的设置及开启情况,写入后台缓冲区的同时写入模板缓存。或在与模板缓存中数据比较后决定是否要往后台缓冲区中写。

你可能感兴趣的:(D3D中镜面反射效果实现)