HDR + CubeMap,HDR上一节讲过,这里是动态生成CubeMap。
载入资源的都省略了,基本都没有什么障碍了,不过这个例子的载入部分封装的不错,特别是FX部分。
OnFrameRender函数内的主体如下,可以看到主要的渲染函数分别在RenderSceneIntoCubeMap和RenderScene中。下面将阅读这两个函数的代码。
RenderSceneIntoCubeMap( pd3dDevice, fTime );
//省略
// Begin the scene
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{
RenderScene( pd3dDevice, g_Camera.GetViewMatrix(), g_Camera.GetProjMatrix(), g_pTech, true, fTime );
//省略
}
首先是这个函数~
//--------------------------------------------------------------------------------------
// Set up the cube map by rendering the scene into it.
//--------------------------------------------------------------------------------------
void RenderSceneIntoCubeMap( IDirect3DDevice9* pd3dDevice, double fTime )
LPDIRECT3DSURFACE9 pRTOld = NULL;
V( pd3dDevice->GetRenderTarget( 0, &pRTOld ) );
LPDIRECT3DSURFACE9 pDSOld = NULL;
if( SUCCEEDED( pd3dDevice->GetDepthStencilSurface( &pDSOld ) ) )
{
// If the device has a depth-stencil buffer, use
// the depth stencil buffer created for the cube textures.
V( pd3dDevice->SetDepthStencilSurface( g_pDepthCube ) );
}
要注意将原来的渲染对象保存,并且设置DS缓存。接下来就是分别渲染6个面了。
for( int nCube = 0; nCube < g_nNumCubes; ++nCube )
for( int nFace = 0; nFace < 6; ++nFace )
{
LPDIRECT3DSURFACE9 pSurf;
V( g_apCubeMap[nCube]->GetCubeMapSurface( ( D3DCUBEMAP_FACES )nFace, 0, &pSurf ) );
V( pd3dDevice->SetRenderTarget( 0, pSurf ) );
SAFE_RELEASE( pSurf );
D3DXMATRIXA16 mView = DXUTGetCubeMapViewMatrix( nFace );
D3DXMatrixMultiply( &mView, &mViewDir, &mView );
//省略
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{
RenderScene( pd3dDevice, &mView, &mProj, &g_pTech[nCube], false, fTime );
// End the scene.
pd3dDevice->EndScene();
}
}
代码出乎意料地简单,当然了,因为其中再一次调用了RenderScene来渲染场景。渲染完成后还有恢复原来的RT,这里就不列出代码了。
接下来看看RenderScene。这个函数用来渲染场景,主要有两种情况,是否渲染中间的物体。若渲染目标为CubeMap,则不渲染。。。
if( bRenderEnvMappedMesh )
{
V( g_pEffect->SetTechnique( pTechGroup->hRenderEnvMap ) );
// Combine the offset and scaling transformation with
// rotation from the camera to form the final
// world transformation matrix.
D3DXMatrixMultiply( &mWorldView, &g_EnvMesh[g_nCurrMesh].m_mWorld, g_Camera.GetWorldMatrix() );
D3DXMatrixMultiply( &mWorldView, &mWorldView, pmView );
V( g_pEffect->SetMatrix( g_hWorldView, &mWorldView ) );
V( g_pEffect->Begin( &cPass, 0 ) );
for( int i = 0; i < g_nNumCubes; ++i )
V( g_pEffect->SetTexture( g_ahtxCubeMap[i], g_apCubeMap[i] ) );
for( p = 0; p < cPass; ++p )
{
V( g_pEffect->BeginPass( p ) );
LPD3DXMESH pMesh = g_EnvMesh[g_nCurrMesh].m_Mesh.GetMesh();
for( DWORD i = 0; i < g_EnvMesh[g_nCurrMesh].m_Mesh.m_dwNumMaterials; ++i )
V( pMesh->DrawSubset( i ) );
V( g_pEffect->EndPass() );
}
V( g_pEffect->End() );
}
基本上每一部分代码都如上面的流程,计算设置变量,设置效果框架,开始PASS渲染。
有一个奇怪的地方,就是这里的HDR并没有真的使用HDR常用算法去ToneMapping和Bloom,这里只是用高强度光照和浮点纹理来渲染场景,这样光照就能够不限于0-1,使得在光照处理后,像素间的亮度差仍然能够很好地保持。因此可以说这里的HDR其实只是真的指HDR。。。