threejs的GLSL源文件阅读
条评论webgl基本知识
参考webgl教程,我们知道WebGL每次绘制需要两个着色器, 一个顶点着色器(vertexShader)和一个片段着色器(fragmentShader),前者主要负责计算顶点坐标(gl_Position),后者主要计算要渲染的颜色(gl_FragColor)。
webgl使用GL Shader Language(GLSL)语法来编写着色器的代码,语法上类似于C++,运行在GPU中(所以很难调试),里面有三种变量类型:
- attribute变量是只能在vertex shader中使用的变量。
- uniform变量是外部程序传递给(vertex和fragment)shader的变量。
- varying变量是vertex和fragment shader之间做数据传递用的。
threejs本质上就是webgl的封装,使其用起来更方便。
threejs 使用自定义shader的办法
threejs(R109)使用shader一般是使用ShaderMaterial,传入vertexShader与fragmentShader来渲染,根据需要传入uniforms。
1 | // 所有顶点经过转 摄像头的正交投影转换,达到近大远小的三维效果。 |
threejs shader源代码阅读
three.js的GLSL代码一般在:three.js-dev\src\renderers\shaders\ShaderChunk\default_vertex.glsl.js
。
他们的写法是根据需要将多个GLSL拼接起来使用,结合#ifdef
来控制部分代码是否生效:
1 | //ShaderLib/cube.glsl.js |
其中的begin_vertex代码与project_vertex分别对应:1
2
3
4//begin_vertex.glsl.js
export default /* glsl */`
vec3 transformed = vec3( position );
`;1
2
3
4
5
6
7
8
9// project_vertex.glsl.js
export default /* glsl */`
vec4 mvPosition = vec4( transformed, 1.0 );
#ifdef USE_INSTANCING
mvPosition = instanceMatrix * mvPosition;
#endif
mvPosition = modelViewMatrix * mvPosition;
gl_Position = projectionMatrix * mvPosition;
`;
ShaderLib/meshphysical.glsl.js
与examples\jsm\nodes\materials\nodes\PhongNode.js
所涉及的主要代码段个人总结如下:
common.glsl.js
包含常见的通用变量与函数begin_vertex.glsl.js
一般的顶点着色器的开始代码project_vertex.glsl.js
常见的正交投影转换代码lights_physical_fragment.glsl.js
物理光的计算encodings_fragment.glsl.js
输出颜色的线性转换
涉及主要变量:
vViewPosition
摄像头的视野坐标vNormal
法向量
three.js里通过 p_uniforms.setValue
来给shader传uniform值。常见的uniform默认值在src\renderers\shaders\UniformsLib.js
可以看到:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20const UniformsLib = {
common: {
diffuse: { value: new Color( 0xffffff ) },
opacity: { value: 1.0 },
map: { value: null },
uvTransform: { value: new Matrix3() },
uv2Transform: { value: new Matrix3() },
alphaMap: { value: null },
alphaTest: { value: 0 }
},
envmap: {
envMap: { value: null },
flipEnvMap: { value: - 1 },
reflectivity: { value: 1.0 }, // basic, lambert, phong
ior: { value: 1.5 }, // standard, physical
refractionRatio: { value: 0.98 },
maxMipLevel: { value: 0 }
}
// 省略................................
}