顶点着色器的输出和片段着色器的输入保存在插值器中,对每个顶点用向量数组的方式存储
。
(OGL会对Uniform变量和插值器进行打包,打包后会更好的利用内存,所以对于uniform数量和顶点输入,输出,片段输入输出的数量在打包后不超过限制即可正常运行)。
(1) 着色器输入输出和变量类型限定符
in(默认类型),out,inout, const, invariant。
GLSL 1.4版本中attribute和varying字段都删除了,都统一使用in out或inout关键字。
其它类型限定,例如:
const
全局常量类型,编译期常量值,可以在函数内部也可以作为函数参数类型,
比直接用数据更加高效。
例如:
const int c_zero = 0;
const int c_one = 1;
invariant限定符
,强制多道渲染算法中,每道着色器渲染时计算位置完全相同(否则因为指令顺序的累积误差,多pass渲染时候,可能多次编译Shader编译器优化导致指令排列有差异,也可能前面的计算存在误差(矩阵累积变换),大多数情况下是可以接受的)在顶点和片段着色器中都声明为invariant,它可能对着色器性能产生影响,会禁用GLSL编译器所执行的优化。
例如:
invariant gl_Position;
在调试时候可以用:
#pragma STDGL invariant(all)
强制要求所有的变量都使用不变性。
(2)布局限定符
layout(location = 1)in vec3 a_color;
布局限定符是用于建立映射的,例如顶点数组属性和shader中变量之间的映射,片段输出和MRT之间的映射,使用布局限定符比glBindAttribLocation (GLuint program, GLuint index, const GLchar *name)简洁。
顶点着色器输出和片段着色器输入不能使用布局限定符(顶点输入和片段输出中才有,输出的index是用于MRT指定的,默认是0)
,且他们输入输出的变量数量也是有限制的,OES3.0上顶点着色器输入变量最大为16,片段着色器输出为15。
(3)片段着色器额外的in关键字插值限定符(和顶点着色器的out的插值限定符一样)
centroid 在打开多点采样的时候,强迫一个片段输入变量的采样位于图元像素覆盖的区域内。
smooth 以透视校正的方式插值片段输入变量。
flat 不对片段输入插值(对于所有的片段输入都是和归属的顶点一样的,就像在单调着色中一样)。
noperspective 线性插值片段变量。
例如:flat centroid in fragment;
例如:
// Vertex Shader
smooth centroid out vec3 v_color;
// Fragment shader
smooth centroid in vec3 v_color;
(4)精度限制
基础数据类型都有
lowp, mediump,highp三种类型,但不同OES实现具体位数有差异。
默认的精度都是highp。更小的精度有利于提高性能和节省电力。
为单个变量指定精度
highp vec4 position;
mediump float specular;
为后面所有的该类型指定精度。
precision highp float;
precision mediump int;
顶点着色器中没有指定精度则默认的精度是highp, 片段着色器中float没有指定精度则没有默认精度,需要自己手动指定。
顶点位置一般用highp, 颜色和照明一般用mediump.