zoukankan      html  css  js  c++  java
  • cocos2d制作动态光晕效果基础——blendFunc

    转自:http://www.2cto.com/kf/201207/144191.html

    最近的项目要求动态光晕的效果。

    何谓动态光晕?之前不知道别人怎么称呼这个效果,

    不过在我看来,“动态光晕”这个名儿起的还是蛮不错的。

    动态光晕就是在背景图片的上面蒙上一层光照。。。

    但是这个光照比较特别,他能够变换颜色,变换光圈的半径大小,从而制造出类似梦幻迷离的效果~

    新项目中我是负责游戏特效这一块的,操作过程中我觉得这东西蛮不错的,很有感觉。

    之前的项目中我是负责整个游戏场景的编码实现的,因为较为复杂的游戏逻辑,所以我做的很蛋痛~

    伙计做的是菜单场景以及所有游戏的图片,那时候我便觉得,其实做美工也是一件很不错的事情:

    没有让人蛋碎的bug等着你去修复,不需要去考虑某些游戏中比较关键的算法,很直观的就出图了,

    工作的质量怎么样全看处出来的图怎么样,好看了,符合要求了便没有其他的麻烦事儿了。

    基于此,我有意思向美工方向发展,新项目中包揽整个游戏的特殊效果,我做起来感觉便很舒心:

    这个东西能够实时的看到出来的效果怎么样,很直观,同时也可以写些代码,甚至是研究一些比较有意思的算法,

    这些算法也能够以很直观的方式呈现在眼前,这一切一切,都是让人感觉那么的享受~

    好吧,废话到此为止,主要使用了下面的两张图片:

     
    左边的那张是游戏的背景图片,右边的那张是光晕的基本图片~

    素材到位了,实现方案也在,将右边那张图片直接叠在左边图片的上面。

    不过,如果真有那么简单的话我也就没必要在这里啰唆了。

    直接叠上去的话,背景图片中的那盏灯笼的细节会被遮盖的所剩无几,

    cocos2d 添加 sprite 到 layer 的机制是这样的:

    opengl 混合将z值较大的精灵叠在 z值较小的精灵上面,混合的配置是

    (ccBlendFunc){GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA}

    很简单,src(源) 代表偏上的精灵,dst(目标) 代表偏下的精灵

    上面的配置所表示的含义为:

    如果偏上的精灵半透明,那么最终呈现的画面将会隐隐的露出偏下的精灵图片,

    如果偏上的精灵完全不透明,那么偏上精灵所在的部分会完全将底下的精灵图片遮盖住~

    如果纯粹的 addChild ,addChild 将 精灵添加进来的话,效果呈现如下:


    我所追求的动态光晕的效果可以在 photoshop中直观的表示出来,如下:

    偏上的图层是光圈那种图片,混合模式采用的是柔光(softlight)~

    项目发起人、出图师兼音效师给我的需求便是提供如上柔光的混合效果。

    当然,事情远没有我想象的简单,photoshop 的柔光,强光,溶解等混合算法都是商业级的,

    网上并不能找到具体的算法,整片叠底还好,定义明确还比较容易实现,

    简单点说,就是将 sprite 的 setBlendFunc 的参数设置为

    (ccBlendFunc){GL_DST_COLOR, GL_ZERO}

    如果你对 opengl 的混合比较熟悉的话,就知道上面得出的结果正好满足正片叠底的定义~

    另外就是,如下的参数设置同样也能得到整片叠低的效果

    (ccBlendFunc){GL_ZERO, GL_SRC_COLOR}

    得到的最终效果基本上是和上面那种参数设置是一致的~

    但遗憾的是,整片叠低不是我所需求的混合模式:

    其一,纯粹正片叠底的混合将会得到这样一幅图像,仅仅只是一个圆形的图像,如下:

    其二,参照上图,很明显重叠的区域颜色的亮度反而降低了

    这样的话,基本上就可以枪毙采用 正片叠底进行混合的方案了~

    后来我又尝试了很多种的 blendFunc 参数配置,简单而言就是不断对参数进行搭配,

    然后看程序运行的效果是否满足我的需求,opengles 混合的参数如下(blendFunc){SRC 源, DST 目标}:

    // ******************************************************************  
     //    iphoneOS5.0/Frameworks/OpenGLES.framework/ES2/gl.h  
      
     /* BlendingFactorDest */ 
     #define GL_ZERO                           0  
     #define GL_ONE                            1  
     #define GL_SRC_COLOR                      0x0300  
     #define GL_ONE_MINUS_SRC_COLOR            0x0301  
     #define GL_SRC_ALPHA                      0x0302  
     #define GL_ONE_MINUS_SRC_ALPHA            0x0303  
     #define GL_DST_ALPHA                      0x0304  
     #define GL_ONE_MINUS_DST_ALPHA            0x0305  
      
     /* BlendingFactorSrc */ 
     /*      GL_ZERO */ 
     /*      GL_ONE */ 
     #define GL_DST_COLOR                      0x0306  
     #define GL_ONE_MINUS_DST_COLOR            0x0307  
     #define GL_SRC_ALPHA_SATURATE             0x0308  
     /*      GL_SRC_ALPHA */ 
     /*      GL_ONE_MINUS_SRC_ALPHA */ 
     /*      GL_DST_ALPHA */ 
     /*      GL_ONE_MINUS_DST_ALPHA */ 
      
     // ****************************************************************** 
    // *****************************************************************
    
            // 黑暗中的带背景图片纹理的光圈~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_DST_COLOR, GL_ZERO};  
              
             // 黑暗中的黄色光圈(前面表示upper,后面表示lower)~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_ONE, GL_ZERO};  
              
             // 黑暗中的黄色光圈(前面表示upper,后面表示lower)~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_DST_ALPHA, GL_ZERO};  
              
             // 默认的 blend 配置~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA};  
              
             // premultiplied~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_ONE, GL_ONE_MINUS_SRC_ALPHA};  
              
             // 仅背景图片有所显示~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_ZERO, GL_ONE};  
              
             // 黄色光圈区域亮度加强(2倍的强度)~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_DST_COLOR, GL_SRC_COLOR};  
              
             // 正片叠底~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA};  
              
             // 类似柔光:黄色光圈区域亮度加强,其他地方也不会显示为纯黑(接近我想要的想过了)~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_DST_COLOR, GL_ONE};  
              
             // Screen~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_ONE_MINUS_DST_COLOR, GL_ONE};  
              
             // Linear Dodge~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_ONE, GL_ONE};  
              
             // 很类似柔光效果,这个也最接近我的需求了~  
             ccBlendFunc tmp_oBlendFunc = {GL_SRC_ALPHA, GL_ONE}; 
              
             // GL_ONE_MINUS_SRC_ALPHA 注定是不行的(光晕中心会被模糊掉)~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA};  
              
             // 标准的正片叠底~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA};  
              
             // 下面两种是差不多的~  
     //        ccBlendFunc tmp_oBlendFunc = {GL_ZERO, GL_SRC_COLOR};  
     //        ccBlendFunc tmp_oBlendFunc = {GL_DST_COLOR, GL_ZERO}; 
    
    // ***************************************************************************************************************      // 1.正片叠底 // ccBlendFunc tmp_oBlendFunc = {GL_DST_COLOR, GL_ONE_MINUS_DST_ALPHA}; // 2. // ccBlendFunc tmp_oBlendFunc = {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA}; // 3.黄色光圈区域显示背景图片,其他区域显示黑色(黄色光圈很柔和)~ // ccBlendFunc tmp_oBlendFunc = {GL_ZERO, GL_SRC_ALPHA}; // 4.背景图片在黄色光圈区域的图片尤为阴暗~ // ccBlendFunc tmp_oBlendFunc = {GL_ZERO, GL_ONE_MINUS_SRC_ALPHA}; // 5.仅仅显示出了原始的背景图片~ // ccBlendFunc tmp_oBlendFunc = {GL_ZERO, GL_DST_ALPHA}; // 6.全黑~ // ccBlendFunc tmp_oBlendFunc = {GL_ZERO, GL_ONE_MINUS_DST_ALPHA}; // ---------------------------------------- // 7.仅显示黄色光圈图片~ // ccBlendFunc tmp_oBlendFunc = {GL_ONE, GL_ZERO}; // 8.纯粹的添加光圈图片到背景图片上面~ // ccBlendFunc tmp_oBlendFunc = {GL_ONE, GL_ONE}; // 9.纯粹的添加光圈图片到背景图片上面~ // ccBlendFunc tmp_oBlendFunc = {GL_ONE, GL_DST_COLOR}; // 10.纯粹的添加光圈图片到背景图片上面~ // ccBlendFunc tmp_oBlendFunc = {GL_ONE, GL_ONE_MINUS_DST_COLOR}; // 11.纯粹的添加光圈图片到背景图片上面~ // ccBlendFunc tmp_oBlendFunc = {GL_ONE, GL_SRC_ALPHA_SATURATE}; // 12.黄色光圈区域显示背景图片,其他区域显示黑色(黄色光圈很刺眼)~ // ccBlendFunc tmp_oBlendFunc = {GL_ONE, GL_SRC_ALPHA}; // 13. // ccBlendFunc tmp_oBlendFunc = {GL_SRC_COLOR, GL_DST_COLOR};
  • 相关阅读:
    Vue内敛模板
    vue自定义组件添加原生事件监听
    vue 组件开发 props 验证
    Vue中子组件数据跟着父组件改变和父组件数据跟着子组件改变的方法
    jQuery中outerWidth()方法
    CSS3-transition
    行内元素(例如)设置float之后才能用width调整宽度
    leetcode LRU Cache python
    opcache effect
    leetcode Same Tree python
  • 原文地址:https://www.cnblogs.com/sevenyuan/p/3865885.html
Copyright © 2011-2022 走看看