• <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>

            制作波浪(1)

            Posted on 2008-11-26 22:59 Herbert 閱讀(956) 評論(1)  編輯 收藏 引用 所屬分類: DirectX
              最近在研究波浪的制作,但在網上很難找到一些詳細地介紹如何制作3D波浪的文章。后來找到了NVIDIA 的一本書《GPU Gems》,剛好在第一章就講到了如何制作波浪,所用到的算法是 Fast Fourier Transform (FFT)。下面簡單地對它作一個解讀。
               先來想以下波浪是怎么形成的。
               在海洋中,大多數波浪是由風產生的。急速流動的空氣推動一些水分子聚集起來,掀起洶涌的浪花——海面特定位點的擾動。這些分子推動相鄰的分子,相鄰的那些分子進而又推動與其相鄰的另一些分子,就這樣推動下去。通過這種方式,擾動沿著海面傳播開來,而單個水分子卻大致停留在同一區域。 
              從波浪的橫截面上看,很像正弦曲線,不同之處在于:正弦曲線波峰和波谷的弧度都一樣;而波浪的波峰比較尖,波谷比較平滑。

               下面來研究這個波浪的計算公式。先做以下約定:

            L : 一個周期的波浪長度

            w: 頻率;( w = 2 *п / L

            A: 幅度

            S: 速度

            φ: 相位(φ= S * 2 *φ / L

            D: 波矢量

            W(x,y,t) : t 時刻,處于 xy)位置的點受到一個波浪中心的影響而形成的高度

            H(x,y,t): t 時刻,處于 xy)位置的點受到所有波浪中心的影響而形成的高度(該點的實際高度)

            P(x, y,t): t 時刻,頂點的實際坐標


               在這里或者還要說明一下,海上的波浪可能是由多個不同中心的波浪共同作用而形成的,而W(x,y,t) 求的是一個波浪的影響,H(x,y,t)求的是所有波浪的影響。
               研究某一點所受到的影響主要有兩個,一個是計算某一時刻某一點的實際位置;另外一個是計算某一時刻某一點的法向量。下面先來研究如何計算某一時刻某一點的實際位置。
              
             

              我們可以設計一個水體類 GWater, 一個波浪類 GWave 。GWater 負責計算某一點的實際位置(即受到所有波浪影響后的實際位置)。GWave 負責記錄的信息有:

            L : 一個周期的波浪長度

            w: 頻率;( w = 2 *п / L

            A: 幅度

            S: 速度

            φ: 相位(φ= S * 2 *φ / L

               而
            D (波矢量)的計算還要涉及到具體的某個點的x和z坐標分量。
               一個GWater 里面可以有一個或多個GWave對象。

              我做了一個簡單的實現,下面是運行效果:

              1、一個波浪中心:


            2、兩個波浪中心:

              
            下面是我實現的源代碼:

               

            GWater.h 

            //************************************************************

            //說明:生成水體

            //作者:何家勉

            //創建日期:年月日

            //修改日期:年月日

            //版權所有Copyright (c) 2008

            //************************************************************

            #ifndef _GWater_H_

            #define _GWater_H_

             

             

            #include "GQuadTree.h"

            #include "GObject.h"

             

             

             

            namespace OpenAE

            {

             

             

             

            //------------------------------------------------------------

            //說明:波浪類

            //------------------------------------------------------------

            class GWave

            {

            private:

             

                float         m_fSpeed; //速度

                float         m_fSwing; //振幅A

                float         m_fCycleLength; //一個周期的長度

                D3DXVECTOR3       m_vCenter; //

             

             

                //------------- 下面變量可以由上面的變量求得,

                //因此只起到減少重復計算的作用--------------

                float         m_fFrequency; //頻率

                float         m_fPhase; //相位

               

                float         m_fAlpha; // sin( m_fAlpha)

             

            public:

                GWave(){};

                ~GWave(){};

             

            //------------------------------------------------------------

            //desc: 構造函數

            //param: fSpeed 速度

            //param: fSwing 幅度

            //param: fCycleLength 一個周期的波長

            //param: vCenter 波浪的中心

            //------------------------------------------------------------

                GWave( float fSpeed, float fSwing, D3DXVECTOR3 vCenter)

                {

                   m_fSpeed = fSpeed;

                   m_fSwing = fSwing;

                   m_fCycleLength = fSpeed * 2.0f * D3DX_PI;

                   m_vCenter = vCenter;

             

                }

             

             

            //------------------------------------------------------------

            //desc: 獲取波浪中心到某點的向量的值

            //param: staticX 點的x分量

            //param: statixZ 點的z分量

            //return: 向量的值

            //------------------------------------------------------------

                float GetDirectionValue(float staticX, float staticZ)

                {

                   float fSign; //決定正負號

                   //fSign = ( ( staticZ - m_vCenter.z ) >= 0 ) ? 1.0f : -1.0f;

                   fSign = -1.0f;

             

                   float fXLen = ( staticX - m_vCenter.x) * ( staticX - m_vCenter.x);

                   float fZLen = ( staticZ - m_vCenter.z) * ( staticZ - m_vCenter.z);

                   float fValue = sqrt( fXLen + fZLen) * fSign;

             

                   return fValue;

                }

             

             

            //------------------------------------------------------------

            //desc: 獲取波浪中心到某點的向量的x分量值

            //param: staticX 點的x分量

            //return: 向量的x分量值

            //------------------------------------------------------------

                float GetDirectionX(float staticX){ return staticX - m_vCenter.x;}

             

             

            //------------------------------------------------------------

            //desc: 獲取波浪中心到某點的向量的z分量值

            //param: statixZ 點的z分量

            //return: 向量的z分量值

            //------------------------------------------------------------

                float GetDirectionZ(float staticZ){ return staticZ - m_vCenter.z;}

             

             

             

             

            //------------------------------------------------------------

            //desc: 以下是一系列Get Set操作

            //------------------------------------------------------------

                void   SetSpeed( float fSpeed){ m_fSpeed = fSpeed;}

                float GetSpeed(){ return m_fSpeed;}

             

                void   SetSwing( float fSwing){ m_fSwing = fSwing;}

                float GetSwing(){ return m_fSwing;}

             

                void   SetCycleLength(float fLength){ m_fCycleLength = fLength;}

                float GetCycleLength(){ return m_fCycleLength;}

             

                void   SetCenter( D3DXVECTOR3 vCenter){ m_vCenter = vCenter;}

                D3DXVECTOR3 GetCenter(){ return m_vCenter;}

             

                float GetFrequency(){ return m_fFrequency;}

                float GetPhase(){ return m_fPhase;}

             

             

            //------------------------------------------------------------

            //desc: 在每次循環調用次類時都要先調用此方法,用于初始化某些變量

            //------------------------------------------------------------

                void   PreUpdate()

                {

                   m_fFrequency = CalculateFrequency(); //計算頻率

                   m_fPhase = CalculatePhase();       //計算相位

                }

             

             

            private:

             

            //------------------------------------------------------------

            //desc: 計算頻率

            //return: 返回頻率

            //------------------------------------------------------------

                float CalculateFrequency()

                {

                   return 2.0f * D3DX_PI / m_fCycleLength;

                }

             

             

            //------------------------------------------------------------

            //desc: 計算相位

            //return: 返回相位

            //------------------------------------------------------------

                float CalculatePhase()

                {

                   return m_fSpeed * 2.0f * D3DX_PI / m_fCycleLength;

                }

             

             

             

            };

             

             

             

             

             

             

            //------------------------------------------------------------

            //說明:水體類

            //------------------------------------------------------------

            class GWater : public GObject

            {

            private:

             

                GQuadTree *              m_pQuadTree; //四叉樹

             

                D3DXVECTOR3              m_vCenter; //水體的中心

                float                m_fWidth; //水體寬度

                float                m_fHeight; //水體高度

                UINT                 m_iLineNum;   //水體網格中橫向或縱向的網格線條數

             

             

                float                m_fCurTime; //當前時間

                float                m_fTimeStep; //最小單位時間

             

                std::vector< GWave *>    m_vWaves; //波浪列表

             

                LPDIRECT3DVERTEXBUFFER9 m_pVB;//頂點緩沖

                LPDIRECT3DINDEXBUFFER9 m_pIB; //索引緩沖

             

            public:

             

                //水的頂點結構

                struct WaterVertex

                {

                   D3DXVECTOR3 pos;

                   D3DCOLOR   color;

                   static const DWORD FVF;

                };

             

             

             

                GWater(void);

                ~GWater(void);

             

             

            //------------------------------------------------------------

            //desc: 創建頂點索引緩沖

            //param: fWidth 寬度

            //param: fHeight 高度

            //param: iLinesParam 決定線條個數(縱向線條條數= 橫向線條條數= 2 ^ iLinesParam + 1

            //param: vCenter 中心

            //return: 返回操作是否成功

            //------------------------------------------------------------

                GWater( LPDIRECT3DDEVICE9 pDev, float fWidth, float fHeight, int iLinesParam, float fTimeStep, D3DXVECTOR3 vCenter);

             

             

             

            //------------------------------------------------------------

            //desc: 更新

            //param: fTime 時間

            //------------------------------------------------------------

                void FrameMove( float fTime);

             

             

             

            //------------------------------------------------------------

            //desc: 渲染

            //param: pDev 設備

            //------------------------------------------------------------

                void Render(LPDIRECT3DDEVICE9 pDev);

             

             

             

            //------------------------------------------------------------

            //desc: 銷毀

            //------------------------------------------------------------

                void Destroy();

             

             

            //------------------------------------------------------------

            //desc: 創建一個波浪

            //param: fSpeed 速度

            //param: fSwing 幅度

            //param: fCycleLength 一個周期的波長

            //param: vCenter 波浪的中心

            //------------------------------------------------------------

                void CreateWave( float fSpeed, float fSwing, D3DXVECTOR3 vCenter)

                {

                   GWave * pWave = new GWave( fSpeed, fSwing, vCenter);

                   m_vWaves.push_back( pWave);

                }

             

             

            private:

             

            //------------------------------------------------------------

            //desc: 創建頂點索引緩沖

            //param: fWidth 寬度

            //param: fHeight 高度

            //param: iLineNum 橫向縱向網格個數

            //param: vCenter 中心

            //return: 返回操作是否成功

            //------------------------------------------------------------

                HRESULT GWater::CreateVIB( LPDIRECT3DDEVICE9 pDev, float fWidth, float fHeight, int iLineNum, D3DXVECTOR3 vCenter);

             

             

            //------------------------------------------------------------

            //desc: 繪制水體

            //param: pDev 設備

            //param: iTrangleNum 要畫的三角形個數

            //------------------------------------------------------------

                void Draw(LPDIRECT3DDEVICE9 pDev, UINT iTrangleNum);

             

             

            //------------------------------------------------------------

            //desc: 更新波浪

            //param: fTime 時間

            //------------------------------------------------------------

                void UpdateWave( float fTime);

             

             

            //------------------------------------------------------------

            //desc: 獲取某坐標位置的實際位置

            //param: staticX 靜止時的坐標x分量

            //param: staticZ 靜止時的坐標z分量

            //param: time 時間

            //return: 返回實際的坐標位置

            //------------------------------------------------------------

                D3DXVECTOR3 GetRealTimePosition(float staticX, float staticZ, float time);

             

             

             

             

            //------------------------------------------------------------

            //desc: 獲取某坐標位置的實際法向量

            //param: staticX 靜止時的坐標x分量

            //param: staticZ 靜止時的坐標z分量

            //param: time 時間

            //return: 返回實際法向量

            //------------------------------------------------------------

                D3DXVECTOR3 GetRealTimeNormal(float staticX, float staticZ, float time);

             

             

             

            //------------------------------------------------------------

            //desc: 獲取某坐標位置的實際高度

            //param: staticX 靜止時的坐標x分量

            //param: staticZ 靜止時的坐標z分量

            //param: time 時間

            //return: 返回實際的高度

            //------------------------------------------------------------

                float GetRealTimeHeight(float staticX, float staticZ, float time);

             

             

            //------------------------------------------------------------

            //desc: 獲取某坐標位置受到某波浪中心影響獲得的實際高度

            //param: staticX 靜止時的坐標x分量

            //param: staticZ 靜止時的坐標z分量

            //param: time 時間

            //param: pWave 波浪指針

            //return: 返回實際的高度

            //------------------------------------------------------------

                float GetHeightAffectByWave(float staticX, float staticZ, float time, GWave * pWave);

             

             

             

            //------------------------------------------------------------

            //desc: 獲取某點對x求導(用于求頂點法向量)

            //param: staticX 靜止時的坐標x分量

            //param: staticZ 靜止時的坐標z分量

            //param: time 時間

            //return: 返回導數

            //------------------------------------------------------------

                float GetHdx(float staticX, float staticZ, float time);

             

             

             

            //------------------------------------------------------------

            //desc: 獲取某點對z求導(用于求頂點法向量)

            //param: staticX 靜止時的坐標x分量

            //param: staticZ 靜止時的坐標z分量

            //param: time 時間

            //return: 返回導數

            //------------------------------------------------------------

                float GetHdz(float staticX, float staticZ, float time);

            };

             

             

             

             

             

            }

             

             

             

            #endif

             

              


             

            Feedback

            # re: 制作波浪(1)  回復  更多評論   

            2009-12-25 12:02 by Bill Hsu
            制作波浪(2)怎么沒寫呢?
            丰满少妇人妻久久久久久| 久久天天躁狠狠躁夜夜不卡 | 国产精品久久久久影视不卡| 18岁日韩内射颜射午夜久久成人 | 国产精品99久久不卡| 久久一区二区三区免费| 亚洲AV无码久久| 中文字幕亚洲综合久久2| 久久精品国产亚洲av麻豆图片 | 日日狠狠久久偷偷色综合96蜜桃 | 久久国产精品一国产精品金尊| 久久亚洲国产精品一区二区| 手机看片久久高清国产日韩| 国产精品久久午夜夜伦鲁鲁| 亚洲日韩欧美一区久久久久我| AV无码久久久久不卡网站下载| 日韩一区二区三区视频久久| 亚洲欧美精品伊人久久| 久久久久亚洲Av无码专| 欧美精品国产综合久久| 久久久久久A亚洲欧洲AV冫| 精品久久人妻av中文字幕| 久久天天躁狠狠躁夜夜躁2014| 久久精品国产精品亚洲下载| 久久婷婷综合中文字幕| 久久精品一本到99热免费| 精品综合久久久久久97| 少妇被又大又粗又爽毛片久久黑人| 欧美精品一本久久男人的天堂| 人妻无码αv中文字幕久久| 亚洲精品国产第一综合99久久| 精品久久久久久无码人妻热| 亚洲成色999久久网站| 久久99亚洲网美利坚合众国| 久久人人爽人人爽人人片AV不| 久久91精品国产91| 国产成年无码久久久免费| 一本色道久久88精品综合| 亚洲AV日韩AV永久无码久久| 欧美亚洲色综久久精品国产| 国产亚洲综合久久系列|