CocosCreator消融效果 |社区征文

效果预览

前期准备

首先我们准备一张噪声图用于后续的噪声消融

核心思路

片段着色器中有一个 discard 可以将片元的颜色丢弃,那我们的可以读取当前片元的某一个颜色基色(r、g、b),与我们的消融阈值 burnThreshold 做判断,低于该阈值的就丢弃掉颜色,当阈值为1时,就全部丢弃掉了。

实现过程

相对于我一遍帖子精灵的代码,只需要修改如下地方:

properties:
  burnThreshold: { value: 0}

CCProgram fs %{
  uniform Constant {
    float burnThreshold;
  };
  
  void main(){
    if (o.b < burnThreshold)
    {
      discard;
    }
  }
}%

运行效果:

仅做了片元丢弃

效果不是很惊艳,思考一下,如果在消融边界的地方加一个类似燃烧的效果会不会好一点?

改良一下

增加一个燃烧颜色的参数burnColor

      properties:
        burnColor: { value: [0.92,0.8,0.95,1] }
        
CCProgram fs %{
  uniform Constant {
    vec4 burnColor;
    float burnThreshold;
  };
  
  void main() {
    if (burnThreshold > 0.1 && o.b < burnThreshold + 0.1) {
      o = vec4(burnColor.rgb, o.a);
    }
  }
}%

这里我加了一个0.1阈值的过渡层来展示燃烧的颜色,其原理如下,很像一个三明治。

运行效果

是不是看着舒服多了?当然这个颜色值可以在材质球里去调整:

让美术调一个适合自己项目风格的色值吧。

最终代码

最后附上修改后的完整代码

// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.  
 
CCEffect %{
  techniques:
  - passes:
    - vert: vs
      frag: fs
      blendState:
        targets:
        - blend: true
      rasterizerState:
        cullMode: none
      properties:
        texture: { value: white }
        alphaThreshold: { value: 0.5 }
        burnThreshold: { value: 0}
        burnColor: { value: [0.92,0.8,0.95,1] }
}%
 
 
CCProgram vs %{
  precision highp float;
 
  #include <cc-global>
  #include <cc-local>
 
  in vec3 a_position;
  in vec4 a_color;
  out vec4 v_color;
 
  #if USE_TEXTURE
  in vec2 a_uv0;
  out vec2 v_uv0;
  #endif


 
  void main () {
    vec4 pos = vec4(a_position, 1);
 
    #if CC_USE_MODEL
    pos = cc_matViewProj * cc_matWorld * pos;
    #else
    pos = cc_matViewProj * pos;
    #endif
 
    #if USE_TEXTURE
    v_uv0 = a_uv0;
    #endif
 
    v_color = a_color;
 
    gl_Position = pos;
  }
}%
 
 
CCProgram fs %{
  precision highp float;
  
  #include <alpha-test>
  #include <texture>
 
  in vec4 v_color;
 
  #if USE_TEXTURE
  in vec2 v_uv0;
  uniform sampler2D texture;
  #endif

  uniform Constant {
    vec4 burnColor;
    float burnThreshold;
  };
 
  void main () {
    vec4 o = vec4(1, 1, 1, 1);
 
    #if USE_TEXTURE
      CCTexture(texture, v_uv0, o);
    #endif

    if (o.b < burnThreshold) {
      discard;
    }

    if (burnThreshold > 0.1 && o.b < burnThreshold + 0.1) {
      o = vec4(burnColor.rgb, o.a);
    }

    o *= v_color;
    
    ALPHA_TEST(o);

    gl_FragColor = o;
  }
}%
 

噪声消融

颜色消融的我们了解了原理,那噪声的就很清晰了,我们对噪声图采样,将噪声图得到的颜色基色与消融阈值做判断就好了

代码如下:

      properties:
        noiseTex: { value: white }
      
      
  uniform sampler2D noiseTex;
  
  void main() {
    vec4 burn = vec4(1, 1, 1, 1);
    CCTexture(noiseTex, v_uv0, burn);

    if (burn.b < burnThreshold)
    {
      discard;
    }
  }

运行的效果:

小结

对比发现,噪声更加随机,不受原图的影响,消融效果可以根据噪声图去定制,而颜色消融跟原图的关联比较大,做不到噪声消融那么定制化,但它也会因为不同图的配色不同,从而消融的效果也不相同,达到千孔千面的感觉。

至于项目中用哪个好,还是得看项目需求。有兴趣的同学可以关注一下我的公众号。你们的支持是我创作的动力!

image

感谢各位的观看,希望在渲染的道路上与君共勉,相互成长!

5赞

挺好 第一种消融 用了噪声图了吗?

第一种没用噪声,直接拿颜色分量处理的,第二种是用了噪声的

嗯,也是这么想的,毕竟没有用到texture