rtt粒子渲染不正常的一系列问题2

    技术2025-02-13  13

    粒子系统中最终颜色的来源:rgba = colorfading中各个阶段的rgba * 纹理的rgba.(不算alphablend到rendertarget的操作)。(colorfading中各个阶段的rgba 其实就是billboadset的顶点声明中的 diffuse 颜色。)1、既然最终的颜色是相乘关系,那么将colorfading的所有alpha改为0,为什么还是有闪烁?这个问题其实就是这个时候colorfading还没到起作用的时候。为什么呢,看看一个粒子系统中的一个billbord是怎样产生的:

    粒子的生成(emmiter)是在 affetor 之后的(以下代码):

    //---------------------------------------------------------------- void ParticleSystem::_update(Real timeElapsed) { ........ else { // Update existing particles _expire(timeElapsed);//销毁粒子 _triggerAffectors(timeElapsed);//触发响应器 _applyMotion(timeElapsed);//更新粒子和emitters的位置信息 // Emit new particles _triggerEmitters(timeElapsed);//生成新的粒子,应该说是一个billboad } .... } // void ParticleSystem::_triggerAffectors(Real timeElapsed) { ParticleAffectorList::iterator i, itEnd; itEnd = mAffectors.end(); for (i = mAffectors.begin(); i != itEnd; ++i) { (*i)->_affectParticles(this, timeElapsed); } } // void ParticleSystem::_executeTriggerEmitters(ParticleEmitter* emitter, unsigned requested, Real timeElapsed) { ...... Particle* p = 0; String emitterName = emitter->getEmittedEmitter(); if (emitterName == StringUtil::BLANK) p = createParticle();//创建粒子billboard else p = createEmitterParticle(emitterName); emitter->_initParticle(p);//初始化粒子在emitter的信息 // apply particle initialization by the affectors itAffEnd = mAffectors.end(); for (itAff = mAffectors.begin(); itAff != itAffEnd; ++itAff) (*itAff)->_initParticle(p);//调用粒子在affetor的初始化信息 //而ColourFading的将刚其颜色初始化为ColourValue::Black; //关键是ColourValue::Black的alpha=1, ...... 可见在effector之后才产生新的billboard,所以colorfading当然不会起作用了。而正是colorfading没起作用,粒子系统采用初始化的颜色来设置当前的billboard的颜色。在Ogre粒子系统中,有以上代码可以看出,这个颜色先是由产生的emitter的颜色付给billboard的颜色。再调用affector的初始化,这里如果是colorfading的话, ColourFading的将刚其颜色初始化为ColourValue::Black; 而ColourValue::Black的alpha=1,因此在一个billboard刚出生时(应该只有一次),它有了alpha值,而它的 rgb 是0,(显然这个alpha是多余的,其实colorfading和ogre的标准affector ColourInterpolator 很相似,而ColourInterpolator 里是没有这个_initParticle的,所以把这个_initparticle去掉吧

     void ColourFadingAffector::_initParticle(Particle* pParticle) {  // we set the colour of the particle to BLACK when it was born, so the colour of   // particle will not be affected by the colour of particle emitter.//  pParticle->colour = ColourValue::Black;//注释掉,或者把alpha也设为0 }

     

    而colorfading还有一个问题

       if (particle_time <= mFadeInTime)   {    currentOpacity *= (particle_time / mFadeInTime);   }

    有时会调用到,会出现随即的数据。所以也修改一下,particle_time < mFadeInTime)想象一下,如果emitter 的发射率是50,那么就有50个这样的 alpha 。而当前粒子系统还有存在的其它 billboard ,这些有颜色和位置却无alpha的已经被effector修改了。而这些带颜色的billboard和这些不正确的alpha混合肯定不会得出正确的结果。因此我们将 初始化的 alpha修改为0,将effctor中的alpha修改为1或者0.x 比较合适的数据。2、了解了原因后,下面给一个修改建议。由于ColourFading和ColourInterpolator相似,所以可以先将ColourFading替换为ColourInterpolator,(会少几个参数)然后是修改emitter和colorfaing里的颜色。我们想让刚出生的billboard透明,因此将emitter里的颜色alpha改为0 emitter Ring {  angle 10  colour 1 1 1 0  colour_range_start 1 1 1 0  colour_range_end 1 1 1 0}

    然后修改ColourInterpolator的颜色alpha affector ColourInterpolator {  colour0 0 0 0 0  time0 0  colour1 0.992157 0.227451 0.168627 0.25  time1 0.3  colour2 1 0.501961 0 0.25  time2 0.5  colour3 0 0 0 0  time3 1  colour4 0.5 0.5 0.5 0.25  time4 1  colour5 0.5 0.5 0.5 0.25  time5 1  repeat_times 1  opacity 0.25  fade_in_time 0  fade_out_time 1 }

    注意,如果在一个阶段的颜色是0,那么alpha设为0比较好。负责这个alpha就是多余的。由代码还可以知道,alpha也是插值的,而r,g,b也在分别插值,因此要得到完美的alpha是困难的,它们的斜率都不同。或者是修改colorfading那一块……

    最新回复(0)