1、 学会画点、画线、画面的知识
2、 学会绘制复杂的图形
还记得2000年左右有一个很不错的OpenGL教程《Nehe OpenGL》,大学时,我才有机会读到那么好的教程。那时,废寝忘食,花了一个月的时间看完了整个教程。觉得不过瘾,又读了一遍师兄翻译的中文教程。在当时,Nehe教程实为经典,第一个原因是当时OpenGL的资料非常罕见,无论是新华书店,还是互联网上都很难找到一本详尽的OpenGL教程。第二个原因是NeHe教程的作者确实非常用心,写出来很精彩的实例,并浅显易懂的讲解了它。
我一直认为,我写《WebGL中文网》的目的是为3D爱好者们提供一套精彩的入门和精通资料,这套资料不仅包含基础知识,而且包含工程级别的实例,更重要的是,那能让大家理解图形学知识。长此以来,很多同学在学习了计算机图形学后,对图形学的知识还是不能应用。有很大的原因,就是缺少理论化的实践,所以,这点,我们也考虑到了,一定在讲解示例的过程中,将其中的图形学原理也给阐述清楚。
以使大家认真学习后,能够在较短的时间学到我所学习的知识。
关于图形学这些知识,我是用了很多时间去摸索的,在资料匮乏的时候去掌握一门新的知识,确实是很费时间和脑力的事情,但是现在,有了本教程,你可以直通光明顶,学到可以胜任WebGL工作的技能。我想,这也是《WebGL中文网》的宗旨吧。
睁开您的眼睛,看看你的周围,它是一个多么美妙的3D世界啊。3D世界由什么组成,除了上帝,还有谁能够回答呢?
是的,没有人能够回答这个问题。但是在计算机世界里,3D世界由什么组成就很好回答。
在计算机世界里,3D世界是由点组成,两个点能够组成一条直线,三个不在一条直线上的点就能够组成一个三角形面,无数三角形面就能够组成各种形状的物体,如下图:
我们通常把这种网格模型叫做Mesh模型。给物体贴上皮肤,或者专业点就叫做纹理,那么这个物体就活灵活现了。最后无数的物体就组成了我们的3D世界。
那么3D世界的组成,是否真的这样简单?是的,从编程的角度,目前为此,你只需要知道这些。下一节,我们从点说起。
在三维空间中的某一个点可以用一个坐标点来表示。一个坐标点由x,y,z三个分量构成。在three.js中,点可以在右手坐标系中表示:
空间几何中,点可以用一个向量来表示,在Three.js中也是用一个向量来表示的,代码如下所示:
THREE.Vector3 = function ( x, y, z ) { this.x = x || 0; this.y = y || 0; this.z = z || 0; };
我们来分析这段代码:前面我们已经知道了THREE是Three.js引擎的一个全局变量。只要你想用它,就可以在任何地方用它。有点充气娃娃的意思,不需要你同意,你想用就用吧。
那么THREE.Vector3呢,就是表示Vector3是定义在THREE下面的一个类。以后要用Vector3,就必须要加THREE前缀。当然Three.js的设计者,也可以不加THREE这个前缀,但是他们预见到,Three.js引擎中会有很多类型,最好给这些类型加一个前缀,以免与开发者的代码产生冲突。
THREE.Vector3被赋值为一个函数。这个函数有3个参数,分别代表x坐标,y坐标和z坐标的分量。函数体内的代码将他们分别赋值给成员变量x,y,z。看看上面的代码,中间使用了一个“||”(或)运算符,就是当x=null或者undefine时,this.x的值应该取0。
在3D世界中点可以用THREE.Vector3D来表示。对应源码为/src/math/Vector3.js(注意:源码所在的位置,可能不同版本不一样,请自己搜索Vector3关键词来确定)。在您继续学习之前,你可以打开该文件浏览一下,推荐使用WebStorm,如果没有,你也可以用NotePad++。
现在来看看怎么定义个点,假设有一个点x=4,y=8,z=9。你可以这样定义它:
var point1 = new THREE.Vecotr3(4,8,9);
另外你也可以使用set方法,代码如下:
var point1 = new THREE.Vector3(); point1.set(4,8,9);
我们这里使用了set方法,为了以后深入学习的方便,这里将Vector3的常用方法列出如下,为了不影响文章的连贯性,我们专门列出了一个网页来介绍它。
初中数学中有一个定理:两个不重合的点能够决定一条直线。在three.js中,也可以通过定义两个点,来画一条直线。我们先看看,这一节,我们要完成实例的效果图:
例子说明:这是一条每个点不同颜色的线条
这个例子的代码如下所示,可以在“【初级教程\chapter2\2-1.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(); var material = new THREE.LineBasicMaterial( { vertexColors: true } ); var color1 = new THREE.Color( 0x444444 ), color2 = new THREE.Color( 0xFF0000 ); // 线的材质可以由2点的颜色决定 var p1 = new THREE.Vector3( -100, 0, 100 ); var p2 = new THREE.Vector3( 100, 0, -100 ); geometry.vertices.push(p1); geometry.vertices.push(p2); geometry.colors.push( color1, color2 ); var line = new THREE.Line( geometry, material, THREE.LinePieces ); 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>
看看initObjec函数的代码,就是画线的代码。
var geometry = new THREE.Geometry();
几何体里面有一个vertices变量,可以用来存放点。
LineBasicMaterial( parameters )
Parameters是一个定义材质外观的对象,它包含多个属性来定义材质,这些属性是:
Color:线条的颜色,用16进制来表示,默认的颜色是白色。
Linewidth:线条的宽度,默认时候1个单位宽度。
Linecap:线条两端的外观,默认是圆角端点,当线条较粗的时候才看得出效果,如果线条很细,那么你几乎看不出效果了。
Linejoin:两个线条的连接点处的外观,默认是“round”,表示圆角。
VertexColors:定义线条材质是否使用顶点颜色,这是一个boolean值。意思是,线条各部分的颜色会根据顶点的颜色来进行插值。(如果关于插值不是很明白,可以QQ问我,QQ在前言中你一定能够找到,嘿嘿,虽然没有明确写出)。
Fog:定义材质的颜色是否受全局雾效的影响。
好了,介绍完这些参数,你可以试一试了,在课后,我们会展示不同同学的杰出作品。下面,接着上面的讲,我们这里使用了顶点颜色vertexColors: THREE.VertexColors,就是线条的颜色会根据顶点来计算。
var material = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors } );
var color1 = new THREE.Color( 0x444444 ), color2 = new THREE.Color( 0xFF0000 );
var p1 = new THREE.Vector3( -100, 0, 100 ); var p2 = new THREE.Vector3( 100, 0, -100 ); geometry.vertices.push(p1); geometry.vertices.push(p2);
geometry.colors.push( color1, color2 );
geometry中colors表示顶点的颜色,必须材质中vertexColors等于THREE.VertexColors 时,颜色才有效,如果vertexColors等于THREE.NoColors时,颜色就没有效果了。那么就会去取材质中color的值,这个很重要,大家一定记住。
定义线条,使用THREE.Line类,代码如下所示:
var line = new THREE.Line( geometry, material, THREE.LinePieces );
第一个参数是几何体geometry,里面包含了2个顶点和顶点的颜色。第二个参数是线条的材质,或者是线条的属性,表示线条以哪种方式取色。第三个参数是一组点的连接方式,我们会在后面详细讲解。
然后,将这条线加入到场景中,代码如下:
scene.add(line);
这样,场景中就会出现刚才的那条线段了。
各位,先休息一下吧,可以在线编辑一下本课的代码,会有实时的效果显示在你的眼前。哈哈,这可是我们精心为您准备的在线编辑功能啊。本课未完,未完部分见下章。如果在线编辑不管用,可能是浏览器问题,可以在顶部菜单下载代码包,本地运行。
给WebGL中文网团队的女程序员"小果妹妹"发一个鸡腿吧,微信扫一扫赞赏,感谢。
亲爱的读者,如果你觉得WebGL中文网的课程不错,您可以购买《WebGL中文网视频课程》 课程支持我们哦,购买后记得给我们好评哦!我们强烈建议您不要在iphone上的网易云课堂软件中购买,这样苹果会收取31%左右的服务费,虽然这是明码标价,我们也表示认可和理解,具体选择权在您自己了。
感谢大家的支持,下面是课程的截图之一
Linewidth参数怎么不行呢
在3D世界中是没有单位的概念的,Linewidth设置为100,webgl也不知道应该在屏幕中占据多少像素。 WebGLRenderer是不支持线宽度的,所以如果要画线并设置宽度请用CanvasRenderer,它是用二维canvas画布模拟3D效果,所以能够设置宽度。
介绍VertexColors:定义线条材质是否使用顶点颜色,这是一个boolean值。这个参数值,教程中代码中是true。但是在后边介绍的时候为什么出现了取值为THREE.VertexColors和THREE.NoColors的情况呢?
最新版本的定义是:
NoColors: 0,
FaceColors: 1,
VertexColors: 2,
其实就是一个整形,请以相应的版本为准,不同版本的定义不一样。
width\height 都没有提前声明,看的好纠结。。。
js代码可以事先声明也可以不用声明,纠结的事情很多,请将心情放平,放到重要的事情上。
var p1 = new THREE.Vector3( -100, 0, 100 );
这几个参数是什么意思呢?
有些问题,学员之间也可以相互沟通解决,建议普通注册用户也能回复其他用户的问题。WebGL中文网老师对答的不好的问题可以补充回答,这样方便问题更快速的解决。
好的。
有点不理解,up是z轴,那么转换成二维,应该是右边X轴正方向,上方是Z轴正方向,画出来的应该是从左向右斜向下的线条啊
明白了,因为y的position是1000,所以是从Y轴正方向向负方向看的,还是谢谢
老师您好,我请问个问题,我现在版本是最新版83的,运行代码出现一下黄色警告:
three.js:23268 THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.
画面只有一条线段,请问如何修改呢
@8楼
var line = new THREE.Line( geometry, material, THREE.LinePieces ); 换成 var line = new THREE.Line( geometry, material, THREE.LineSegments);
应该是类库升级
大家好,6楼的问题我看了7楼的回答还没搞明白为什么不是从左上方指向右下方的线条 啊?camera.up.z=1是什么意思?y轴的正方是垂直于屏幕向内还是向外?
10楼的问题解决了,如果还有不懂的去百度 “three.js中camera的属性设置” 就了解了,不然的话后续的教程会越看越迷糊的。谢谢。
看看A begin 和A end之间的代码,就是画线的代码。——哪里有A begin和A end 啊?怎么后面的问题都没有老师回答了?
camera.position相机的位置
camera.up相机以哪个方向为上方
camera.lookAt相机看向哪个坐标
谢谢11楼的解答~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>点线面</title>
</head>
<body>
<div id="wq">
</div>
<script type="text/javascript" src="../../three.js-master/build/three.js"></script>
<script type="text/javascript">
var renderer;
function initThree() {
width = document.getElementById('wq').clientWidth;
height = document.getElementById('wq').clientHeight;
renderer = new THREE.WebGLRenderer({
antialias : true
});
/**
* 设置渲染器的大小
*/
renderer.setSize(400, 300);
document.getElementById('wq').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();
var material = new THREE.LineBasicMaterial({
vertexColors: true
});
var color1 = new THREE.Color(0x444444),
color2 = new THREE.Color(0xFF0000);
// 线的材质可以由2点的颜色决定
var p1 = new THREE.Vector3(-100, 0, 100);
var p2 = new THREE.Vector3(100, 0, -100);
geometry.vertices.push(p1);
geometry.vertices.push(p2);
geometry.colors.push(color1, color2);
var line = new THREE.Line(geometry, material, THREE.LinePieces);
scene.add(line);
}
function threeStart() {
initThree();
initCamera();
initScene();
initLight();
initObject();
renderer.clear();
renderer.render(scene, camera);
}
threeStart();
</script>
</body>
</html>
为什么我这么写不显示,请老师帮忙看下,哪里出错了
课程代码里好多大小写弄错了,比如LineBasicMaterial( parameters) 的parameters参数,第一个字母都是小写,不应该是大写,例如Color应该是color,大小写写错的话是不会执行的。
看见好想回 14 <body onload="threeStart()"> 写上这个试试
和14楼一样,也是出不来,没报错,只有一个LinePieces的警告,改成了segment,也出不来
为啥所有 应该有超链接的地方 都没有超链接。。。。这文章体验有问题啊
@14楼
我觉得应该是没有给容器设置初始大小导致的,我给那个div设置高度之后就可以正常显示了
<div id="wq" style="height:300px;">
@16楼
14楼他在</script>前已经执行了threeStart方法
@14楼
难道不是<script type = "text/javascript">< /script>的问题么,改成<script>< /script>后不报错,但是不显示,不显示的原因就是没有设置你的canvas高度...加了一个高度打开浏览器,这下可以了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>点线面</title>
</head>
<style type="text/css">
#wq{
height: 600px;
width: 100%;
}
</style>
<body>
<div id="wq">
</div>
<script type="text/javascript" src="js/three.min.js" ></script>
<script>
var renderer;
function initThree() {
width = document.getElementById('wq').clientWidth;
height = document.getElementById('wq').clientHeight;
renderer = new THREE.WebGLRenderer({
antialias : true
});
/**
* 设置渲染器的大小
*/
renderer.setSize(400, 300);
document.getElementById('wq').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();
var material = new THREE.LineBasicMaterial({
vertexColors: true
});
var color1 = new THREE.Color(0x444444),
color2 = new THREE.Color(0xFF0000);
// 线的材质可以由2点的颜色决定
var p1 = new THREE.Vector3(-100, 0, 100);
var p2 = new THREE.Vector3(100, 0, -100);
geometry.vertices.push(p1);
geometry.vertices.push(p2);
geometry.colors.push(color1, color2);
var line = new THREE.Line(geometry, material, THREE.LinePieces);
scene.add(line);
}
function threeStart() {
initThree();
initCamera();
initScene();
initLight();
initObject();
renderer.clear();
renderer.render(scene, camera);
}
threeStart();
</script>
</body>
</html>
"我们这里使用了set方法,为了以后深入学习的方便,这里将Vector3的常用方法列出如下,为了不影响文章的连贯性,我们专门列出了一个网页来介绍它。" 我怎么看不到这个网页链接呢?
老师你好,var p1 = new THREE.Vector3( -100, 0, 100 );这个x,y,z的坐标轴到底是怎样的,不是和c3 3d动画的坐标轴一样的吗,z轴不是垂直于面向我们的平面吗,x轴不是向右越来越大,y轴向下越来越大吗;
您好,这个用最新的three.js就显示不出来线条,需要用以前的three.js才可以。是由于哪块更新了吗?
不同版本的three.js不一样,仔细F12键看控制台输出情况。
24楼的你的线条显示出来了吗?我的也显示不出来
看有没有报错,F12键看浏览器console对话框输出的内容是什么。
更新到最新版(我的是88dev)后无法显示,同楼上,哪里能看到最新版的更新内容
回答同楼上。
应该是camera.lookAt()的方法错了,如果是88dev的版本的话,应该写成:camera.lookAt(0, 0, 0)。官方的文档描述是这样的https://threejs.org/docs/#api/cameras/Camera
注意版本变迁。
难怪看不到人把能正确显示的code贴出来。。。原来会超出字数哇。。。
通过看各位大神的评论,可以显示出线的正确版本的修改点:
1.THREE.LinePieces 换成 THREE.LineSegments
2.camera.lookAt(0, 0, 0)的写法
下载我们的源码包,在菜单中,能看到一定能够运行的代码。
30楼正解
30楼正解
30楼正解,我还说上一节的框架代码不报错也出不来东西呢
camera.lookAt(0,0,0);
var line = new THREE.Line( geometry, material, THREE.LineSegments );
线出不来的原因是three.js心版本做了更改,要么把three.js换成73版本的,要么向30楼那样改一下就行了。
刚刚接触 报这个错怎么解决THREE.WebGLProgram: gl.getProgramInfoLog()
刚刚接触 报这个警告怎么解决THREE.WebGLProgram: gl.getProgramInfoLog()
找到了 还是版本问题我的是90dev 把camera.lookAt({x: 0, y: 0,z: 0 });改成camera.lookAt(0,0,0);就好了,
老师您好。我发现90版本的three.js好像不能兼容73版本的,上面这个例子换成73版本的js库就能正确显示了
你好,感谢你提的问题。不兼容的想象是很常见的,这也是我们一直强调学员,学习必须要学习原理,不看表象,要知其所以然。不兼容,大多数函数的参数变了,这只要看一下源码(js看源码比任何语言都方面),就能够知道了。大多数情况,原理不会变,变的只是函数名,参数等。所以,我们的课程也是注重原理的,这才是学习的捷径。不然,即使你现在学会了90版本,但是100版本,有变了函数名,参数怎么办。
老师你好,linewidth参数既然无法使用,那canvas能绘制3维空间的直线吗,canvas绘制直线参数只有x,y,没有z吧?
搞不懂那里出问题,画线的,啥都没显示,three 版本 90
var benscene;
var bencamera;
var benrenderer;
var light;
var obj;
var width;
var height;
function getdiv() {
width=document.getElementById('tline').clientWidth;
height=document.getElementById('tline').clientHeight;
}
function initscene() {
benscene= new THREE.Scene();
}
function initcamera() {
bencamera = new THREE.PerspectiveCamera(75, width/height, 0.1, 10000);
bencamera.position.x=0;
bencamera.position.y=1000;
bencamera.position.z=0;
bencamera.up.x=0;
bencamera.up.y=0;
bencamera.up.z=0;
bencamera.lookAt({
x:0,
y:0,
z:0
})
}
function initrenderer() {
benrenderer=new THREE.WebGLRenderer({
antialias:true
})
benrenderer.setSize(width,height);
document.getElementById('tline').appendChild(benrenderer.domElement);
benrenderer.setClearColor(0xffffff,1);
}
function initlight() {
light=new THREE.DirectionalLight(0xff0000,1,0);
light.position.set(100,100,200);
benscene.add(light);
}
function initobj() {
var geomerty =new THREE.Geometry();
var material =new THREE.LineBasicMaterial({ vertexColors: true})
var color1=new THREE.Color(0x12b949);
var color2=new THREE.Color(0x2480e4);
var point1=new THREE.Vector3(-100, 0, 100);
var point2=new THREE.Vector3(100, 0, -100);
geomerty.vertices.push(point1,point2);
geomerty.colors.push(color1,color2)
obj=new THREE.Line(geomerty,material,THREE.LineSegments);
benscene.add(obj);
}
function init() {
getdiv();
initscene();
initcamera();
initrenderer();
initlight();
initobj();
benrenderer.clear();
benrenderer.render(benscene,bencamera);
}
30楼正解
还好我有看评论的习惯
在线编程功能在哪呢?为什么我这没有
额,有,抱歉
最新版本运行有问题的,参考30楼评论:
1.
camera.lookAt({x: 0,y: 0,z: 0})
改为
camera.lookAt(0,0,0)
2.
let line = new THREE.Line( geometry, material, THREE.LinePieces);
改为
let line = new THREE.Line( geometry, material, THREE.LineSegments);
再次感谢30楼的帮助。
版本93, 不提示报错,啥也不出来。问题可能在哪?
我们这边迁移了一下,是可以的,可能你那里有其他错误。
46楼问题 解决了 camera.lookAt(0,0,0)
老师您好,能不能注释写的多一些,很多代码看不懂,不指定做什么用的
需要循序渐进,我们尽量多写,但是推荐你看完整视频,多花时间。
30楼正解
修改了lookAt为lookAt(0,0,0)和THREE.LineSegments还是显示不出来,也没报错。
相机的位置在哪里,如果在原点,那么自己就不可能看到自己。用你的眼睛,能看到你的眼睛吗?
function Line( geometry, material, mode ) {
if ( mode === 1 ) {
console.warn( 'THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.' );
return new LineSegments( geometry, material );
}
例子是不是过时了呀?
笔者你好呀~THREE.LinePieces参数已经被THREE.LineSegments替代啦
是的版本更新很快,所以大家知道原理即可,改变的是函数名,原理一百年不变,这也是本套课程上100集的精髓,感谢阅读。
显示不出来的可以看 30 楼
请问 threeStart()函数里边,renderer.clear()这个语句是什么逻辑,如果是清空,具体哪里清空了??
请问一下,我在浏览器中打开文件后,控制台并没有报错,但是页面上一片空白,什么效果也没有是什么原因?
通过打桩可以确定所有程序都跑完了
代码不报错,不代表就能显示东西,看一下必要的组件是否加入到代码中,如物体,相机,相机位置等。不行,就用我们的代码包先学会在自己动手。
【友情提醒】
源码本地打开报错的具体请查看【45楼】
看扩展阅读第二章,跨域问题是javascript最基本的问题之一。不要怪教程没教哦,因为太基础了。哈哈
请问,怎么修改页面背景颜色?修改这里的色值,为什么不起作用?
background-color: #FFB7DD;
看webglrender是不是占据了整个屏幕,缩小canvas,就能看到背景了,你的背景很可能被挡住了。
97版本 改了
THREE.LineSements)
和
camera.lookAt(0, 0, 0);
依然显示不出来
97版本 改了
THREE.LineSements)
和
camera.lookAt(0, 0, 0);
依然显示不出来
示例中两个点的位置无法理解:
分别创建了两个点,一个是深灰色:
color1 = new THREE.Color( 0x444444 );
p1 = new THREE.Vector3( -100, 0, 100 );
另一个是红色:
color2 = new THREE.Color( 0xFF0000 );
p2 = new THREE.Vector3( 100, 0, -100 );
根据方法:THREE.Vector3(x,y,z)有:
第一个点p1在坐标系的X:-100,Y:0,Z:100
第二个点p2在坐标系的X:100,Y:0,Z:-100
以X的正反向为屏幕右侧,Y的正反向为屏幕上方,Z的正反向为垂直屏幕向外,那么,这个线条在这个视觉上,看起来应该是水平的直线呀,为什么会是右上向左下倾斜45度的??
@58 坐标轴写错了
你的z是x
x是y,
y是z
将:camera.lookAt({ x : 0,y : 0, z : 0 })改成camera.lookAt(new THREE.Vector3(0, 0, 0));后在在0.98同0.73上测试均可正常显示
没有效果也没有 ,控制台也没报错,why????
没有效果也没有 ,控制台也没报错,why????
没有效果也没有 ,控制台也没报错,why????
没有效果也没有 ,控制台也没报错,why????
没有效果也没有 ,控制台也没报错,why????
没有效果也没有 ,控制台也没报错,why????
没有效果也没有 ,控制台也没报错,why????
没有效果也没有 ,控制台也没报错,why????
THREE.WebGLRenderer 102dev
1.THREE.LinePieces 换成 THREE.LineSegments
2.camera.lookAt(0, 0, 0)
正确运行
老师你好,代码何时更新?
@9楼
谢谢你的代码!
@58楼
和Camera所处位置、Camera摄像机的机头位置、Camera所聚焦朝向的位置有关系。
camera.position,相机自身所处位置
camera.up,相机的机头,所处的位置
camera.lookAt,相机所聚焦朝向的位置
renderer.setClearColorHex(0xFFFFFF, 1.0);新版的threejs似乎已经不支持setClearColorHex方法,我试了这句可以直接删掉。
camera.lookAt(0,0,0);这句现在应该这么写
Line方法里最后一参数改为THREE.LineSegments
这么做就能看见线了
老师你好 我看了 教程试着写了实例中的代码 都报错 THREE.Line: parameter THREE.LinePieces no longer supported. Use THREE.LineSegments instead. 我改成这句代码 var line = new THREE.LineSegments( geometry, material, THREE.LinePieces ); 什么都没出来
感谢73 楼 我一开始异味是版本的问题 切换到0.83.0就可以了 没有去查看api
renderer.setClearColorHex is not a function
有报错,这个怎么处理?
老师您好,请问这个教程是用的three.js的什么版本。我用r110版本的three.js实现划线失败了,是函数找不到定义。
老师您好,请问这个教程是用的three.js的什么版本。我用r110版本的three.js实现划线失败了,是函数找不到定义。
threejs版本不同,需要修改东西
1.这部分代码应该缺了width和height的定义
2.然后camera部分
camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 10000);
camera.position.set(0, 1000, 0);
camera.up.set(0,0,1)
camera.lookAt(0,0,0);
3.line部分
var line = new THREE.Line( geometry, material, THREE.LineSegments);
我是看到这个博客修改的:https://blog.csdn.net/davidPan1234/article/details/85765021
一开始我的也画不出先,用的是97版本的three.js
后来发现28楼才是正解
@10楼的
不管你看不看得到,我专门注册了账号来感谢你。
我刚开始也看的晕晕乎乎的,也没在意这个坐标系,看了你的搜索之后,发现很有用。
https://www.cnblogs.com/v-weiwang/p/6072235.html
就是上面的这个地址,参考文档,很好用,给后面的人看。
代码太久了,最新的都不能用了
32楼正解!!谢谢
Geometry这个在three里面不存在,我的three.js 是0.130.1
geometry.colors.push( color1, color2 ); 新版本这个方式已经失效,
改为:
geometry.setAttribute('color',new THREE.Float32BufferAttribute(colors,3));
THREE.REVISION: 138
const bufferGeom = new THREE.BufferGeometry();
const positions = new Float32Array([
-100, 0, 100,
100, 0, -100
]);
bufferGeom.setAttribute('position', new THREE.BufferAttribute(positions, 3));
const colors = new Float32Array([
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
]);
bufferGeom.setAttribute('color', new THREE.BufferAttribute(colors, 3));
const indexs = new Uint16Array([
0, 1
]);
bufferGeom.index = new THREE.BufferAttribute(indexs, 1);
const material = new THREE.LineBasicMaterial({
vertexColors: THREE.VertexColors, //使用缓存中的颜色
side: THREE.DoubleSide
});
const mesh = new THREE.Line(bufferGeom, material);
scene.add(mesh);
2022/6/13 最新版本可运行示例代码, 综合了楼上各位祖师的代码
<!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.set(0, 1000, 0);
camera.up.set(0, 0, 1)
camera.lookAt(0, 0, 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.BufferGeometry();
var material = new THREE.LineBasicMaterial({ vertexColors: true });
const positions = new Float32Array([
-100, 0, 100,
100, 0, -100
]);
const colors = new Float32Array([
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
]);
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
var line = new THREE.Line(geometry, material, THREE.LineSegments);
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>
2022/6/13 最新版本可运行示例代码, 综合了楼上各位祖师的代码
<!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.set(0, 1000, 0);
camera.up.set(0, 0, 1)
camera.lookAt(0, 0, 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.BufferGeometry();
var material = new THREE.LineBasicMaterial({ vertexColors: true });
const positions = new Float32Array([
-100, 0, 100,
100, 0, -100
]);
const colors = new Float32Array([
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
]);
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
var line = new THREE.Line(geometry, material, THREE.LineSegments);
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>
var geometry = new THREE.Geometry();
var material = new THREE.LineBasicMaterial( { vertexColors: true } );
var color1 = new THREE.Color( 0x444444 ), color2 = new THREE.Color( 0xFF0000 );
// 线的材质可以由2点的颜色决定
var p1 = new THREE.Vector3( -100, 0, 100 );
var p2 = new THREE.Vector3( 100, 0, -100 );
geometry.vertices.push(p1);
geometry.vertices.push(p2);
geometry.colors.push( color1, color2 );
老师,上面的代码中 var geometry = new THREE.Geometry(); 提示Geometry 找不到,
geometry.vertices.push(p1); 三个 push提示 不可用,为什么呢?