1、 学会画点、画线、画面的知识
2、 学会绘制复杂的图形
我们下面会学习使用直线画一个网格出来,为了更好的理解这个网格在空间中的位置,我们是时候,讲一讲空间坐标系了。
Threejs使用的是右手坐标系,这源于opengl默认情况下,也是右手坐标系。下面是右手坐标系的图例,如果对这个概念不理解,可以百度一下,我保证你伸出手比划的那一瞬间你就明白了,如果不明白请给作者留言,我会尽快补上关于坐标系的知识。
图中右边那个手对应的坐标系,就是右手坐标系。在Threejs中,坐标和右边的坐标完全一样。x轴正方向向右,y轴正方向向上,z轴由屏幕从里向外。
在Threejs中,一条线由点,材质和颜色组成。
点由THREE.Vector3表示,Threejs中没有提供单独画点的函数,它必须被放到一个THREE.Geometry形状中,这个结构中包含一个数组vertices,这个vertices就是存放无数的点(THREE.Vector3)的数组。这个表示可以如下图所示:
为了绘制一条直线,首先我们需要定义两个点,如下代码所示:
var p1 = new THREE.Vector3( -100, 0, 100 ); var p2 = new THREE.Vector3( 100, 0, -100 );
请大家思考一下,这两个点在坐标系的什么位置,然后我们声明一个THREE.Geometry,并把点加进入,代码如下所示:
var geometry = new THREE.Geometry(); geometry.vertices.push(p1); geometry.vertices.push(p2);
geometry.vertices的能够使用push方法,是因为geometry.vertices是一个数组。这样geometry 中就有了2个点了。
然后我们需要给线加一种材质,可以使用专为线准备的材质,THREE.LineBasicMaterial。
最终我们通过THREE.Line绘制了一条线,如下代码所示:
var line = new THREE.Line( geometry, material, THREE.LinePieces );
ok,line就是我们要的线条了。
我还深爱着高中时的那个坐标平面,它勾起了我关于前排同学的细细长发的回忆…
这个平面的效果如下所示,截图不完整哦:
它横竖分别绘制了20条线段,在摄像机的照射下,就形成了这般模样。你可以在[初级教程\chapter2\2-2.html]发现这些代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Three框架</title> <script src="js/Three.js"></script> <style type="text/css"> div#canvas-frame { border: none; cursor: pointer; width: 100%; height: 600px; background-color: #EEEEEE; } </style> <script> var renderer; 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); } var camera; function initCamera() { camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000); camera.position.x = 0; camera.position.y = 1000; camera.position.z = 0; camera.up.x = 0; camera.up.y = 0; camera.up.z = 1; camera.lookAt({ x : 0, y : 0, z : 0 }); } var scene; function initScene() { scene = new THREE.Scene(); } var light; function initLight() { light = new THREE.DirectionalLight(0xFF0000, 1.0, 0); light.position.set(100, 100, 200); scene.add(light); } var cube; function initObject() { var geometry = new THREE.Geometry(); geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) ); geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) ); for ( var i = 0; i <= 20; i ++ ) { var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) ); line.position.z = ( i * 50 ) - 500; scene.add( line ); var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) ); line.position.x = ( i * 50 ) - 500; line.rotation.y = 90 * Math.PI / 180; scene.add( line ); } } function threeStart() { initThree(); initCamera(); initScene(); initLight(); initObject(); renderer.clear(); renderer.render(scene, camera); } </script> </head> <body onload="threeStart();"> <div id="canvas-frame"></div> </body> </html>
画网格关键之处initObject函数中,我们不浪费纸,但是浪费一些电,在下面重复一下上面的代码:
var cube; function initObject() { var geometry = new THREE.Geometry(); // B begin geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) ); geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) ); // B end for ( var i = 0; i <= 20; i ++ ) { var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) ); line.position.z = ( i * 50 ) - 500; scene.add( line ); var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) ); line.position.x = ( i * 50 ) - 500; line.rotation.y = 90 * Math.PI / 180; scene.add( line ); } }
思路:我们要画一个网格的坐标,那么我们就应该找到线的点。把网格虚拟成正方形,在正方形边界上找到几个等分点,用这些点两两连接,就能够画出整个网格来。
在x轴上定义两个点p1(-500,0,0),p2(500,0,0)。
geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) ); geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );
这两个点决定了x轴上的一条线段,将这条线段复制20次,分别平行移动到z轴的不同位置,就能够形成一组平行的线段。
同理,将p1p2这条线先围绕y轴旋转90度,然后再复制20份,平行于z轴移动到不同的位置,也能形成一组平行线。
经过上面的步骤,就能够得到坐标网格了。代码如下:
for ( var i = 0; i <= 20; i ++ ) { var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) ); line.position.z = ( i * 50 ) - 500; scene.add( line ); var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) ); line.position.x = ( i * 50 ) - 500; line.rotation.y = 90 * Math.PI / 180; // 旋转90度 scene.add( line ); }
好了,本节课讲完了,感觉自己写了好久好久。要兼顾深度和初学者,确实有些困难。最后,希望您喜欢。
给WebGL中文网团队的女程序员"小果妹妹"发一个鸡腿吧,微信扫一扫赞赏,感谢。
亲爱的读者,如果你觉得WebGL中文网的课程不错,您可以购买《WebGL中文网视频课程》 课程支持我们哦,购买后记得给我们好评哦!我们强烈建议您不要在iphone上的网易云课堂软件中购买,这样苹果会收取31%左右的服务费,虽然这是明码标价,我们也表示认可和理解,具体选择权在您自己了。
感谢大家的支持,下面是课程的截图之一
老师,我看不懂算法这部分(
这两个点决定了x轴上的一条线段,将这条线段复制20次,分别平行移动到z轴的不同位置,就能够形成一组平行的线段。
同理,将p1p2这条线先围绕y轴旋转90度,然后再复制20份,平行于z轴移动到不同的位置,也能形成一组平行线。
)
不明白问题的意思。 注意相机的up方向,本课并不是y轴。
camera.position.x = 0;
camera.position.y = 1000;
camera.position.z = 0;
camera.up.x = 0;
camera.up.y = 0;
camera.up.z = 1;
camera.lookAt({
x : 0,
y : 0,
z : 0
});
老师,您好!
1.up & position & lookAt的区别是什么?相机默认位置面向Z轴,camera.up.z = 1之后发现面向X轴了,不太明白。
2.camera.lookAt({ x : 0, y : 0, z : 0 });这句的意思应该是重置当前位置为相机的初始位置,这里是将position设置为初始位置还是将up设置为初始位置?
3.请问,camera.lookAt({ x : 0, y : 0, z : 0 });重置之后,是否相机面向还是Z还是新设定的位置呢?
谢谢!
首先要说的是up、position、lookat在初级视频课程中有详细的讲解,不明白可以看,是免费的。
再说position,不用说也知道是相机的位置。如果吧人头比作相机,那么就是人头的中心的位置
up是头顶的方向,大多数时候,是朝天空的。少部分时候,是朝床头的
lookat是眼睛,看的方向,或者说是眼睛的聚焦点,不要告诉我,你眼睛可以同时聚焦2个点。
最后要说明的是 up 和lookat这两个方向必须垂直,无论怎么设置,他们必须互相垂直。不然相机看到的结果无法预知。
上面的问题很误导人,position在英文中是位置的意思,所以不要怀疑up是位置
另外,相机没有朝向的说法,只有lookat,就是它看到的那一个聚焦点,就像眼睛看到的聚焦点一样。
camera.position.y 的值从1000到1208之间,值越大锯齿网格上线多出来的东西越少;
超过1208就没有多出的部分,我不确定是相机视角的问题还是其他的问题。
这个和图片放得越大,越不清晰一个道理,可以尝试设置WebGLRenderer的参数来抗锯齿。代码如下:
new THREE.WebGLRenderer({antialias:true})
相机距离网格越近看到的细节就越多,锯齿感也就越来越严重。相片放得的越大会发现越不清晰,锯齿也就越多,也是这个道理。antialias:true可以弱化锯齿就像PS中的羽化效果一样。
THREE.Line在google中出现警告,google测试提示,让更换成LineSegments,不过两种都可以显示
新旧版本的three.js版本更更换,说明在未来的版本中,该类会被删除
老师你好,请问一下
line.rotation.y = 90 * Math.PI / 180; // 旋转90度
这里表示围绕着y轴旋转90度,那么改为围绕着z轴旋转90度的话,
line.rotation.z = 90 * Math.PI / 180; // 旋转90度
看到的效果不应该是20个相隔的点吗,为什么效果是两条中间有间隙的直线呢,不太懂这个旋转的方向。。。
___________ ___________
关于这个地方,我发表下自己的看法,看对不对:
console.log("正常的右手坐标系是x向右,y向上,z向屏幕外");
console.log("分析横线的画法可以得出当前坐标系:x向左,y向屏幕外,z向上");
console.log("分析竖线的画法可以得出:绕y轴旋转90°,方向是逆时针");
不知道是不是这样呢?
老师,我一直不明白这个坐标原点具体是在哪里?或者以照相机为参照,照相机是原点吗?
坐标原点指定的是世界坐标,不是计算机的屏幕中心,与显示器无关。是我们脑海中的一个世界坐标,相机放在世界坐标中的一个位置。而相机的中心与世界坐标无关,相机只是世界坐标中一个特殊的物体而已。这个问题,如果想通的人很简单,想不通的,很难。你可以看一下视频课程(hewebgl.com/paytip),课程上百集,已经足够你深入学习了,课程介绍了很多图形学的知识,可以少走弯路。
初级免费教程的压缩包有密码?
密码是网站域名 www.hewebgl.com
这个地方我看过教程之后发现,可能坐标的描述是有问题的,屏幕向右是x的正方向,垂直屏幕向外是y轴正方向,沿屏幕向上是z轴正方向,点的描述中点的坐标表示为THREE.Vector3(x,y,z),个人觉得基本是这样的。
在相机在z轴正方向位置,lookat指向(0,0,0)点的时候,x右边是正,y向上,z从屏幕里面到外面。当相机位置变了,那么所谓的世界坐标就变了,另外,最好不要把世界坐标和屏幕的关系绑在一起,不然很难理解。
其实我也跟9楼一样的问题,坐标系究竟是怎样的,为什么网格是z轴位移的?是不是跟1楼提问的关系有关?摄像机究竟怎样摆放
建议用实际的模型在现实生活中摆一下就明白了。 要有空间的感觉。实在不明白,请看视频课程,100多集,这些一定能搞懂。
其实我觉得如下设置camera更容易理解(y向上,x向右坐标系):
function initCamera() {
camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 1000;
camera.up.x = 0;
camera.up.y = 1;
camera.up.z = 0;
camera.lookAt({
x : 0,
y : 0,
z : 0
});
}
因为屏幕2D空间大多数程序都是这样设置的,相应修正initObject:
function initObject() {
var geometry = new THREE.Geometry();
geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );
geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );
for ( var i = 0; i <= 1; i ++ ) {
var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0xffffff, opacity: 1.0 } ) );
line.position.y = ( i * 50 ) - 500;
scene.add( line );
var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
line.position.x = ( i * 50 ) - 500;
line.rotation.z = 90 * Math.PI / 180;
scene.add( line );
}
}
不知道老师为什么喜欢用z向上的坐标系呢?
是的,如果能把我的理解了,那么其他的也就理解了。
给5楼,你的想法是对的,你说的两条线其实是就是中间两个点的侧面,但因为相机离平面太近你只看到两条线在你左右。
尝试了简化 initObject() :
function initObject() {
var material = new THREE.LineBasicMaterial({
color: 'black'
});
var geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3(-500,0,0),
new THREE.Vector3(500,0,0)
);
var createLine = function (x,z,isVertical) {
var line = new THREE.Line( geometry, material );
if (x) {
line.position.x = x;
}
if (z) {
line.position.z = z;
}
if (isVertical) {
line.rotation.y = 90 * Math.PI / 180;
}
scene.add( line );
}
for (var i = 1, length = 22, half = length / 2; i < length; i++) {
createLine(0, (i - half) * 50);
createLine((i - half) * 50, 0, true);
}
}
总感觉相机camera.up.z=1有些别扭——相当于头顶朝向屏幕外面往下看,但咱们开发者都是看向屏幕里面,低头往下看的话也是头顶朝向屏幕内,感觉z=-1更舒服些...
老师你好,我想问的是为什么横线只有17根,明明设置的是21根嘛。我调试过好多次,而且您这个网页上贴的图也是只有17根,我数过了的。
哈哈,是21根,截图的时候没有截完,不要太学究了。
画出来的网格并不是正方形的,是长<高的长方形。为什么不是20*20个正方形呢?
额。。。18楼19楼的问题解决了:是因为camera.position.y的值设置小了,这好比就是相机的视野小了,所以上下分别有两根竖线在视野之外,相机看不到。因此只需要把camera.position.y设置大一点(1208以上)就可以了。
老师我是初学者 ,我想知道怎么增加网格??
请问在已经生成线体之后能否改变线的两个端点的坐标呢,还是只能修改线本身的坐标位置
看来还是有很多人不明白坐标系,老师把up.z设为1是按照现实生活来的,把地面作为xy平面,那么高度就由z轴确定了,我理解了一下,你把显示器屏幕朝上举着,眼睛从显示器右边水平看过去就是这种情况了,具体可以看一下http://www.cnblogs.com/heyach/p/6902948.html,写的不好请各位大佬多多指教。
老师绘制出来的网格是长20宽20 , 大家看到的是17个原因是相机距离网格太近,大家把源码里的camera.position.y = 1000 (改为1500) ; 正方形就完整的呈现出来了
@5楼 @14楼
5楼提出的问题在14楼有了解答,但我感觉并不完全正确,14楼懂了照相机的概念但是没有具体去想想照相机的高度。正确来讲那两条线肯定不只是两条线的侧面,而是多条线叠在一起的结果(建议以对称的两条线为一组来为线段设置不同的颜色,这样最后看到的效果非常明显)。
在解决这个问题时我产生了一个疑惑,感觉按道理讲在i===10时的那条线应该在照相机眼里会是一个点,
但实际上并没有这么一个点,我不知道是不是在这种三维世界里单个点都是直接忽略的,希望老师或者懂这方面的朋友能够解答一下,谢谢了
老师好,画出20个网格,for循环里以50为间隔,那么画出来后不应该是长宽都是50px的正方形吗,这个单位不是px吗
我们在浏览器看到的图像,都是相机拍照后,用渲染器渲染出来的。
理解了这个,那么我们就要找到相机在哪个方向,对场景进行了拍照。
在本节课中,相机在(0,1000,0)这个位置,相机的聚焦点在(0,0,0),也就是说,
在右手坐标系中,相机是从 上方垂直向下拍照场景的。这个情况下,Y轴在相机的眼中,就成了一个点,而
X轴和Z轴垂直交叉 ,构成了一个 “十”字。我们看到的图像,就是相机拍照 X和Z轴构成的那个平面。
老师您好,我是特意注册一下,上来就是为您鼓掌。感谢您的无私奉献,为我这样的初学者带来了很多曙光。非常的感谢您。
老师您好,我还有一个问题
document.getElementById('canvas-frame').appendChild(renderer.domElement)
这句话是说 向canvas-frame中添加一个渲染器的元素对吗?
那么是否也可以用这个方式向其中添加一个物体对象呢 比如说一个长方体,我的意思是向这个场景中。
我的根本意思就是 我想通过外部的鼠标事件 来触发向这个场景中添加我需要的物体,请问是否可以实现
由于camera视角的问题会出现理解不能的情况...所以自己重新改了点参数,加了点线段,便于理解
代码在https://github.com/BadWaka/BadWaka.github.io/blob/master/views/three/three-demo-2-2.html
不错,加油
31楼的哥们有初级教程的密码吗
官网域名:www.hewebgl.com 是密码
用新版的同学,把lookat修改就可以啦。
修改前:
camera.lookAt({ x : 0,
y : 0,
z : 0
});
修改后:
camera.lookAt(0,0,0);
其实一样,本质没变,看一下源码,30s即明白,大家要养成一些学习的习惯,如看源码。
为什么上传图片失败了呢。。
0,1000,0老师好,老师在评论里说up 和lookat这两个方向必须垂直,
camera.position.x = 0;
camera.position.y = 1000;
camera.position.z = 0;
camera.up.x = 0;
camera.up.y = 0;
camera.up.z = 1;
camera.lookAt({
x : 0,
y : 0,
z : 0
});
请问up(0,0,1),lookat(0,0,0),position(0,1000,0)是如何垂直的;
position-up:(0,1000,0)->(0,0,1);
position-lookat:(0,1000,0)->(0,0,0);
如果是中心->头顶,中心->视点,这样是不垂直的
91版本的three.js复制文中代码不报错没效果什么情况
图中右边那个手对应的坐标系,就是右手坐标系。在Threejs中,坐标和右边的坐标完全一样。x轴正方向向右,y轴正方向向上,z轴由屏幕从里向外。
感觉上面原文的话错了,z轴正方向向上,y轴由屏幕从里向外才对。
@12楼
一个是从上向下看,一个是从前向后看,不一样吧
用92dev版本的 只显示竖线,不显示横线 ,什么情况??
30楼的代码链接打不开?求大神告知
老师你好,我在本课遇到这个警告WebGL: INVALID_OPERATION: getAttribLocation: program not linked,页面没有显示出网格。百度过没有找到答案,我该怎么解决呢?
看一下浏览器是否支持webgl。
[3楼]相机的位置position的值与THREE.PerspectiveCamera(75, cw / ch, 1, 1000)最后的一个值有关系.
[9楼][10楼]此节的例子相机是在Y轴,主要拍摄X\Z轴组成的面,而且头顶在Z轴方向,所以,在电脑屏幕,水平向左为X轴正方向,向上为Z轴正方向,屏幕向外(向我们人)这边为正方向.
是的,你说的是正确的,当3D世界在屏幕中之后,最好忘记世界坐标。本课时特殊的情况,如果相机是歪着摆的,那么什么世界坐标系x、y、z就根本说不清了,反而难以理解。
老师你好:
line.rotation.y = 90 * Math.PI / 180;
上述代码中的rotation,旋转中心是哪里?能不能详细讲解一下?
旋转中心是坐标原点?还是这条直线的中点?还是这条直线的某个端点?
在这个示例中,坐标原点就是直线的中点,所以这个rotation的旋转中心具体是什么?
关于相机与世界坐标以及相机各个参数之间的关系,我是这样理解的:举个例子来说,我们要用手机拍一个物体,比如香蕉,那么我们会怎么做?首先是不是得把手机拿起来放到某个位置上去,你得拿你的手固定住手机才能拍出照片,对吧,这就对应是camera的三个position属性(位置)。其次,当你把手机放到那个位置上后,你要拍到香蕉,你是不是得把手机对准那个香蕉,不然你手机虽然在那个位置,但你向上,向下随便翻动手机,可能会拍到香蕉吗?当然不会,所以对准香蕉这个操作就对应camera的 looAt() 操作。最后,你手机也摆好了,香蕉也对准了,但你是不是还得考虑到底是横着拍还是竖着拍,或者斜着拍?因为你手机横着或者竖着拍出来的香蕉是不同的,所以你手机到底是横着还是竖着对应的就是camera的up属性,这个up指的就是你手机向上的方向。当这三个因素被确定下来后,相机才能够被确定,从而拍出确定的照片,“确定”这个条件对计算机是非常重要的,因为不确定的东西对计算机来说是无法被理解的,所以也就不可能被计算机呈现。
老师,明白相机参数的意思,但是我三维想象差,不明白参数变了拍到的是什么样子,痛苦中。。。,求指点
老师你好,我想问下这个关于相机的位置在(0, 100, 0) 看向 (0, 0, 0)的问题:
camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
camera.position.x = 0;
camera.position.y = 100;
camera.position.z = 0;
camera.up.x = 0;
camera.up.y = 1;
camera.up.z = 0;
camera.lookAt({
x : 0,
y : 0,
z : 0
});
然后两个点分别是p1是黑色的,p2是红色的,我原本觉得从上往下看的时候,应该是左下角是黑色 -> 右上角是红色的,但是事实却是左上角黑色 -> 右下角红色(截图上传不了呢)
var p1 = new THREE.Vector3( -100, 0, 100 );
var p2 = new THREE.Vector3( 100, 0, -100 );
@5楼
因为,围绕自身y轴旋转,指的是,在 x轴和z轴围成的那个平面之内,进行旋转。
这教程真给劲儿,点赞!!两个线对象的名称居然可以一样?
camera.postion定义camera的位置。camera.up定义相机镜头所在的平面,lookat定义镜头朝向,聚焦位置。camera.position所在的坐标系参照物就是场景。 而camera.up定义的时候要以相机为原点,重新建立右手坐标系。up(x,y,z)的数值所表示的方向 只要跟lookat 的点跟相机位置连线垂直就可以了。这个得自己去理解了。
小计:
场景就是这个世界,相机就是我们的眼睛,而显示在屏幕上的就是相当于眼睛看到以后视网膜的成像,
我个人理解偏向于世界中心固定,方便自己想象成像。
至于楼上的大佬们说在不同位置坐标轴的方向会变,这是相对相机而言的,人站着的时候和躺着的时候看电线杆自然是不一样的,.up方法就是用来决定人是站着还是躺着的。
感谢老师。一个困惑:
var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000,opacity:0.2} ) );
Opacity 这个 property 似乎被忽略?我画出来的线是 opacity=1 的实线。
在官方文档上没有罗列出 opacity 这个 parameter?
https://threejs.org/docs/#api/en/materials/LineBasicMaterial
var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000,transparent: true,opacity:0.2} ) );
加上“transpare:true” 解决。具体原因跟three.js需要确定渲染顺序有关?对此很疑惑。
为什么我把代码copy下来,在浏览器中运行,没有任何的效果呢?
回复32楼,当前最新版,以下两处改一下即可
camera.lookAt(new THREE.Vector3(0, 0, 0));
var line = new THREE.LineSegments( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 1 } ) );
同样48楼
camera.position.x = 0;
camera.position.y = 1300;
camera.position.z = 0;
我将视角放大到1300,才能完整显示21根线
最新的能跑起来的代码,使用了更简单的易看的代码风格,逻辑没变, 没办法太长了没法直接发完整代码:
initLight() {
this.light = new THREE.DirectionalLight(0xff0000, 1.0, 0)
this.light.position.set(100, 100, 200)
this.scene.add(this.light)
},
initObject() {
let geometry = new THREE.BufferGeometry()
geometry.setFromPoints([
new THREE.Vector3(-500, 0, 0),
new THREE.Vector3(500, 0, 0)
])