定义

渲染(Rendering)就是指将你做的模型数据呈现在屏幕上的过程。

着色器(Shader)就是屏幕上呈现画面之前的最后一步。它可以用来对先前渲染结果做修改,包括对颜色、位置等等信息的修改,甚至可以对先前渲染的结果做后处理,实现高级的渲染效果。

分类

着色器通常分为:几何着色器(Geometry Shader)、顶点着色器(Vertex Shader)、片元着色器(Fragment Shader)等。

由于WebGL是基于OpenGL ES 2.0的,所以,它只支持 顶点着色器 和 片元着色器。

顶点着色器

顶点”指的是Mesh中的顶点,对于每个顶点调用一次。

可以修改顶点的位置或颜色等信息,然后传入片元着色器。

片元着色器

片元”是由给定的”顶点”计算后得到的图形里所有的点组成的。

片元着色器特别适合用来做图像后处理。

Three.js与着色器

有上述描述可以看出,并不是在所有应用中都需要着色器。

但是WebGL要求程序编写者必须定义着色器(即使你只希望使用默认的渲染方法)。对于不了解图形学的开发者来说,这并不容易。

对此,Three.js友好地允许了不定义着色器,即采用默认的方法渲染。

着色器限定符(Qualifier)

  • const:常量

  • uniform:它表示每个顶点/片元对应相同的值。(比如,一个点光源的位置。)既可以传入顶点着色器,也可以传入片元着色器。

  • attribute:从js代码传递到顶点着色器中,每个顶点可以对应不同的值。(比如每个顶点都具有一个颜色。)attribute变量和顶点的关系是一一对应的。

  • varying:从顶点着色器中定义,传入给片元着色器的变量。

    为了确保这点,我们需要确保在两个着色器中变量的类型和命名完全一致。

    一个经典的应用是法线向量,因为在计算光照的时候需要用到法线。

HelloWorld

着色器简单创建示例

**注意:首先,着色器是一段在GPU中执行的接近C语言的代码,它需要main方法!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* Example:一个最简单的顶点着色器。
* 每个顶点坐标乘以模型视图矩阵在乘以投影矩阵
* 获得在二维屏幕上的坐标
*/
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}

/**
* Example:一个最简单的片元着色器。
* 将任意一个像元色设置为粉红(注意颜色参数为float类型,即需要使用0.0)
*/
void main() {
gl_FragColor = vec4(
1.0, // R
0.0, // G
1.0, // B
1.0 // A
);
}

在HTML中使用着色器

  1. 着色器创建代码可以写在单独的文件中(顶点着色器后缀为.vs;片元着色器后缀为.fs)

    使用Ajax完成文件的导入(这里使用了JQuery的get()方法)。

1
2
3
4
5
6
7
8
9
10
//导入shader
$.get('shader/my.vs', function(vShader){
$.get('shader/my.fs', function(fShader){
//把顶点和片元传入材质
meterial = new THREE.ShaderMeterial({
vertexShader: vShader,
fragmentShader: fShader
});
});
});
  1. 也可以在HTML文件中使用script标签创建着色器
1
2
3
4
5
6
7
8
9
10
11
12
<script id="vs" type="x-shader/x-vertex">
//这里的内容相当于.vs中的内容(顶点着色器)
</script>
<script id="fs" type="x-shader/x-fragment">
//这里的内容相当于.fs中的内容(片元着色器)
</script>

//材质定义
meterial = new THREE.ShaderMeterial({
vertexShader: document.getElementById('vs').textContent,
fragementShader: document.getElementById('fs').textContent
});