GLSL:OpenGL Shading Language,是OpenGL的着色语言,是一种基于C语言的高级编程语言,用于描述GPU的渲染管道。

Cocos effect是基于opengl的,使用glsl语法和函数。但是经过了cocos进行封装,所以一般看不到main函数,直接写关键函数即可。点击写好的effect,在Cocos creator属性面板可以看到生成的完整代码。effect一般会有三个部分:

  1. CCEffect 声明部分
  2. CCProgram vs 顶点着色器
  3. CCProgram fs 片段着色器
    CCEffect中每个passes都需要指定顶点着色器和片段着色器,一般都是vs:vert和fs:frag两个函数。

创建使用材质与shader

  1. 创建一个shader
  2. 创建一个材质–>选择一个shader
  3. MeshRenderer–>选择一个材质,MeshRenderer–>Mesh–>MeshData模型的网格(形状)–>MeshVertexData–>MeshIndexData

cocos-shader结构

shader是代码,是算法,有数据,那shader的数据哪里来?

  1. 顶点shader数据需要从渲染管道里获取数据
  2. CPU要传递数据给顶点shader和片段shader
  3. 顶点shader的数据传递给片段shader

GLSL-顶点shader

  1. attribute:顶点属性,用于从缓冲区中读取数据,如位置、法线、颜色等。修饰的变量是从渲染管道获取的数据给顶点shader
  2. uniform:全局变量,用于向顶点着色器传递数据,如摄像机位置、光源位置、光源颜色等。修饰的变量都是CPU传递给shader的数据
  3. varying:顶点着色器输出到片段着色器的变量,用于向片段着色器传递数据。修饰的变量是顶点着色器输出到片段着色器的数据,顶点shader要定义一次,片段shader也到定义一次,才能使用一次

GLSL-片段shader

  1. varying:顶点着色器输出到片段着色器的变量,用于向片段着色器传递数据。修饰的变量是顶点着色器输出到片段着色器的数据,顶点shader要定义一次,片段shader也到定义一次,才能使用一次
  2. uniform:全局变量,用于向片段着色器传递数据,如摄像机位置、光源位置、光源颜色等。修饰的变量都是CPU传递给shader的数据
  3. texture:纹理,用于从贴图中读取数据,如贴图颜色、法线、深度等。修饰的变量是从贴图中读取的数据
  4. gl_FragColor:片段着色器输出的颜色,用于渲染到屏幕上。
shi  CCEffect %{
  techniques:
  - passes:#渲染管道,可以有多个
    - vert: vs:vert #顶点shader,入口函数名vert
      frag: fs:frag #片段shader,入口函数名frag
      blendState:#混合状态
        targets:
        - blend: true
          blendSrc: src_alpha
          blendDst: one_minus_src_alpha
          blendDstAlpha: one_minus_src_alpha
      rasterizerState:#光栅化状态
          cullMode: none        # 剔除模式(none/front/back)
          fillMode: solid       # 填充模式(solid/wireframe)
          depthBias: 0.0        # 深度偏移值
          slopeScaleDepthBias: 0.0  # 斜率缩放深度偏移
      properties:
        # 着色器中需要同步定义一个 ‘uniform center’,该属性可在编辑器的属性检查器中进行配置
        center: { value: [0.5, 0.5], editor: { tooltip: '模糊中心点' } }
        # 着色器中需要同步定义一个 ‘uniform strength’,该属性可在编辑器的属性检查器中进行配置
        strength: { value: 0.03, editor: { tooltip: '模糊强度' } }
}%

CCProgram vs %{
  precision highp float;  // precision精度声明  高highp、中mediump、低lowp

  #include <cc-global>
//attribute 渲染管道传递给你的
  in vec3 a_position;  //输入变量,三维,顶点位置数据-世界坐标
  in vec2 a_texCoord;  //输入变量,二维,顶点纹理坐标,当前顶点对应的纹理位置
  in vec4 a_color;     //输入变量,四维,顶点颜色
  in vec3 a_normal;    //输入变量,三维,顶点法线

  out vec2 v_uv0;      //输出变量,二维,纹理坐标

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

    #剪切空间坐标 = 投影矩阵 * 世界坐标
    //通过 MVP 乘以空间顶点,得到裁剪空间 (clip space) 坐标并返回
    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;// 固定返回绿色的 RGBA 色值
  }
}%
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐