游戏开发论坛

 找回密码
 立即注册
搜索
查看: 12656|回复: 9

天龙八部粒子特效还原技术

[复制链接]

27

主题

563

帖子

568

积分

高级会员

Rank: 4

积分
568
发表于 2009-12-21 09:08:00 | 显示全部楼层 |阅读模式
一,天龙八部的粒子效果非常漂亮,漂亮的后面一定有着复杂的过程.下面以一个粒子特效为例.看看它是怎样一

个过程.
1,用TlParticleViewer.exe工具导出一个"变身火炬_01"粒子特效,得到下面的脚本
  particle_system b_变身火炬_01
  {
        quota        40
        emit_emitter_quota        3
        material        shidenglong_010
        particle_width        20
        particle_height        20
        cull_each        false
        renderer        billboard
        sorted        false
        local_space        false
        iteration_interval        0
        nonvisible_update_timeout        0
        billboard_type        point
        billboard_origin        center
        billboard_rotation_type        vertex
        common_up_vector        0 1 0
        point_rendering        false
        accurate_facing        false
        speed_relatived_size_factor        0.01

        emitter Box
        {
                angle        5
                colour        1 1 1 1
                colour_range_start        1 1 1 1
                colour_range_end        1 1 1 1
                direction        0 1 0
                emission_rate        40
                position        0 0 0
                velocity        6
                velocity_min        6
                velocity_max        80
                time_to_live        1
                time_to_live_min        1
                time_to_live_max        1
                duration        0
                duration_min        0
                duration_max        0
                repeat_delay        0
                repeat_delay_min        0
                repeat_delay_max        1
                name       
                emit_emitter       
                width        1
                height        1
                depth        1
        }

        affector ColourFading
        {
                colour0        0 0 0 1
                colour1        1 0.607843 0.215686 1
                colour2        0.47451 0.168627 0 1
                colour3        0 0 0 1
                colour4        0.5 0.5 0.5 0
                colour5        0.5 0.5 0.5 0
                time0        0
                time1        0.2
                time2        0.4
                time3        1
                time4        1
                time5        1
                repeat_times        1
                opacity        1
                fade_in_time        0
                fade_out_time        1
        }

        affector Rotator
        {
                rotation_speed_range_start        0
                rotation_speed_range_end        0
                rotation_range_start        0
                rotation_range_end        360
        }

        affector ScaleInterpolator
        {
                time0        0
                time1        1
                time2        1
                time3        1
                time4        1
                time5        1
                scale0        1 1 1
                scale1        0.1 0.1 0
                scale2        1 1 1
                scale3        1 1 1
                scale4        1 1 1
                scale5        1 1 1
                scale5        1 1 1
                repeat_times        1
                uniform_size        true
                width_range_start        200
                width_range_end        200
                height_range_start        300
                height_range_end        300
                use_constant_scale        false
                constant_scale        1 1 1
                use_interpolated_scale        true
        }
     }
  2,ogre中并没有上面脚本中的ColourFading和ScaleInterpolator这2个影响器.要正确执行这个脚本.必须为

ogre引擎系统增加这2个影响器.

27

主题

563

帖子

568

积分

高级会员

Rank: 4

积分
568
 楼主| 发表于 2009-12-21 09:09:00 | 显示全部楼层

Re: 天龙八部粒子特效还原技术

二,添加一个ScaleInterpolator影响器

01,首先下载一个OGRE源码包,

02,创建一个影响器并把它压进容器
   1,打开文件..\ogre-v1-6-4\ogre\PlugIns\ParticleFX\src\OgreParticleFXPlugin.cpp
   2,找到函数void ParticleFXPlugin::install(),在函数后面增加如下代码:
     pAffFact = OGRE_NEW ScaleInterpolatorAffectorFactory();
     ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact);
     mAffectorFactories.push_back(pAffFact);

03,定义新增的影响器类
   1,打开文件夹..\ogre-v1-6-4\ogre\PlugIns\ParticleFX\include,
   2,找到OgreColourFaderAffector.h,复制一份并改名为OgreScaleInterpolatorAffector.h
   3,找到OgreColourFaderAffectorFactory.h,复制一份并改名为OgreScaleInterpolatorAffectorFactory.h
   4,用下面的源码替换OgreScaleInterpolatorAffector.h中的源码
#ifndef __ScaleInterpolatorAffector_H__
#define __ScaleInterpolatorAffector_H__
#include "OgreParticleFXPrerequisites.h"
#include "OgreParticleAffector.h"
#include "OgreStringInterface.h"
namespace Ogre {
    class _OgreParticleFXExport ScaleInterpolatorAffector : public ParticleAffector
    {
    public:
                enum { MAX_STAGESA = 6 };
        class CmdColourAdjust : public ParamCommand
        {
                public:
                        size_t                mIndex;
                public:
            String doGet(const void* target) const;
            void doSet(void* target, const String& val);
        };
                class CmdTimeAdjust : public ParamCommand
        {
        public:
                        size_t                mIndex;
                public:
            String doGet(const void* target) const;
            void doSet(void* target, const String& val);
                };
        class Cmdwidth_range_startAdjust : public ParamCommand           
        {
        public:
            String doGet(const void* target) const;
           void doSet(void* target, const String& val);
        };
        class Cmdwidth_range_endAdjust : public ParamCommand           
        {
        public:
            String doGet(const void* target) const;
            void doSet(void* target, const String& val);
        };
        class Cmdheight_range_startAdjust : public ParamCommand           
        {
       public:
            String doGet(const void* target) const;
            void doSet(void* target, const String& val);
        };
        class Cmdheight_range_endAdjust : public ParamCommand         
        {
       public:
           String doGet(const void* target) const;
           void doSet(void* target, const String& val);       };
                    
       static CmdColourAdjust                    msColourCmd[MAX_STAGESA];
       static CmdTimeAdjust                    msTimeCmd[MAX_STAGESA];
        static Cmdwidth_range_startAdjust        mswidth_range_startCmd;
       static Cmdwidth_range_endAdjust            mswidth_range_endCmd;
       static Cmdheight_range_startAdjust        msheight_range_startCmd;
       static Cmdheight_range_endAdjust        msheight_range_endCmd;
                           
       ScaleInterpolatorAffector(ParticleSystem* psys);        
        void _affectParticles(ParticleSystem* pSystem, Real timeElapsed);
                void setColourAdjust(size_t index, Real colour);
                Real getColourAdjust(size_t index) const;
              
                void setTimeAdjust(size_t index, Real time);
        Real getTimeAdjust(size_t index) const;
              
       void setwidth_range_startAdjust(float width);
                Real getwidth_range_startAdjust(void) const;
        void setwidth_range_endAdjust(float width);
                Real getwidth_range_endAdjust(void) const;
        void setheight_range_startAdjust(float width);
                Real getheight_range_startAdjust(void) const;
       void setheight_range_endAdjust(float width);
                Real getheight_range_endAdjust(void) const;

   protected:
        Real                                    mColourAdj[MAX_STAGESA];
                Real                                        mTimeAdj[MAX_STAGESA];
       Real NewWideA;
        Real  width_range_start;  
        Real  width_range_end;   
       Real  height_range_start;  
        Real  height_range_end;   
   };
}
#endif
   5,用下面的源码替换OgreScaleInterpolatorAffectorFactory.h中的源码
    #ifndef __ScaleInterpolatorAffectorFactory_H__
#define __ScaleInterpolatorAffectorFactory_H__
#include "OgreParticleFXPrerequisites.h"
#include "OgreParticleAffectorFactory.h"
#include "OgreScaleInterpolatorAffector.h"
namespace Ogre {
  
class _OgreParticleFXExport ScaleInterpolatorAffectorFactory : public ParticleAffectorFactory
    {
    String getName() const { return "ScaleInterpolator"; }      
       ParticleAffector* createAffector(ParticleSystem* psys)
        {
            ParticleAffector* p = OGRE_NEW ScaleInterpolatorAffector(psys);
            mAffectors.push_back(p);
            return p;
        }
   };
}
#endif

27

主题

563

帖子

568

积分

高级会员

Rank: 4

积分
568
 楼主| 发表于 2009-12-21 09:10:00 | 显示全部楼层

Re:天龙八部粒子特效还原技术

04,
   1,打开文件夹..\ogre-v1-6-4\ogre\PlugIns\ParticleFX\src
   2,找到OgreColourFaderAffector.cpp,复制一份并改名为OgreScaleInterpolatorAffector.cpp
   3,用下面的源码替换OgreScaleInterpolatorAffector.cpp中的源码
#include "OgreScaleInterpolatorAffector.h"
#include "OgreParticleSystem.h"
#include "OgreStringConverter.h"
#include "OgreParticle.h"
#include <windows.h>
namespace Ogre {
    ScaleInterpolatorAffector::CmdColourAdjust                        

ScaleInterpolatorAffector::msColourCmd[MAX_STAGESA];
    ScaleInterpolatorAffector::CmdTimeAdjust                        

ScaleInterpolatorAffector::msTimeCmd[MAX_STAGESA];
    ScaleInterpolatorAffector::Cmdwidth_range_startAdjust   

ScaleInterpolatorAffector::mswidth_range_startCmd;
    ScaleInterpolatorAffector::Cmdwidth_range_endAdjust      

ScaleInterpolatorAffector::mswidth_range_endCmd;
    ScaleInterpolatorAffector::Cmdheight_range_startAdjust   

ScaleInterpolatorAffector::msheight_range_startCmd;
    ScaleInterpolatorAffector::Cmdheight_range_endAdjust      

ScaleInterpolatorAffector::msheight_range_endCmd;
     ScaleInterpolatorAffector::ScaleInterpolatorAffector(ParticleSystem* psys)
        : ParticleAffector(psys)
    {
                for (int i=0;i<MAX_STAGESA;i++)
                {
                        mColourAdj        = 1.0f;
                        mTimeAdj                = 1.0f;
                }
              
        mType = "ScaleInterpolator";
        if (createParamDictionary("ScaleInterpolatorAffector"))
       {
            ParamDictionary* dict = getParamDictionary();
                        for (int i=0;i<MAX_STAGESA;i++)
                        {
                                msColourCmd.mIndex        = i;
                                msTimeCmd.mIndex                = i;
                                StringUtil::StrStreamType stage;
                                stage << i;
                                String        colour_title        = String("scale") + stage.str();
                                String        time_title                = String("time") + stage.str();
                                String        colour_descr        = String("Stage ") + stage.str() +

String(" scale.");
                                String        time_descr                = String("Stage ") + stage.str()

+ String(" time.");
                                dict->addParameter(ParameterDef(colour_title, colour_descr,

PT_COLOURVALUE), &msColourCmd);
                                dict->addParameter(ParameterDef

(time_title,   time_descr,   PT_REAL),                 &msTimeCmd);
                        }
      

     dict->addParameter(ParameterDef("width_range_start",
                "The amount by which

to adjust the width_range_start component of particles per second.",
                PT_REAL),

&mswidth_range_startCmd);
            dict->addParameter(ParameterDef("width_range_end",
      

         "The amount by which to adjust the width_range_end component of particles per

second.",
                PT_REAL), &mswidth_range_endCmd);
            dict->addParameter

(ParameterDef("height_range_start",
                "The amount by which to adjust the

height_range_start component of particles per second.",
                PT_REAL),

&msheight_range_startCmd);
            dict->addParameter(ParameterDef("height_range_end",
     

           "The amount by which to adjust the height_range_end component of particles per

second.",
                PT_REAL), &msheight_range_endCmd);
        }
    }
    void ScaleInterpolatorAffector::setColourAdjust(size_t index, Real colour)
    {
        mColourAdj[index] = colour;
    }
    Real ScaleInterpolatorAffector::getColourAdjust(size_t index) const
   {
        return mColourAdj[index];
    }
   void ScaleInterpolatorAffector::setTimeAdjust(size_t index, Real time)
    {
       mTimeAdj[index] = time;
   }
   Real ScaleInterpolatorAffector::getTimeAdjust(size_t index) const
    {
        return mTimeAdj[index];
    }
void ScaleInterpolatorAffector::setwidth_range_startAdjust(float width)
{
width_range_start = width;
}
float ScaleInterpolatorAffector::getwidth_range_startAdjust(void) const
{
        return width_range_start;
}
void ScaleInterpolatorAffector::setwidth_range_endAdjust(float width)
{
width_range_end = width;
}
float ScaleInterpolatorAffector::getwidth_range_endAdjust(void) const
{
       return width_range_end;
}
        void ScaleInterpolatorAffector::setheight_range_startAdjust(float height)
{
height_range_start = height;
}
float ScaleInterpolatorAffector::getheight_range_startAdjust(void) const
{
        return height_range_start;
}
void ScaleInterpolatorAffector::setheight_range_endAdjust(float height)
{
height_range_end = height;
}
float ScaleInterpolatorAffector::getheight_range_endAdjust(void) const
{
       return height_range_end;
}       
    String ScaleInterpolatorAffector::Cmdwidth_range_startAdjust::doGet(const void* target)

const
    {
       return StringConverter::toString(
           static_cast<const ScaleInterpolatorAffector*>(target)->getwidth_range_startAdjust()

);
    }
    void ScaleInterpolatorAffector::Cmdwidth_range_startAdjust::doSet(void* target, const

String& val)   
{
        static_cast<ScaleInterpolatorAffector*>(target)->setwidth_range_startAdjust(
           StringConverter::parseReal(val));
    }
    String ScaleInterpolatorAffector::Cmdwidth_range_endAdjust::doGet(const void* target) const
    {
        return StringConverter::toString(
            static_cast<const ScaleInterpolatorAffector*>(target)->getwidth_range_endAdjust() );
    }
    void ScaleInterpolatorAffector::Cmdwidth_range_endAdjust::doSet(void* target, const String&

val)
    {
        static_cast<ScaleInterpolatorAffector*>(target)->setwidth_range_endAdjust(
            StringConverter::parseReal(val));
   }
    String ScaleInterpolatorAffector::Cmdheight_range_startAdjust::doGet(const void* target)

const
   {
       return StringConverter::toString(
           static_cast<const ScaleInterpolatorAffector*>(target)->getheight_range_startAdjust()

);
    }
   void ScaleInterpolatorAffector::Cmdheight_range_startAdjust::doSet(void* target, const

String& val)
    {
       static_cast<ScaleInterpolatorAffector*>(target)->setheight_range_startAdjust(
            StringConverter::parseReal(val));
    }
   String ScaleInterpolatorAffector::Cmdheight_range_endAdjust::doGet(const void* target) const
    {
       return StringConverter::toString(
            static_cast<const ScaleInterpolatorAffector*>(target)->getheight_range_endAdjust()

);
    }
   void ScaleInterpolatorAffector::Cmdheight_range_endAdjust::doSet(void* target, const String&

val)
    {
        static_cast<ScaleInterpolatorAffector*>(target)->setheight_range_endAdjust(
            StringConverter::parseReal(val));
    }
    String ScaleInterpolatorAffector::CmdColourAdjust::doGet(const void* target) const
    {
       return StringConverter::toString(
            static_cast<const ScaleInterpolatorAffector*>(target)->getColourAdjust(mIndex) );
    }    void ScaleInterpolatorAffector::CmdColourAdjust::doSet(void* target, const String& val)
    {        static_cast<ScaleInterpolatorAffector*>(target)->setColourAdjust(mIndex,
           StringConverter::parseReal(val));   
}
    String ScaleInterpolatorAffector::CmdTimeAdjust::doGet(const void* target) const
    {
        return StringConverter::toString(
            static_cast<const ScaleInterpolatorAffector*>(target)->getTimeAdjust(mIndex) );
    }
   void ScaleInterpolatorAffector::CmdTimeAdjust::doSet(void* target, const String& val)
    {
       static_cast<ScaleInterpolatorAffector*>(target)->setTimeAdjust(mIndex,
           StringConverter::parseReal(val));   
}
void ScaleInterpolatorAffector::_affectParticles(ParticleSystem* pSystem, Real timeElapsed)
{
        Particle*                        p;
                ParticleIterator        pi                                = pSystem->_getIterator

();
     Real dsw,dsh;
      Real  mScaleAdj;
                Real NewWide, NewHigh;
                Real width_range=Math::RangeRandom (width_range_start,width_range_end);
                Real height_range=Math::RangeRandom (height_range_start,height_range_end);
   while (!pi.end())
   {
     p = pi.getNext();
   if(p->timeToLive<=mTimeAdj[0])   
     {
     mScaleAdj=mColourAdj[0];
         }
         else if(p->timeToLive<=mTimeAdj[1])  
    {  
     mScaleAdj=mColourAdj[1];        
}
         else if(p->timeToLive<=mTimeAdj[2])
     {
        mScaleAdj=mColourAdj[2];
         }
         else if(p->timeToLive<=mTimeAdj[3])
     {
     mScaleAdj=mColourAdj[3];
         }
         else if(p->timeToLive<=mTimeAdj[4])  
     {
     mScaleAdj=mColourAdj[4];
         }
         else   
    {
       mScaleAdj=mColourAdj[5];
         }
              
     dsw=-width_range*mScaleAdj*timeElapsed;   
      dsh=-height_range*mScaleAdj*timeElapsed;  
                        if( p->hasOwnDimensions() == false )
                        {
                   NewWide = pSystem->getDefaultWidth() + dsw;
                    NewHigh = pSystem->getDefaultHeight() + dsh;
                        }
                        else
                        {
                   NewWide = p->getOwnWidth()+ dsw;
                    NewHigh = p->getOwnHeight() + dsh;
                        }
                        p->setDimensions( NewWide, NewHigh );
        }
}
}

27

主题

563

帖子

568

积分

高级会员

Rank: 4

积分
568
 楼主| 发表于 2009-12-21 09:11:00 | 显示全部楼层

Re:天龙八部粒子特效还原技术

05,添加OgreScaleInterpolatorAffector.cpp到项目中

三,依样画葫芦添加一个ColourFading影响器
四,
1,编译工程..\ogre-v1-6-4\ogre\PlugIns\ParticleFX\scripts\Plugin_ParticleFX_vc8.vcproj,得到

Plugin_ParticleFX.dll
2,替换应用程序中的Plugin_ParticleFX.dll

34

主题

443

帖子

478

积分

中级会员

Rank: 3Rank: 3

积分
478
发表于 2009-12-21 15:20:00 | 显示全部楼层

Re:天龙八部粒子特效还原技术

谢谢分享

5

主题

74

帖子

86

积分

注册会员

Rank: 2

积分
86
发表于 2010-1-26 20:17:00 | 显示全部楼层

Re:天龙八部粒子特效还原技术

好~
抬回去我也试试~

14

主题

597

帖子

597

积分

高级会员

Rank: 4

积分
597
发表于 2010-1-27 19:45:00 | 显示全部楼层

Re:天龙八部粒子特效还原技术

不懂不装懂者华丽路过
领完酱油,土遁......

5

主题

27

帖子

27

积分

注册会员

Rank: 2

积分
27
发表于 2010-1-31 12:57:00 | 显示全部楼层

Re:天龙八部粒子特效还原技术

lz我有个问题, 这个粒子效果 是搜狐 压缩前,然后 你给解压吗?

6

主题

38

帖子

63

积分

注册会员

Rank: 2

积分
63
发表于 2010-2-21 08:58:00 | 显示全部楼层

Re:天龙八部粒子特效还原技术

就是做了一个粒子影响器

13

主题

312

帖子

312

积分

中级会员

Rank: 3Rank: 3

积分
312
发表于 2010-2-22 00:10:00 | 显示全部楼层

Re:天龙八部粒子特效还原技术

学习了!!!


-------------------------------------------------------------------------------------------


欢迎访问开源图形处理器体系结构论坛(OpenGPU论坛) http://www.opengpu.org/bbs/

OpenGPU Graphics Open Source community(图形开源社区),聚焦领域(focus domain)包括:
  * GPU Architecture(图形处理器体系结构)
  * Graphics Algorithm(图形算法)
  * Open Source Rendering Engine(开源渲染器)
  * Open Source GPU Simulator/RTL Implement(开源GPU模拟器)
  * Mobile GPU Developing (移动图形设备的开发)
  * GPGPU Programming (面向通用的图形处理器编程)
                      (包括CUDA/OpenCL /DirectCompute)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2024-4-30 16:29

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表