导读
1.项目Spike功能点
2.Three.js基本元素简单介绍
3.Three.js做出xy面网格
下面的还没写
4.添加静态点元素
5.添加GUI控制元素属性
6.添加轨迹球控件
7.让定位点动起来
一、项目Spike功能点
1.建立三维网格坐标系。
2.添加运动元素,坐标改变位置由硬件提供的数据转换为json格式读取。
3.添加camera的观察对象改变功能。
4.添加camera视角切换,远近切换功能。
二、Three.js基本元素简单介绍
Three.js的基本元素包括scene(场景)、camera(相机)和renderer(渲染器)。
scene是一个容器用来保存并跟踪所有需要渲染的物体,一个scene想要显示任何东西需要三个类型的组 件:相机、光源、物体。
camera定义我们能够在scene里看见的内容。camera分为正投影相机(OrthographicCamera)和透视 相机(PerspectiveCamera)两种。
OrthographicCamera的参数包括:fov(视场)、aspect(长宽比)、 near(近面)、far(远面)
PerspectiveCamera的参数包括:left(左边界)、right(右边界)、top(上边界)、bottom(下边 界)、near(近面)、far(远面)
camera.lookAt(new THREE.Vector3(x,y,z))设置相机聚焦位置。
renderer负责计算指定相机角度下浏览器中scene的样子。考虑到CPU资源和功能,一般选择使用Three.js里的WebGLRenderer对象(另外两种renderer对象为Canvas和SVG的渲染器)
三、Three.js做出xy面网格
首先定义renderer、scene、camera, 并在场景中添加光源light。
光源light包括AmbientLight(环境光)、PointLight(点光源)、SpotLight(聚光灯光源)、DirectionalLight(方向光)、HemisphereLight(半球光)、AreaLight(面光源)、LensFlare(镜头眩光)。
let renderer; let scene; let camera, light; function initRenderer() { renderer = new THREE.WebGLRenderer(); //定义渲染器 renderer.setSize(window.innerWidth, window.innerHeight); //渲染器大小 renderer.setClearColor(0xFFFFFF); //设置renderer背景色 document.body.appendChild(renderer.domElement); //将renderer添加到对应的对象 } function initScene() { scene = new THREE.Scene(); //定义场景 } function initCamera(){ camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight,0.1,100000); camera.position.set(0,0,800); //定义相机位置 camera.up.x = 0; camera.up.y = 1; camera.up.z = 0; //定义相机镜头方向 camera.lookAt({ //定义相机焦点位置 x:0, y:0, z:0 }); } function initLight(){ light = new THREE.DirectionalLight(0xFF0000,1.0,0); light.position.set(100,100,200); scene.add(light); //向scene中添加光源 }
然后我们开始准备画一个网格,这里的网格我们以线条组来实现而不直接向场景添加一个二维面对象。
首先我们创建一个线段基础材质(LineBasicMaterial)他可以设置线段的颜色、宽度、端点和连接点。
接着新建一个几何对象,定义将使用到的线段颜色,再定义两个三维坐标点作为线条的端点。并将定义的点集和颜色添加到该几何对象中。
let material = new THREE.LineBasicMaterial({vertexColors: THREE.VertexColors}); let frame_geometry = new THREE.Geometry(); let point_color_1 = new THREE.Color(0x999999); let point_color_2 = new THREE.Color(0xff0000); let point_1 = new THREE.Vector3(-1000,0,0); let point_2 = new THREE.Vector3(1000,0,0); frame_geometry.vertices.push(point_1); frame_geometry.vertices.push(point_2); frame_geometry.colors.push(point_color_1,point_color_1);
接下来我们向scene中添加设定好坐标的线条Line,这里我们使用THREE.Line,线段只有顶点不包含任何面。
//添加横向线条 for (let i=-100;i<100;i++){ let line = new THREE.Line(frame_geometry,material,THREE.LineSegments ); line.position.y = i*10; scene.add(line); } //添加纵向线条 for (let i=-100;i<100;i++){ let line = new THREE.Line(frame_geometry,material,THREE.LineSegments ); line.rotation.z = (90 * Math.PI)/180; line.position.x = i*10; scene.add(line) }
添加横纵线条后我们就得到了一个 xy面上的网格,这里我设置的间隔是10,即一格小格是10*10的大小,如果这里取值为一或者更小出现的是一格黑色的面,原因大家都懂。
ps:我在学习的时候百度的关键词是”three.js 网格绘制“,出来的几篇博客中和我这里的代码是基本一样的,但是每一篇的镜头角度是有区别的,加上renderer的添加对象不一样,可能会出现参考那几篇博客无法看见网格的情况,因为他们镜头观察的焦点不在画网格的面上。
画完这个网格后我们得到的网格的x轴和y轴并不能直观的展现,这里我是用类似的方法在x和y轴添加了不同颜色的线段,当然也可以在for循环里判断一下添加不同的颜色。
下面是这部分的完整代码:
function initFrame(){ let material = new THREE.LineBasicMaterial({vertexColors: THREE.VertexColors}); let frame_geometry = new THREE.Geometry(); let point_color_1 = new THREE.Color(0x999999); let point_color_2 = new THREE.Color(0xff0000); let point_1 = new THREE.Vector3(-1000,0,0); let point_2 = new THREE.Vector3(1000,0,0); frame_geometry.vertices.push(point_1); frame_geometry.vertices.push(point_2); frame_geometry.colors.push(point_color_1,point_color_1); for (let i=-100;i<100;i++){ let line = new THREE.Line(frame_geometry,material,THREE.LineSegments ); line.position.y = i*10; scene.add(line); } for (let i=-100;i<100;i++){ let line = new THREE.Line(frame_geometry,material,THREE.LineSegments ); line.rotation.z = (90 * Math.PI)/180; line.position.x = i*10; scene.add(line) } let cross_geometry = new THREE.Geometry(); cross_geometry.vertices.push(point_1); cross_geometry.vertices.push(point_2); cross_geometry.colors.push(point_color_2,point_color_2); let cross_lineX = new THREE.Line(cross_geometry,material,THREE.LineSegments ); let cross_lineY = new THREE.Line(cross_geometry,material,THREE.LineSegments ); cross_lineX.position.y = 0; cross_lineY.rotation.z = (90 * Math.PI)/180; cross_lineY.position.x = 0; scene.add(cross_lineX); scene.add(cross_lineY); }
最后我们将上面的function挨个执行就能得到想要的效果。
function threeStart(){ initRenderer(); initCamera(); initScene(); initLight(); initFrame(); renderer.clear(); renderer.render(scene, camera); } window.onload = threeStart();