• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            環境反射效果

            Posted on 2009-02-11 19:39 Herbert 閱讀(1415) 評論(0)  編輯 收藏 引用 所屬分類: DirectX

              就我所知常用的環境貼圖有兩種,一種是球狀的環境貼圖;一種是立方體的環境貼圖。如果是制作水體的反射或折射效果也可以只做平面的環境貼圖。
              DirectX中提供了一個很方便的立方體環境貼圖。立方體的六個面定義如下:

            typedef enum _D3DCUBEMAP_FACES
            {
                D3DCUBEMAP_FACE_POSITIVE_X     = 0,
                D3DCUBEMAP_FACE_NEGATIVE_X     = 1,
                D3DCUBEMAP_FACE_POSITIVE_Y     = 2,
                D3DCUBEMAP_FACE_NEGATIVE_Y     = 3,
                D3DCUBEMAP_FACE_POSITIVE_Z     = 4,
                D3DCUBEMAP_FACE_NEGATIVE_Z     = 5,

                D3DCUBEMAP_FACE_FORCE_DWORD    = 0x7fffffff
            } D3DCUBEMAP_FACES;


            如下圖所示:


               實現原理也很簡單:
               1、把立方體環境貼圖放到反射物體所知位置,并把該反射物體以外的東西映射到立方體環境貼圖上。
               2、根據攝像機到反射物體表面的點的向量a和該點的法向量n,求出a的反射向量b。
               3、以反射向量b作為立方體環境貼圖的尋址,把它所對應的顏色賦給反射物體上的點。

               實現過程需要用到一個立方體環境貼圖和一個深度表面,步驟如下:

               1、定義
                LPDIRECT3DCUBETEXTURE9 m_pReflectCubeTex;  //反射的立方貼圖 
                LPDIRECT3DSURFACE9           m_pSurfDepthCube; // DepthStencilSurface

               2、初始化
                HRESULT hr;

             //創建 DepthStencilSurface
                DXUTDeviceSettings d3dSettings = DXUTGetDeviceSettings();
             hr = pDev->CreateDepthStencilSurface( ENVMAPSIZE,
                     ENVMAPSIZE,
                     d3dSettings.pp.AutoDepthStencilFormat,
                     D3DMULTISAMPLE_NONE,
                     0,
                     TRUE,
                     & m_pSurfDepthCube,
                     NULL );
             if( FAILED( hr))
              return hr;

             //創建立方體貼圖
                hr = pDev->CreateCubeTexture( ENVMAPSIZE,
                                                    1,
                                                    D3DUSAGE_RENDERTARGET,
                                                    D3DFMT_A16B16G16R16F,
                                                    D3DPOOL_DEFAULT,
                                                    & m_pReflectCubeTex,
                                                    NULL );
             if( FAILED( hr) )
              return hr;



            3、把被反射物體渲染到立方體環境貼圖中

            //------------------------------------------------------------
            //desc: 渲染反射場景
            //param: pDev 設備
            //return: 是否創建成功
            //------------------------------------------------------------
            HRESULT GRenderMaterialProxy::RenderReflectScene(LPDIRECT3DDEVICE9 pDev)
            {
             HRESULT hr;

             if( pDev == NULL)
              return E_FAIL;

             LPDIRECT3DSURFACE9 pSufRTBackup; //RenderTarget 備份
             LPDIRECT3DSURFACE9 pSufDSBackup; //DepthStencilSurface 備份

             pDev->GetRenderTarget( 0, & pSufRTBackup);

             if( SUCCEEDED( pDev->GetDepthStencilSurface( & pSufDSBackup) ) )
             {
              pDev->SetDepthStencilSurface( m_pSurfDepthCube);
             }

             //以反射物體為中心,設置視口投影矩陣
             LPDIRECT3DSURFACE9 pSurf;
             D3DXMATRIXA16 mView, mProj;
             D3DXMATRIXA16 mViewDir( * GCameraManager::GetInstance()->GetCamera()->GetViewMatrix() );
             mViewDir._41 = mViewDir._42 = mViewDir._43 = 0.0f;

                D3DXMatrixPerspectiveFovLH( &mProj, D3DX_PI * 0.5f, 1.0f, 0.01f, 10000.0f );

             std::vector< IRenderObject *>::iterator itRenderObj;

             //渲染Cube 6個表面
             for( int iFace = 0; iFace < 6; ++iFace)
             {
              //獲取立方體環境貼圖表面,并設為設備的渲染目標
              //注意:GetCubeMapSurface的第二個參數0表示獲取立方體環境貼圖的表面
              //如果是 n則表示獲取立方體環境貼圖的第n層表面
              V( m_pReflectCubeTex->GetCubeMapSurface( ( D3DCUBEMAP_FACES) iFace, 0, & pSurf));
              V( pDev->SetRenderTarget( 0, pSurf));


              mView = DXUTGetCubeMapViewMatrix( iFace);
              D3DXMatrixMultiply( & mView, & mViewDir, & mView);

              V( pDev->Clear( 0L, NULL, D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0L ));
              
              //渲染被反射物體
              for( itRenderObj = m_vpReflectObjects.begin(); itRenderObj != m_vpReflectObjects.end(); itRenderObj++)
               (*itRenderObj)->Render( pDev, & mView, & mProj);

              SAFE_RELEASE( pSurf);

             }

             if( pSufDSBackup)
             {
              pDev->SetDepthStencilSurface( pSufDSBackup); //恢復深度表面
              SAFE_RELEASE( pSufDSBackup);
             }

             pDev->SetRenderTarget( 0, pSufRTBackup); //恢復渲染目標
             SAFE_RELEASE( pSufRTBackup);

             return S_OK;
            }
               

            4、根據立方體環境貼圖確定反射物體的顏色(用HLSL實現)

             //渲染環境貼圖
             if( m_bEnableReflect)
              RenderReflectScene( pDev);

             D3DXMATRIXA16 mWorld, mView, mProj, mWorldView;
             CBaseCamera * pCamera = GCameraManager::GetInstance()->GetCamera();
             D3DXVECTOR4 vEyePos = D3DXVECTOR4(* GCameraManager::GetInstance()->GetCamera()->GetEyePt(), 0.0f);
             D3DXMATRIXA16 mEyePos;
             ::D3DXMatrixTranslation( & mEyePos, vEyePos.x, vEyePos.y, vEyePos.z);
             ::D3DXMatrixTranslation( & mWorld, 0.0f, 0.0f, 0.0f);

             mView = * pCamera->GetViewMatrix();
             mProj = * pCamera->GetProjMatrix();

             GVector4 * pLightDirList = G3DSceneManager::GetInstance()->GetLightDirList();
             UINT iLightCount = G3DSceneManager::GetInstance()->GetLightCount();

             //設置變化矩陣
             m_pEffect->SetMatrix("g_mWorld", &mWorld);
             m_pEffect->SetMatrix("g_mProj", &mProj);
             m_pEffect->SetMatrix("g_mView", &mView);

             m_pEffect->SetTexture("g_texReflect", m_pReflectCubeTex); //設置立方體環境貼圖
             m_pEffect->SetFloat("g_fReflectivity", m_fReflectivity); //設置反射率




            ( fx文件代碼如下)

            extern matrix  g_mWorld;
            extern matrix  g_mView;
            extern matrix  g_mProj;

            texture    g_texReflect;

            float    g_fReflectivity = 0.9f;

            samplerCUBE g_samReflect =
            sampler_state
            {
             Texture = <g_texReflect>;
             MinFilter = Linear;
             MagFilter = Linear;
             MipFilter = Linear;
            };


            void VS_Reflect( float4 iPos : POSITION,
             float3 iNor : NORMAL,
             out float4 oPos : POSITION,
             out float3 oEnvTex : TEXCOORD0 )
            {
             matrix mWorldView = mul( g_mWorld, g_mView);
             oPos = mul( iPos, mWorldView);
             
             float3 vN = mul( iNor, mWorldView);
             vN = normalize( vN);
             
             float3 vEyeR = -normalize( oPos);
             
             float3 vRef;
             vRef = 2 * dot( vEyeR, vN) * vN - vEyeR;
             //vRef = reflect( vEyeR, vN);
             
             oEnvTex = vRef;
             
             oPos = mul( oPos, g_mProj);
            }


            float4 PS_Reflect( float3 iTex : TEXCOORD0 ) : COLOR
            {
             float4 fColor = texCUBE( g_samReflect, iTex);
             fColor.x = fColor.x * g_fReflectivity;
             fColor.y = fColor.y * g_fReflectivity;
             fColor.z = fColor.z * g_fReflectivity;
             return fColor;  
            }

            technique Tec_RenderMaterial
            {
             pass p0
             {
              vertexShader = compile vs_2_0 VS_Reflect();
              pixelShader = compile ps_2_0 PS_Reflect(); 
             }
            }


            實現效果如下:

            亚洲欧美成人久久综合中文网 | 色偷偷888欧美精品久久久| 7777久久久国产精品消防器材| 国产免费久久精品99久久| 青青国产成人久久91网| 久久精品www| 久久国产午夜精品一区二区三区| www性久久久com| 久久99精品久久久久久| 热re99久久精品国产99热| 国产精品午夜久久| 久久综合一区二区无码| 久久人妻少妇嫩草AV蜜桃| 亚洲综合日韩久久成人AV| 久久久久国产精品熟女影院| 国产午夜免费高清久久影院| 人人狠狠综合久久亚洲88| 国产毛片久久久久久国产毛片| 人人狠狠综合88综合久久| 久久久无码精品亚洲日韩京东传媒| 99精品国产免费久久久久久下载 | 久久国产乱子伦精品免费午夜| 久久久久国产视频电影| 久久精品国产精品亚洲精品 | 久久99精品久久只有精品| 国产69精品久久久久99尤物| 色偷偷91久久综合噜噜噜噜| 亚洲精品无码久久久久去q | 亚洲国产精品无码久久SM | 久久精品国产亚洲欧美| 久久伊人色| 99久久精品影院老鸭窝| 久久综合伊人77777| 国产成人久久精品激情| 日韩电影久久久被窝网| 久久久久99精品成人片欧美| 欧美日韩成人精品久久久免费看| 久久久精品2019免费观看| 免费一级欧美大片久久网| 国产精品美女久久久久| 久久精品国产亚洲AV久|