CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)

摘要:
第二个Cocos中着色器的每个图片cc.Sprite或文本cc.Label都具有默认材质。与材质对应的效果文件包含着色器代码。有三种着色器语言:1。基于OpenGL的OpenGL ShadingLanguage,简称GLSL。Cocos使用YAML和GLSL,YAML声明控制流列表,GLSL声明实际的着色器段。CCP程序的大多数自定义着色器逻辑代码都在这里编写。在cocos中创建一个新的效果和测试材料,分别命名为TestMaterial和TestEffect。

 cocos版本:2.4.4

参考:

Cocos2D文档: 材质资源  、 Effect

Cocos3D文档:  材质 、 常用 shader 内置 Uniform

基础知识:    The Book of Shader 中文版

水友文章:    学习shader的入门笔记

                      cocos2.3 Shader编写示例

           Cocos Creator Shader Effect 系列

                  从被攻击闪白shader到相关原创整理,以及相关学习资料整理

        TheBookOfShader开始

        OpenGL shader GLSL 中文手册 

目录

一 Shader

二 Cocos中的Shader

三 学习TheBookOfShader,并在cocos中实现书中效果

一 Shader

着色器(Shader)是用来实现图像渲染的,用来替代固定渲染管线的可编辑程序。其中Vertex Shader(顶点着色器)主要负责顶点的几何关系等的运算,Pixel Shader(像素着色器)主要负责片源颜色等的计算。

着色器替代了传统的固定渲染管线,可以实现3D图形学计算中的相关计算,由于其可编辑性,可以实现各种各样的图像效果而不用受显卡的固定渲染管线限制。

理解上Shader是一段代码,通过编程告诉GPU如何绘制顶点和颜色,从而实现各种各样的图像效果,例如彩色字体、按钮置灰、图片马赛克、描边、动态让图片扭动起来等等。

二  Cocos中的Shader

每张图片cc.Sprite或文本cc.Label都有一个默认Materials材质。

材质资源可以用来控制渲染组件在场景中的视觉效果。简单来说材质就是用来指定物体表面的特性,如颜色、光亮程度、自发光度以及不透明度等。

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第1张

材质对应的Effect文件,里面就是shader代码

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第2张

Shader语言有3种:

1.基于OpenGL的OpenGL Shading Language,简称GLSL。

2.基于DirectX的High Level Shading Language,简称HLSL。

3. NVIDIA公司的C for Graphic,简称Cg语言。

Cocos采用的是YAML和GLSL,YAML声明控制流程清单,GLSL声明实际的shader片段。具体查看Effect语法

builtin-2d-sprite.effect完整代码如下:

CCEffect编写声明

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第3张

其中properties可以自定义外部变量,例如自定义颜色变量,定义后可在属性面板选择颜色。

CCPrograms vs

获取顶点数据,向下一个渲染管道传递数据。

 CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第4张

 这段代码之后基本不用动,主要理解是两个变量:

out vec4 v_color; //当前node节点颜色。

out vec2 v_uv0;   //坐标,原点在左上角,xy轴坐标分别通过v_uv0.x 和v_uv0.y获取。

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第5张

 CCProgram fs

大部分自定义shader逻辑代码写在这里面。下面的代码对cocos的图片进行采样,然后和node节点颜色混合后输出,实现普通builtin-2d-sprite效果。

CCTexture(texture,v_uv0,o); //对图片进行采样,颜色存储在o里

o *= v_color;                          // o和node节点颜色v_color进行混合

gl_FragColor = i;                   //输出颜色

 CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第6张

那么问题来了,里面的其它变量都是什么意思...都有哪些内置函数和变量,cocosAPI搜索根本查不到这些....哪里看这些API的文档...

Cocos Effect语法:Effect语法

Cocos常用 shader 内置 Uniform:内置Uniform

GLSL语法:OpenGL shader GLSL 中文手册

三 学习TheBookOfShader,并在cocos中实现书中效果

 打开 The Book of Shader 中文版 ,开始学习。

边看教程边写例子。在cocos中新建测试用的Effect和Material,分别命名为TestMaterial和TestEffect。

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第7张

选择TestMaterial,设置Effect属性为TestEffect

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第8张

选择任意一张图片,赋值Materials属性为TestMaterial

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第9张

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第10张

在资源管理器,选择这个图片,将packable的勾去掉。如果这个打包的勾被勾选,则shader在发布后出问题。

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第11张

双击TestEffect,则可以在vs code打开并编辑TestEffect文件,但是文件都是白字,没有语法高亮。需要安装一个插件来支持代码高亮。

vscode中安装Cocos Effect插件

这个插件可以高亮effect文件,方便阅读代码。选择查看-扩展

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第12张

搜索Cocos Effect并安装

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第13张

安装后代码有了颜色

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第14张

第一个例子,将图片变成红色

修改TestEffect的CCProgram fs的最后一行gl_FragColor=o改为gl_FragColor = vec4(1.0,0,1.0,1.0)

vec4的4个参数分别代表颜色通道(red, green,blue,alpha),颜色值是范围0-1,注意不要写整数1,要写浮点数1.0。

CCProgram fs %{
  precision highp float;
  
  #include <alpha-test>
  #include <texture>
  #include <cc-global>
  #include <cc-local>

  in vec4 v_color;
  #if USE_TEXTURE
   in vec2 v_uv0;
   uniform sampler2D texture;
  #endif
  
  uniform color{
    vec4 imgColor;
  };

 
  void main () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
      CCTexture(texture, v_uv0, o);
    #endif

    o *= v_color;

    ALPHA_TEST(o); 

    gl_FragColor = vec4(1.0,0,1.0,1.0)*o; 
  } 
}%

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第15张

关于颜色值vec4的访问,下图中访问方式是等效的。

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第16张

 第二个例子,图片红色闪烁

cc_time.x就是书里的u_time,表示游戏的运行时间。o.r就是红色通道值, abs(sin(cc_time.x))就是利用余弦函数,随着游戏时间增加,红色通道值一直在0-1之间变化,从而形成了闪烁效果。

  void main () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
      CCTexture(texture, v_uv0, o);
    #endif

    o *= v_color;

    ALPHA_TEST(o); 

    o.r = abs(sin(cc_time.x));
    gl_FragColor = o;
  }

 CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第17张

  

 第三个例子,渐变色

v_uv0就是书中的gl_FragCoord.xy/u_resolution,表示坐标。

v_uv0.x和v_uv0.y值是从0-1变化的,gl_FragColor = vec4(v_uv0.x,v_uv0.y,1.0,1.0)表示红色和绿色通道值从左上角到右下角由0-1变化。

  void main () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
      CCTexture(texture, v_uv0, o);
    #endif

    o *= v_color;

    ALPHA_TEST(o); 

    gl_FragColor = vec4(v_uv0.x,v_uv0.y,1.0,1.0);
  } 

因为没有计算cocos图片颜色o,所以这里是单纯的颜色值。

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第18张

gl_FragColor = vec4(v_uv0.x,v_uv0.y,1.0,1.0)理解起来很抽象,我们代入几个值到公式里看看就知道规律了。

x坐标                y坐标                颜色值                            结果

v_uv0.x=0        v_uv0.y=0         vec4(0,0,1.0,1.0)             (0,0)表示左上角,颜色值蓝色

v_uv0.x = 1.0   v_uv0.y=1.0      vec4(1.0,1.0,1.0,1.0)       (1,1)表示右下角,颜色值白色

v_uv0.x = 0.5   v_uv0.y=0.5      vec4(0.5,0.5,1.0,1.0)       (0.5,0.5)表示中间,颜色值淡紫色

 CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第19张

渐变色带图,这里计算了图片本身的颜色o

  void main () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
      CCTexture(texture, v_uv0, o);
    #endif

    o *= v_color;

    ALPHA_TEST(o); 

    gl_FragColor = vec4(v_uv0.x*o.r,v_uv0.y*o.g,o.b,o.a);
  } 

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第20张

 第四个例子,画一条绿线

smoothstep(起始值A,结束值B,插值t)  ,参考cocos里的cc.Vec3.lerp函数,大致smoothstep(A,B,t)返回值应该是A + (B-A)*t 

  float plot(vec2 st) {    
    return smoothstep(0.02, 0.0, abs(st.y - st.x));
  }
 
  void main () {

    float y = v_uv0.x;

    vec3 color = vec3(y);

    // Plot a line
    float pct = plot(v_uv0);
    color = (1.0-pct)*color+pct*vec3(0.0,1.0,0.0);
    gl_FragColor = vec4(color,1.0);
  } 

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第21张

 第五个例子,圆

distance计算距离, distance(v_uv0, vec2(0.5))得到坐标离图片中心点的距离,距离越远值越大,越接近白色;距离越近值越小,越接近黑色。

  void main () {

    float pct = 0.0;

    pct = distance(v_uv0,vec2(0.5));

    vec3 color = vec3(pct);

    gl_FragColor = vec4( color, 1.0 );
  } 

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第22张

画圆形,dot(x,y)返回x,y的点积。

  float circle(in vec2 _st, in float _radius){
    vec2 dist = _st-vec2(0.5);
	  return 1.-smoothstep(_radius-(_radius*0.01),
                         _radius+(_radius*0.01),
                         dot(dist,dist)*4.0);
  }
 
  void main () {
    vec3 color = vec3(circle(v_uv0,0.25));
    gl_FragColor = vec4(color,1.0);
  } 

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第23张

 第六个例子 画长方形

step(阙值A,检测值B)   B<A返回0.0,B>=A返回1.0。

下面只画了左和上,left在x<0.1的地方是0,其它地方1;bottom在y<0.1的地方是0,其它地方1。left*bottom有&&的作用,只有x和y都=1结果才是1。

所以只有满足x>=0.1&&y>=0.1的地方才会是1白色值。

  void main () {
    vec3 color = vec3(0.0);
    float left = step(0.1,v_uv0.x);
    float top = step(0.1,v_uv0.y);
    color = vec3( left * top );
    gl_FragColor = vec4(color,1.0);
  } 

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第24张

下面画右和下,只有x<=0.9 && y<=0.9的地方是1白色。

  void main () {
    vec3 color2 = vec3(0.0);
    float right = step(0.1,1.0-v_uv0.x);
    float bottom = step(0.1,1.0-v_uv0.y);
    color2 = vec3( right * bottom );
    gl_FragColor = vec4(color2,1.0);
  } 

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第25张

代码合起来

  void main () {
    vec3 color = vec3(0.0);
    float left = step(0.1,v_uv0.x);
    float top = step(0.1,v_uv0.y);
    color = vec3( left * top );

    vec3 color2 = vec3(0.0);
    float right = step(0.1,1.0-v_uv0.x);
    float bottom = step(0.1,1.0-v_uv0.y);
    color2 = vec3( right * bottom );
    gl_FragColor = vec4(color*color2,1.0);
  } 

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第26张

 第7个例子  从上到下四色渐变

  void main () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
      CCTexture(texture, v_uv0, o);
    #endif

    o *= v_color;

    ALPHA_TEST(o); 

    vec4 color1 = vec4(1,0,0,1);
    vec4 color2 = vec4(0,1,0,1);
    vec4 color3 = vec4(0,0,1,1);
    vec4 color4 = vec4(1,1,1,1);  
    vec4 resultColor = vec4(1,1,1,1);
    if(v_uv0.y < 0.33){
      resultColor = vec4(color1.x + (color2.x - color1.x)*v_uv0.y*3.0, color1.y + (color2.y - color1.y)*v_uv0.y*3.0, color1.z + (color2.z - color1.z)*v_uv0.y*3.0, 1.0);
    }else if(v_uv0.y < 0.66){
      resultColor = vec4(color2.x + (color3.x - color2.x)*(v_uv0.y-0.33)*3.0, color2.y + (color3.y - color2.y)*(v_uv0.y-0.33)*3.0, color2.z + (color3.z - color2.z)*(v_uv0.y-0.33)*3.0, 1.0);
    }else if(v_uv0.y <= 1.0){
      resultColor = vec4(color3.x + (color4.x - color3.x)*(v_uv0.y-0.66)*3.0, color3.y + (color4.y - color3.y)*(v_uv0.y-0.66)*3.0, color3.z + (color4.z - color3.z)*(v_uv0.y-0.66)*3.0, 1.0);
    }
    gl_FragColor = resultColor*o;
  } 

  

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第27张

第8个例子 设置effect属性

 定义个imgColor属性

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第28张

定义变量

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第29张

在TestMaterial属性检查器中看一看到属性,并可以选择颜色

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第30张

 将imgColor赋予图片

  void main () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
      CCTexture(texture, v_uv0, o);
    #endif

    o *= v_color;

    ALPHA_TEST(o);

    gl_FragColor = o*imgColor;
  }

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第31张

第9个例子 攻击闪白效果

复制cocos的sprite和spine的普通effect

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第32张

修改复制的sprite effect,高亮图片的颜色

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第33张

修改复制的spine effect,高亮图片颜色 

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第34张

将修改后的高亮effect赋予图片,效果是这样的  

CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第35张

点击一个图片或spine、db时,切换高亮effect持续0.1秒,然后恢复正常的effect,就可以做出攻击闪白的效果

const { ccclass, property } = cc._decorator;

@ccclass
export default class AttackFlash extends cc.Component {

    @property(dragonBones.ArmatureDisplay)  //龙骨怪物
    monster_db: dragonBones.ArmatureDisplay = null;

    @property(sp.Skeleton)     //spine怪物
    monster_spine: sp.Skeleton = null;

    @property(cc.Sprite)    //普通图片怪物
    monster_img: cc.Sprite = null;

    @property(cc.Material)  //sprite被攻击闪白材质
    mat_attacked_sprite: cc.Material = null;

    @property(cc.Material)  //spine被攻击闪白材质
    mat_attacked_spine: cc.Material = null;

    @property(cc.Material)  //普通材质
    mat_normal: cc.Material = null;

    @property(cc.Material)  //普通spine材质
    mat_normal_spine: cc.Material = null;

    onLoad() {
        this.monster_db.node.on(cc.Node.EventType.TOUCH_END, this.onMonsterDbTap, this);
        this.monster_spine.node.on(cc.Node.EventType.TOUCH_END, this.onMonsterSpineTap, this);
        this.monster_img.node.on(cc.Node.EventType.TOUCH_END, this.onMonsterImgTap, this);
    }

    //点击dragonBones,切换高亮material
    onMonsterDbTap() {
        this.monster_db.setMaterial(0, this.mat_attacked_sprite);
        this.unschedule(this.flashDb);
        this.schedule(this.flashDb, 0.1);
    }

    //计时结束,切换普通material
    flashDb() {
        this.monster_db.setMaterial(0, this.mat_normal);
    }

    //点击spine,切换高亮material
    onMonsterSpineTap() {
        this.monster_spine.setMaterial(0, this.mat_attacked_spine);
        this.unschedule(this.flashSpine);
        this.schedule(this.flashSpine, 0.1);
    }

    //计时结束,切换普通material
    flashSpine() {
        this.monster_spine.setMaterial(0, this.mat_normal_spine);
    }

    //点击图片,切换高亮material
    onMonsterImgTap() {
        this.monster_img.setMaterial(0, this.mat_attacked_sprite);
        this.unschedule(this.flashImg);
        this.schedule(this.flashImg, 0.1);
    }

    //计时结束,切换普通material
    flashImg() {
        this.monster_img.setMaterial(0, this.mat_normal);
    }
}

  

 CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)第36张 

  

  

  

免责声明:文章转载自《CocosCreator Shader笔记 (TheBookOfShader、渐变色、攻击闪白特效)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Xshell批量导入IP地址brew安装指定版本的软件下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Unity Shader之模板测试

Unity Shader之模板测试一沙一世界,一花一天堂 一、Stencil testing   渲染管线     当片段着色器处理完一个片段之后,模板测试(Stencil Test)会开始执行,和深度测试一样,它也可能会丢弃片段。接下来,被保留的片段会进入深度测试,它可能会丢弃更多的片段。模板测试是根据又一个缓冲来进行的,它叫做模板缓...

Unity Shader 颜色处理(亮度,饱和度 ,对比度)

Unity Shader 颜色处理(亮度,饱和度 ,对比度) 基本概念 亮度 图像中RGB值的大小,RGB各个值越大,那么亮度越亮,越小,亮度越暗。比如我们要增加亮度,那么直接增加RGB值即可 饱和度 饱和度可定义为彩度除以明度,与彩度同样表征彩色偏离同亮度灰色的程度。注意,与彩度完全不是同一个概念。但由于其和彩度决定的是出现在人眼里的同一个效果,所以才会...

【Unity】经验汇总

移动平台使用顶点动画或UV动画的问题 5.4.2 在开发中,游戏打包到移动平台常出现的两种问题: 1.顶点动画:卡顿,动画变得生硬。 2.UV动画:贴图马赛克,模糊。 在实际问题解决中发现,导致这种问题的一般都是精度问题,移动平台开发针对大量性能不一的GPU。各种无法预料的问题。 很多效果在PC上的模拟器正常,打包到安卓还有ios就会出现各种奇怪的问题。...

C# 自定义弹窗提醒

classShaderBox { privateForm _shader; privateForm _parent; privateForm _child; publicShaderBox(Form parent, Form child) {...

cocos2d环境搭建

cocos2d是一个开源免费的Python 2D游戏引擎,至于iphone上面的cocos2d-iphone在代码的结构上基本与这个一样,不过cocos2d-iphone因为收到iphone开发者的积极追捧,而更新频繁,功能越来越强大。而cocos2d好像已经停止更新,最后一个release版本是0.4rc0 在官网也有cocos2d的环境搭建,不过写的太...

[原] OpenGL ES 学习笔记 (一)

1.OpenGL ES 的坐标系在屏幕上的分布 OpenGL ES 的坐标系{x, y, z} 通过图片的三维坐标系可以知道: - 它是一个三维坐标系 {x, y, z} - 三维坐标中心在正方体的几何中心 {0, 0, 0} - 整个坐标系是 [0, 1] 的点,也就是说 OpenGL 中只支持 0 ~ 1 的点 (这里所讲的 0 和 1 ,最好理...