从零开始shader系列,做个火焰形状的人物描边

从零开始shader系列,做个火焰形状的人物描边

准备场景,准备一张图摆上

搞一个空shader,创建材质都给上,搞几个变量放上去,一会要用

CCEffect段


CCEffect %{
 techniques:
 - passes:
   - vert: vs
     frag: fs
     blendState:
       targets:
       - blend: true
     rasterizerState:
       cullMode: none
     properties:
       texture: {  value: white }
       noiseTex: { value: white }
       color1 : { value : [0.88,0.29,0.16,1.], editor: { type: "color" } }
       color2 : { value : [0.96,0.92,0.45,1.], editor: { type: "color" } }
       speed1 : { value : [1.0,1.0,1.0,1.0,] }
       speed2 : { value : [1.0,1.0,1.0,1.0,] }
}%


fs代码段

CCProgram fs %{
precision mediump float;

uniform sampler2D texture;
 
uniform sampler2D noiseTex;
uniform sampler2D fireTex;

uniform Constants {
  vec4 color1;
  vec4 color2;
  vec4 speed1;
  vec4 speed2;
};

varying mediump vec2 v_uv0;
varying lowp vec4 v_color;

#include <cc-global>

// 先不要管这里的参数和函数名,备用的,先占位
vec4 fragFire(vec2 uv,vec4 mc,vec2 move,vec2 offmul){
  vec4 color = vec4(vec3(0.),1.);

  return color;
}


void main() {
    float time = cc_time.x;
    vec2 uv = v_uv0;
	
	// 先不要管这里的参数和函数名,备用的,先占位
    vec4 f1 = fragFire(uv,color1,vec2(0.),vec2(0.));

    vec4 colorfire = vec4(f1);
    
    gl_FragColor = colorfire;
  }
}%

好了,图黑了!
在这里插入图片描述

做一个描边先

vec4 fragFire(vec2 uv,vec4 mc,vec2 move,vec2 offmul){
  vec4 color = vec4(vec3(0.),1.);
	
  // 图片取样
  vec4 tex3 = texture2D(texture, uv);
  // 用传进来的颜色做一个纯色的角色图 透明度用取样取到的放大后的角色图的透明度
  color.xyz = mc.xyz;
  color.a = tex3.a;

  return color;
}


void main() {
    float time = cc_time.x;
    vec2 uv = v_uv0;

    // *.97 + 0.15 给图片做缩放同时矫正位置到中心
    // 作用是让纯色图比原图要大一点
    vec4 f1 = fragFire(uv* .97 + .015,color1,vec2(0.),vec2(0.));

    vec4 colorfire = vec4(f1);
    
    gl_FragColor = colorfire;
  }
}%

在这里插入图片描述

加一张新图放上去看下,确实是变大了哈


题外话,之前一直在试各种办法做个好看点的外发光shader,各种做法都试了,居然没想到放大一下就完了。。。

我要边缘看起来像火苗


放下噪声图

-

vec4 fragFire(vec2 uv,vec4 mc,vec2 move,vec2 offmul){
  vec4 color = vec4(vec3(0.),1.);

  // uv*6 不然噪声图纹理太粗 不像火焰的细纹理
  vec4 tex1 = texture2D(noiseTex, uv * 6.);
  // 用噪声图取样随机值 给纹理偏移
  vec2 off = tex1.xy ;
	
	// offmul 噪声图取值的缩放倍数
  vec4 tex3 = texture2D(texture, uv + off * offmul);
  
  color.xyz = mc.xyz;
  color.a = tex3.a;

  return color;
}

void main() {
    float time = cc_time.x;
    vec2 uv = v_uv0;

    // *.97 + 0.15 给图片做缩放同时矫正位置到中心
    // 修改了offmul值为vec2(0.,0.03)
    // offmul.x = 0 所以x轴方向不加扰动,制作y轴效果
    vec4 f1 = fragFire(uv* .97 + .015,color1,vec2(0.),vec2(0.,0.03));

    vec4 colorfire = vec4(f1);
    
    gl_FragColor = colorfire;
  }
}%

在这里插入图片描述

一层不好看,再来一层

void main() {
    float time = cc_time.x;
    vec2 uv = v_uv0;

    // *.97 + 0.15 给图片做缩放同时矫正位置到中心
    vec4 f1 = fragFire(uv* .97 + .015,color1,vec2(0.),vec2(0.,0.03));
	// 第二层缩放*99 和第一层大小不一致,noise缩放也不一致,所以两层描边的大小是不一样的
    vec4 f2 = fragFire(uv* .99 + .005,color2,vec2(0.),vec2(0.,0.015));

    vec4 color = mix(f1,f2,f2.a);
    
    float a = f1.a + f2.a;

    vec4 colorfire = vec4(color.xyz,a);
    
    gl_FragColor = colorfire;
  }
}%

在这里插入图片描述

动起来

直接放最终代码了哈


CCEffect %{
  techniques:
  - passes:
    - vert: vs
      frag: fs
      blendState:
        targets:
        - blend: true
      rasterizerState:
        cullMode: none
      properties:
        texture: {  value: white }
        noiseTex: { value: white }
        color1 : { value : [0.88,0.29,0.16,1.], editor: { type: "color" } }
        color2 : { value : [0.96,0.92,0.45,1.], editor: { type: "color" } }
        speed1 : { value : [1.0,1.0,1.0,1.0,] }
        speed2 : { value : [1.0,1.0,1.0,1.0,] }
}%


CCProgram vs %{
precision highp float;

#include <cc-global>
#include <cc-local>

attribute vec3 a_position;
attribute lowp vec4 a_color;
attribute mediump vec2 a_uv0;

varying mediump vec2 v_uv0;
varying lowp vec4 v_color;
varying lowp vec4 v_wp;

 void main () {
   mat4 mvp;
   mvp = cc_matViewProj;
   v_color = a_color;
   gl_Position = mvp * vec4(a_position, 1);
   v_wp = cc_matWorld * vec4(a_position, 1);

   v_uv0 = a_uv0;
 }

}%


CCProgram fs %{
precision mediump float;

uniform sampler2D texture;
 
uniform sampler2D noiseTex;
uniform sampler2D fireTex;

uniform Constants {
  vec4 color1;
  vec4 color2;
  vec4 speed1;
  vec4 speed2;
};

varying mediump vec2 v_uv0;
varying lowp vec4 v_color;
varying lowp vec4 v_wp;

#include <cc-global>

// offmul 取样的随机数的缩放倍数
// move 火焰抖动幅度 cc_time.x * speed 时间乘速度等于距离
// mc 火焰颜色
vec4 fragFire(vec2 uv,vec4 mc,vec2 move,vec2 offmul){
  vec4 color = vec4(0.);

  // *6 不然噪声图纹理太粗 不像火焰的细纹理
  vec4 tex1 = texture2D(noiseTex, uv * 6. + move);
  // 用噪声图取样随机值 给纹理偏移
  vec2 off = tex1.xy ;
  // off的取值0-1 减去0.5 让值范围变到 -0.5-0.5 效果比之前好看点
  off -= .5;

  vec4 tex3 = texture2D(texture, uv + off * offmul);
  
  color.xyz = mc.xyz;
  color.a = tex3.a;

  return color;
}


void main() {
    vec2 uv;
    vec4 color;
    float time = cc_time.x;
    uv = v_uv0;

    // *.97 + 0.15 给图片做缩放同时矫正位置到中心
    vec4 f1 = fragFire(uv* .97 + .015,color1,time * speed1.xy,vec2(0.,0.03));
    vec4 f2 = fragFire(uv* .99 + .005,color2,time * speed2.xy,vec2(0.,0.015));

    color = mix(f1,f2,f2.a);
    float a = f1.a + f2.a;

    vec4 colorfire = vec4(color.xyz,a);

    // 直接对原图取样 也显示来 省的在创建个图盖上去了
    vec4 tex = texture2D(texture, v_uv0);

    gl_FragColor = mix(colorfire,tex,tex.a);

    // v_color 就是编辑器面板上面能调整的那个颜色 乘了之后那个颜色才有用
    gl_FragColor *= v_color;
  }
}%


 
}%


放点别的噪声图和参数效果

在这里插入图片描述

vec4 f1 = fragFire(uv* .97 + .015,color1,time * speed1.xy,vec2(0.,0.86));
vec4 f2 = fragFire(uv* .99 + .005,color2,time * speed2.xy,vec2(0.,0.43));


总之吧,噪声图和参数不一样,会出来点奇奇怪怪的东西。。

15赞

新手建议先看前置帖子

图片违规可还行

1赞

王师傅,图片违规啦。

大佬流啤,所以上面为啥有两张图显示“图片违规!” :rofl:

大佬牛蛙,虽然没学会,但是还是想看那两张图 :7:

效果不错,会打断合批呀

image 收到了csdn的提示

借一步看违规图片:smirk_cat:

违规图片私发给我研究一下技术 谢谢 :smirk:

有点好奇违规图片长啥样 :7:

我有个朋友想看看违规的图片

我就是那个朋友,直接发我吧

我二弟想看下违规图片

图片选的好 绅士少不了 :ox: :frog:

牛皮!!!!!!!!

喜欢原图 :heart_eyes:

说实话 代码看不来, 主要就是想看看图片哪里违规

2.x的shader和3.x的shader不相通吗?

需要升级材质。
看你使用的 编辑器版本

2.x 升级到 3.x
https://docs.cocos.com/creator/3.1/manual/zh/material-system/effect-2.x-to-3.0.html
3.0 升级到 3.1
https://docs.cocos.com/creator/3.1/manual/zh/material-system/Material-upgrade-documentation-for-v3.0-to-v3.1.html
3.4 升级到 3.5
https://docs.cocos.com/creator/manual/zh/material-system/effect-upgrade-documentation-for-v3.4.2-to-v3.5.html