Cocos effect基本知识

2021-12-08  本文已影响0人  魂狩

注:此处所说Cocos creator版本为3.X,和其他版本会有区别。
Cocos effect是基于opengl的,使用glsl语法和函数。但是经过了cocos进行封装,所以一般看不到main函数,直接写关键函数即可。点击写好的effect,在Cocos creator属性面板可以看到生成的完整代码。

effect一般会有三个部分:

声明部分可以参考官方文档,这部分文档还算全面,在此就不再赘述。下面主要介绍顶点着色器。

顶点着色器有2个参数,a_positiona_color。如果有纹理的话,还会多个a_texCoord参数。a_position是世界坐标,a_color是设定的渲染颜色(如果是sprite,可以看到属性面板有个color属性,就是这个),a_texCoord是当前点对应纹理的位置。
一般来说,世界坐标是无法直接使用的,需要转换成视图投影(你可以理解成,世界坐标需要转换成摄像头坐标,摄像头坐标的(0,0)代表屏幕中间。ccc是这么定的。)我们需要引用#include <cc-global>,得到视图投影矩阵cc_matViewProj,返回cc_matViewProj * pos即可完成顶点着色器。
注意:这是2D情况,3D还需要引用#include <cc-local>得到模型空间转世界空间矩阵cc_matWorld,再乘以这个。而2D情况下不能引用这个文件,否则会报错。

片段着色器是核心部分,一般要做什么效果都要在这里写。如果只是单纯的显示图片,return texture(cc_spriteTexture, uv);即可。texture函数会把图片当前位置的颜色返回出来,提供给片段着色器完成渲染。其他更复杂的处理就看后续学习了。

下面是基于 陈皮皮写的某个effect进行适配的示例,原始文件在这里

CCEffect %{
  techniques:
  - passes:
    - vert: vs:vert
      frag: fs:frag
      blendState:
        targets:
        - blend: true
          blendSrc: src_alpha
          blendDst: one_minus_src_alpha
          blendDstAlpha: one_minus_src_alpha
      rasterizerState:
        cullMode: none
      properties:
        center: { value: [0.5, 0.5], editor: { tooltip: '模糊中心点' } }
        strength: { value: 0.03, editor: { tooltip: '模糊强度' } }
}%

CCProgram vs %{
  precision highp float;

  #include <cc-global>

  in vec3 a_position;
  in vec2 a_texCoord;
  in vec4 a_color;

  out vec2 v_uv0;

  vec4 vert () {
    vec4 pos = vec4(a_position, 1);

    pos = cc_matViewProj * pos;

    v_uv0 = a_texCoord;

    return pos;
  }
}%


CCProgram fs %{
  precision highp float;
  in vec2 v_uv0;
    #pragma builtin(local)
    layout(set = 2, binding = 10) uniform sampler2D cc_spriteTexture;

//定义文件里写的属性可以这样获取
  uniform Properties {
    vec2 center;
    float strength;
  };

  // 获取径向模糊颜色
  vec4 getRadialBlurColor(vec2 coord) {
      // 偏移
        vec2 offset = coord.xy - center;
      // 采样次数
      const int samples = 10;
      // 强度
      float perStrength = strength / float(samples - 1);
      // 采样
      vec4 color = vec4(0.0);
      for(int i = 0; i < samples; i++) {
          vec2 uv = offset * (1.0 + (float(i) * perStrength)) + center;
          color += texture(cc_spriteTexture, uv);
      }
      color /= float(samples);
      // 完成
      return color;
  }

  vec4 frag () {
    vec4 o = vec4(1, 1, 1, 1);
    o *= getRadialBlurColor(v_uv0);
    return o;
  }
}%
上一篇下一篇

猜你喜欢

热点阅读