顶点着色器和片元着色器
本文是WebGL教程(电子书)的2.8节内容
WebGL的着色器代码分为顶点着色器代码和片元着色器代码两部分,顶点着色器代码会在GPU的顶点着色器单元执行,片元着色器代码会在GPU的片元着色器单元执行,在WebGL渲染管线流程中,或者说GPU的渲染流程中,顶点着色器代码先执行处理顶点,得到一系列片元,然后再执行片元着色器代码处理片元。
main()
函数
顶点着色器和片元着色器代码都有一个唯一的主函数main()
,attribute、varying和uniform类型的变量需要在main函数之外声明,在main函数中通常编写,逐片元或逐顶点处理的代码。
// attribute、varying和uniform关键字声明变量的位置
void main(){
...
// 顶点着色代码或者片元着色器代码
...
}
着色器数据传递
javascript可以通过WebGL相关的API把一些数据传递给顶点着色器和片元着色器。
在着色器中通过attribute和uniform关键字声明的变量,需要通过javascript代码传递相关的数据。比如通过关键字attribute声明的顶点位置坐标数据,可以通过javascript调用WebGL相关API传递顶点数据。
着色器编写形式
顶点着色器、片元着色器代码在javascript代码中以字符串的形式存在,javascript会通过调用相关WebGL API编译处理着色器代码,然后在CPU着色器单元执行。
在javascript语言中以字符串的形式编写着色器代码比较麻烦,可以在div元素中编写着色器代码,然后通过元素的.innerText
属性返回着色器代码字符串即可。
WebGL着色器代码在javascript以字符串的形式存在。
//顶点着色器源码
var vertexShaderSource = '' +
'void main(){' +
//给内置变量gl_PointSize赋值像素大小
' gl_PointSize=20.0;' +
//顶点位置,位于坐标原点
' gl_Position =vec4(0.0,0.0,0.0,1.0);' +
'}';
为了方便,可以把着色器代码放在script标签中编写。
<!-- 顶点着色器源码 -->
<script id="vertexShader" type="x-shader/x-vertex">
void main() {
//给内置变量gl_PointSize赋值像素大小
gl_PointSize=20.0;
//顶点位置,位于坐标原点
gl_Position =vec4(0.0,0.0,0.0,1.0);
}
</script>
通过元素的.innerText
属性以字符串形式获得script标签中的WebGL着色器代码
//顶点着色器源码
var vertexShaderSource = document.getElementById('vertexShader').innerText;
//片元着色器源码
var fragShaderSource = document.getElementById('fragmentShader').innerText;
javascript调用相关的WebGL API编译处理着色器代码
//创建顶点着色器对象
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
//创建片元着色器对象
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
//引入顶点、片元着色器源代码
gl.shaderSource(vertexShader,vertexShaderSource);
gl.shaderSource(fragmentShader,fragmentShaderSource);
//编译顶点、片元着色器
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);