9.3 着色器完整实例
优质
小牛编辑
129浏览
2023-12-01
着色器代码可以写在单独的文件中(顶点着色器的文件名后缀为.vs
,片元着色器的文件名后缀为.fs
),也可以在HTML文件中定义script
标签实现。通常对于较长的着色器代码,建议使用单独的文件;对于较短的着色器代码,在HTML文件中定义也是一个不错的选择。当然,从代码可维护性的角度看,本书更建议使用单独的着色器文件。
单独的着色器文件
使用单独的着色器文件,需要在javascript代码中导入着色器文件。我们假设顶点着色器定义在shader/my.vs
文件中,片元着色器定义在shader/my.fs
中。
可以使用Ajax完成导入文件的工作,而如果使用jQuery的get
函数就可以更方便地实现。
// load shader
$.get('shader/my.vs', function(vShader){
$.get('shader/my.fs', function(fShader){
// TODO
});
});
jQuery的get
函数第一个参数为文件路径,第二个参数为导入文件后的回调函数,这里我们在加载完顶点着色器后加载片元着色器。vShader
与fShader
分别为导入的着色器程序,用来构造着色器材质。
接下来,我们需要在加载完两个着色器后,新建一个THREE.ShaderMaterial
,需要传入属性vertexShader
与fragmentShader
:
$.get('shader/my.vs', function(vShader){
$.get('shader/my.fs', function(fShader){
material = new THREE.ShaderMaterial({
vertexShader: vShader,
fragementShader: fShader
});
});
});
之后可以将material
应用于需要该着色器效果的物体上。
HTML中的着色器代码
在HTML中,可以使用
<script id="vs" type="x-shader/x-vertex">
这里的内容相当于.vs文件中的内容
</script>
定义顶点着色器;使用
<script id="fs" type="x-shader/x-fragment">
这里的内容相当于.fs文件中的内容
</script>
定义片元着色器。
定义材质时的方法:
material = new THREE.ShaderMaterial({
vertexShader: document.getElementById('vs').textContent,
fragmentShader: document.getElementById('fs').textContent
});
完整实例
下面,我们通过完整的例子了解着色器的应用。
首先,我们创建一个绿色的正方体在场景中旋转,这些都是在前几章中讲解过的:
var scene = null;
var camera = null;
var renderer = null;
var cube = null;
function init() {
renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('mainCanvas')
});
scene = new THREE.Scene();
camera = new THREE.OrthographicCamera(-5, 5, 3.75, -3.75, 0.1, 100);
camera.position.set(5, 15, 25);
camera.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(camera);
var light = new THREE.DirectionalLight();
light.position.set(3, 2, 5);
scene.add(light);
cube = new THREE.Mesh(new THREE.CubeGeometry(2, 2, 2),
new THREE.MeshLambertMaterial({color: 0x00ff00}));
scene.add(cube);
draw();
}
function draw() {
cube.rotation.y += 0.01;
if (cube.rotation.y > Math.PI * 2) {
cube.rotation.y -= Math.PI * 2;
}
renderer.render(scene, camera);
requestAnimationFrame(draw);
}
然后,我们需要定义着色器代码,并导入到应用中。着色器程序参见上节,导入着色器的两种方法在本节也做了介绍。因此,最终得到的结果是: