GPU管道渲染流水线基本流程;
我们的图形绘制是GPU绘制的;
游戏引擎是由CPU传递数据给GPU, GPU进行绘制;
GPU绘制物体有一个标准的流程m大部分的显卡厂商的GPU;
管道渲染流水线,绘制物体的 “产线” --》开始–>输出出来;
-
顶点初始化–>模型指的是白色的框架,点组成,连成了线–>线连成了面,面连成了体–》3D物体骨架;美术建模而来,还有一些是自带的几何体;模型顶点数据从文件–>吃到内存里面–>显存里面;顶点(位置,纹理坐标,法线,切线…)
-
顶点Shader
-
Tellellation曲面化–>
-
几何Shader–>
-
裁剪、投影–>
-
三角形遍历–>
-
片元着色Shader–>
-
输出2D图像
为什么一个Label一个DrawCall,Label绘制的底层原理
- 我们的Label有一个字体文件–>字模型
- 更新我们的label内容的时候,我们的游戏引擎调用矢量字库引擎库的api,绘制我们的文字的模型,纹理贴图到Texture2D上;每一个Label生成了一个Texture2D文件(本文为小主推荐一个完全免费(开源)的、高质量的且可移植的字体引擎FreeType);
- 我们将这个贴图调用精灵的材质+shader绘制出来;
- 游戏引擎–>cc.Label,读取材质,给GPU装载对应的shader;
- 游戏引擎–>传递参数给shader(Texture2D,等其它参数,世界变换矩阵,摄像机变换矩阵)–>矩形
- 绘制出来我们的label对应的Texture2D。摄像机只是一个矩阵而已;同样的模型、材质和shader因此是1个;
什么叫做DrawCall?
我们的游戏引擎,绘制游戏场景里面的所有物体,分了几个批次来绘制的,那就是多少个DrawCall;
如果一个draw call绘制超过了一个物体,那么叫做合批,合并;–>效率会搞?
- 不用重复的复制顶点数据到GPU,传递参数–>CPU性能好;
- 对GPU也好,你的显卡是由一个吞吐量? 每次绘制的时候,GPU一次最多可以处理多少个面;
- 满足哪些条件可以合批呢?
- Mesh(模型网格)要一致
- shader要一致
- 纹理贴图要一致
一个图集里面的所有精灵,Mesh shader纹理对象; 如果你把一个图集的精灵图片放到一起–>合并draw call
动态合批技术:
可移植的字体引擎(FreeType)。
如何制作渐变文字的特效(本文使用cocos creator2.3.2版本)

// 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;
}
}%
关注【游戏讲坛】微信公众号,获取最新动态!
