1. GPU管道渲染流水线基本流程;


我们的图形绘制是GPU绘制的;

游戏引擎是由CPU传递数据给GPU, GPU进行绘制;

GPU绘制物体有一个标准的流程m大部分的显卡厂商的GPU;

管道渲染流水线,绘制物体的 "产线" --》开始-->输出出来;


- 顶点初始化-->模型指的是白色的框架,点组成,连成了线-->线连成了面,面连成了体--》3D物体骨架;美术建模而来,还有一些是自带的几何体;模型顶点数据从文件-->吃到内存里面-->显存里面;顶点(位置,纹理坐标,法线,切线...)


- 顶点Shader


- Tellellation曲面化-->


- 几何Shader-->


- 裁剪、投影-->


- 三角形遍历-->


-  片元着色Shader-->


- 输出2D图像


2. 为什么一个Label一个DrawCall,Label绘制的底层原理


 - 我们的Label有一个字体文件-->字模型


 - 更新我们的label内容的时候,我们的游戏引擎调用矢量字库引擎库的api,绘制我们的文字的模型,纹理贴图到Texture2D上;每一个Label生成了一个Texture2D文件(本文为小主推荐一个完全免费(开源)的、高质量的且可移植的字体引擎FreeType);


 - 我们将这个贴图调用精灵的材质+shader绘制出来;


 - 游戏引擎-->cc.Label,读取材质,给GPU装载对应的shader;


 - 游戏引擎-->传递参数给shader(Texture2D,等其它参数,世界变换矩阵,摄像机变换矩阵)-->矩形


 - 绘制出来我们的label对应的Texture2D。摄像机只是一个矩阵而已;同样的模型、材质和shader因此是1个;


3. 什么叫做DrawCall?


我们的游戏引擎,绘制游戏场景里面的所有物体,分了几个批次来绘制的,那就是多少个DrawCall;

如果一个draw call绘制超过了一个物体,那么叫做合批,合并;-->效率会搞?

- 不用重复的复制顶点数据到GPU,传递参数-->CPU性能好;


- 对GPU也好,你的显卡是由一个吞吐量? 每次绘制的时候,GPU一次最多可以处理多少个面;


- 满足哪些条件可以合批呢?


    1. Mesh(模型网格)要一致

    2. shader要一致

    3. 纹理贴图要一致


一个图集里面的所有精灵,Mesh shader纹理对象; 如果你把一个图集的精灵图片放到一起-->合并draw call

动态合批技术:

可移植的字体引擎(FreeType)。


4.如何制作渐变文字的特效(本文使用cocos creator2.3.2版本)


文字渐变.png


// 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 }
        gray_texture: { value: white }
}%
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>
  in vec4 v_color;
  #if USE_TEXTURE
  in vec2 v_uv0;
  uniform sampler2D texture;
  #endif
  #if USE_TEXTURE2
  uniform sampler2D gray_texture;
  #endif
  void main () {
    vec4 o = vec4(1, 1, 1, 1);
    #if USE_TEXTURE
    o *= texture(texture, v_uv0);
      #if CC_USE_ALPHA_ATLAS_TEXTURE
      o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;
      #endif
    #endif
    o *= v_color;
    ALPHA_TEST(o);
    float ap = o.a;
    o = texture2D(gray_texture, v_uv0 + vec2(0, 0.5));
    o.a = ap;
    gl_FragColor = o;
  }
}%


关注【游戏讲坛】微信公众号,获取最新动态!