毕业之后就习惯了买正版书,两年多的时间估计买了四五千元的书了吧。书中自有黄金屋还是有道理的,不过现代社会,这个书是指海量的书。
《Three.js开发指南》这本书晚上刚到货,大概的翻了三分之一,感觉没什么难度,因为之前有Unity3D和Revit二次开发的基础,另外也学了些Opengl,这部分看一眼就明白是怎么回事。所以图形图像学才是这类软件的基础。
现阶段只求知识的量,并未求质,博客也一样,都没有什么时间去整理,排版也懒得搞,后面到了一定的境界应该就会注重这些。
好了,就直接开始这三分之一部分的内容。
1、首先用什么编译器来开始Webgl?
我觉得还是Visual Studio最好,直接新建项目ASP.NET web应用程序,这样就免了配置web服务器的烦恼,另外我也习惯了用Visual Studio。然后运行Webgl的浏览器自然是Chrome了。
2、创建第一个三维场景
就着上一篇博客的框架修改:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Three框架</title> <script src="js/three.js"></script> <script src="js/stats.js"></script> <script src="js/Tween.js"></script> <style type="text/css"> div#canvas-frame { border: none; cursor: pointer; width: 100%; height: 600px; background-color: #EEEEEE; } </style> <script> function initTween() { new TWEEN.Tween(mesh.position) .to({ x: -400 }, 3000).repeat(Infinity).start(); } var renderer; var stats; function initThree() { width = document.getElementById('canvas-frame').clientWidth; height = document.getElementById('canvas-frame').clientHeight; renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(width, height); document.getElementById('canvas-frame').appendChild(renderer.domElement); renderer.setClearColor(0xFFFFFF, 1.0); renderer.shadowMapEnabled = true; stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.getElementById('canvas-frame').appendChild(stats.domElement); } var camera; function initCamera() { camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000); camera.position.x = 600; camera.position.y = 0; camera.position.z = 600; camera.up.x = 0; camera.up.y = 1; camera.up.z = 0; camera.lookAt(0,0,0); } var scene; function initScene() { scene = new THREE.Scene(); } var light; function initLight() { light = new THREE.PointLight(0x00FF00); light.position.set(0, 0, 300); light.castShadow = true; scene.add(light); } var cube; var mesh; var mesh2; var mesh3; function initObject() { var geometry = new THREE.CubeGeometry(100, 100, 100); var material = new THREE.MeshPhongMaterial({ map: THREE.ImageUtils.loadTexture('textures/a.jpg') }); mesh = new THREE.Mesh(geometry, material); mesh.position = new THREE.Vector3(0, 0, 300); mesh.castShadow = true; scene.add(mesh); var geometry2 = new THREE.PlaneGeometry(600, 200, 1,1); var material2 = new THREE.MeshPhongMaterial({ map: THREE.ImageUtils.loadTexture('textures/a.jpg') }); mesh2 = new THREE.Mesh(geometry2, material2); mesh2.position.set(200, 0, -100); mesh2.receiveShadow = true; scene.add(mesh2); var geometry3 = new THREE.SphereGeometry(100,20,20); var material3 = new THREE.MeshLambertMaterial({ color: 0xFFFFFF }); var mesh3 = new THREE.Mesh(geometry3, material3); mesh3.position.set(100, -150, 200); mesh3.castShadow = true; scene.add(mesh3); } function threeStart() { initThree(); initCamera(); initScene(); initLight(); initObject(); animation(); //initTween(); } function animation() { mesh.rotation.x += 0.1; mesh.rotation.y += 0.1; //mesh2.position.x += 10; renderer.render(scene, camera); requestAnimationFrame(animation); stats.update(); //TWEEN.update(); } </script> </head> <body onload="threeStart();"> <div id="canvas-frame"></div> </body> </html>
比较丑,但是关键点出来了。
1)通过以下几行代码增加了光源和阴影的效果 :
mesh.castShadow = true;
mesh2.receiveShadow = true;
mesh3.castShadow = true;
light.castShadow = true;
renderer.shadowMapEnabled = true;
2)创建几何没什么特别的,这里材料用上MeshLambertMaterial和MeshPhongMaterial这两种材料,这样会对光源产生反应。
3、添加GUI
添加GUI用dat.gui.js这个库。
其中关键语句:
controls = new function () {
this.rotationSpeed = 0.1;
} //定义参数
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed', 0, 0.5); //参数与GUI关联起来
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Three框架</title> <script src="js/three.js"></script> <script src="js/stats.js"></script> <script src="js/Tween.js"></script> <script src="js/dat.gui.js"></script> <style type="text/css"> div#canvas-frame { border: none; cursor: pointer; width: 100%; height: 600px; background-color: #EEEEEE; } </style> <script> function initTween() { new TWEEN.Tween(mesh.position) .to({ x: -400 }, 3000).repeat(Infinity).start(); } var controls; var renderer; var stats; function initThree() { width = document.getElementById('canvas-frame').clientWidth; height = document.getElementById('canvas-frame').clientHeight; renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(width, height); document.getElementById('canvas-frame').appendChild(renderer.domElement); renderer.setClearColor(0xFFFFFF, 1.0); stats = new Stats(); stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.getElementById('canvas-frame').appendChild(stats.domElement); controls = new function () { this.rotationSpeed = 0.1; } var gui = new dat.GUI(); gui.add(controls, 'rotationSpeed', 0, 0.5); } var camera; function initCamera() { camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000); camera.position.x = 600; camera.position.y = 0; camera.position.z = 600; camera.up.x = 0; camera.up.y = 1; camera.up.z = 0; camera.lookAt(0,0,0); } var scene; function initScene() { scene = new THREE.Scene(); } var light; function initLight() { light = new THREE.AmbientLight(0xFF0000); light.position.set(100, 100, 200); scene.add(light); light = new THREE.PointLight(0x00FF00); light.position.set(0, 0, 300); scene.add(light); } var cube; var mesh; function initObject() { var geometry = new THREE.CubeGeometry(100, 100, 100); geometry.vertices[0].uv = new THREE.Vector2(0, 0); geometry.vertices[1].uv = new THREE.Vector2(1, 0); geometry.vertices[2].uv = new THREE.Vector2(1, 1); geometry.vertices[3].uv = new THREE.Vector2(0, 1); var material = new THREE.MeshPhongMaterial({ map: THREE.ImageUtils.loadTexture('textures/a.jpg') }); mesh = new THREE.Mesh(geometry, material); mesh.position = new THREE.Vector3(0, 0, 0); scene.add(mesh); } function threeStart() { initThree(); initCamera(); initScene(); initLight(); initObject(); animation(); initTween(); } function animation() { mesh.rotation.x += controls.rotationSpeed; renderer.render(scene, camera); requestAnimationFrame(animation); stats.update(); //TWEEN.update(); } </script> </head> <body onload="threeStart();"> <div id="canvas-frame"></div> </body> </html>