我想根据红龙那本书介绍的镜面效果的实例,制作水面反射效果。在其提供的源程序上修改得到的效果是可以的。如图:
目标像素可以与镜面融合。
但我拿到SIMPLESAMPLE里边时,只是将物体翻转渲染。效果如图:
好像没有进行模板检测,只是没有写入深度缓存,也没有融合。是不是模板检测格式没有设置?
镜面代码如下:
//设置模板检测
device->SetRenderState(D3DRS_STENCILENABLE, true);
device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
device->SetRenderState(D3DRS_STENCILREF, 0x1);
device->SetRenderState(D3DRS_STENCILMASK, 0xffffffff);
device->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);
device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
//取消写入深度缓存和后台缓存
device->SetRenderState(D3DRS_ZWRITEENABLE, false);
device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
//渲染镜面
device->SetTransform(D3DTS_WORLD,&g_matGround);
device->SetTexture(0, g_pTexture3);
device->SetStreamSource(0, g_pVB3, 0, sizeof(CUSTOMVERTEX));
device->SetFVF(D3DFVF_SeaWave);
device->DrawPrimitive(D3DPT_TRIANGLESTRIP,0, 2);
//重置深度缓冲
device->SetRenderState( D3DRS_ZWRITEENABLE, true );
//仅绘制与镜面重合的反射物体的像素
device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
//以A平面创建反射矩阵
D3DXPLANE plane(0.0f, 1.0f, 0.0f, 1.4f); //平面A,与xz平面平行,高出1.4
D3DXMATRIX R,W,T;
D3DXMatrixReflect(&R, &plane);
D3DXMatrixTranslation(&T,233,6,110);
W=T*R;
//清除深度缓存,混合反射物体与镜面
device->Clear(0, 0, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
//绘制反射影像物体
device->SetTransform(D3DTS_WORLD, &W);
device->SetMaterial(&TeapotMtrl);
device->SetTexture(0, 0);
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
Teapot->DrawSubset(0);
// 重置渲染状态
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
device->SetRenderState(D3DRS_STENCILENABLE,false);
device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
device->SetRenderState( D3DRS_STENCILENABLE, false);
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);