Shader执行逻辑
Shader的执行是和app的drawcall相关的,一次draw call会进行一次顶点处理和片段处理,这个时候就会用一段Shader程序来代替,但是Shader程序是基于并行的顶点或像素上的,所以每个Shader程序执行的时候,都是并行处理的。并且着色器输入数据,也会为了一个完整顶点的处理或者完整像素的处理,会从非连续的显卡内存区域获得它需要的数据:
glEnableVertexAttribArray(0);
// 顶点位置数据
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
// 顶点颜色数据
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)48);
顶点Shader并行处理中的一个顶点处理会到非连续的内存里面取得一个顶点的位置和该顶点的颜色数据。
Shader处理只是图像渲染管道中开放出来可编程的片段,Shader以外的处理还是按照具体实现的图形驱动程序进行处理的(比如模型数据准备好后才进行顶点Shader, 后面硬件进行图元组装,裁剪,透视除法,视口变换,背面剔除,光栅化; 光栅化后才进行片段Shader,后面还要进行像素归属测试/ssissor/alpha/stencil/depth测试,融合,抖动,逻辑操作,掩码写入)。
Shader基础框架
所以一个Shader程序(无论是顶点还是片段)都有一个void main入口,输入用in类型指定,输出用out类型指定,所以该main函数是没有返回值的。
例如:
// Vertex Shader
#version 330
in vec4 pos;
in vec4 incolor;
uniform vec2 offset;
smooth out vec4 thecolor;
void main()
{
vec4 totalOffset = vec4(offset.x, offset.y, 0.0, 0.0);
gl_Position = pos + totalOffset;
thecolor = incolor;
}
// Fragment Shader
#version 330
smooth in vec4 thecolor;
out vec4 outputColor;
void main()
{
outputColor = thecolor;
}