第2章 还记得点、线、面吗(一)

1、 学会画点、画线、画面的知识

2、 学会绘制复杂的图形

1、因为精彩,所以值得

还记得2000年左右有一个很不错的OpenGL教程《Nehe OpenGL》,大学时,我才有机会读到那么好的教程。那时,废寝忘食,花了一个月的时间看完了整个教程。觉得不过瘾,又读了一遍师兄翻译的中文教程。在当时,Nehe教程实为经典,第一个原因是当时OpenGL的资料非常罕见,无论是新华书店,还是互联网上都很难找到一本详尽的OpenGL教程。第二个原因是NeHe教程的作者确实非常用心,写出来很精彩的实例,并浅显易懂的讲解了它。

我一直认为,我写《WebGL中文网》的目的是为3D爱好者们提供一套精彩的入门和精通资料,这套资料不仅包含基础知识,而且包含工程级别的实例,更重要的是,那能让大家理解图形学知识。长此以来,很多同学在学习了计算机图形学后,对图形学的知识还是不能应用。有很大的原因,就是缺少理论化的实践,所以,这点,我们也考虑到了,一定在讲解示例的过程中,将其中的图形学原理也给阐述清楚。

以使大家认真学习后,能够在较短的时间学到我所学习的知识。

关于图形学这些知识,我是用了很多时间去摸索的,在资料匮乏的时候去掌握一门新的知识,确实是很费时间和脑力的事情,但是现在,有了本教程,你可以直通光明顶,学到可以胜任WebGL工作的技能。我想,这也是《WebGL中文网》的宗旨吧。

2、不从画鸡蛋开始,我们从画点开始

睁开您的眼睛,看看你的周围,它是一个多么美妙的3D世界啊。3D世界由什么组成,除了上帝,还有谁能够回答呢?

是的,没有人能够回答这个问题。但是在计算机世界里,3D世界由什么组成就很好回答。

1、3D世界的组成

在计算机世界里,3D世界是由点组成,两个点能够组成一条直线,三个不在一条直线上的点就能够组成一个三角形面,无数三角形面就能够组成各种形状的物体,如下图:three.js网格模型

我们通常把这种网格模型叫做Mesh模型。给物体贴上皮肤,或者专业点就叫做纹理,那么这个物体就活灵活现了。最后无数的物体就组成了我们的3D世界。

那么3D世界的组成,是否真的这样简单?是的,从编程的角度,目前为此,你只需要知道这些。下一节,我们从点说起。

2、在Threejs中定义一个点

在三维空间中的某一个点可以用一个坐标点来表示。一个坐标点由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。

3、点的操作

在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的常用方法列出如下,为了不影响文章的连贯性,我们专门列出了一个网页来介绍它。

3、实例:画一条彩色线

初中数学中有一个定理:两个不重合的点能够决定一条直线。在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函数的代码,就是画线的代码。

1、首先,我们声明了一个几何体geometry,如下:

var geometry = new THREE.Geometry();

几何体里面有一个vertices变量,可以用来存放点。

2、定义一种线条的材质,使用THREE.LineBasicMaterial类型来定义,它接受一个集合作为参数,其原型如下:

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 } );

3、接下来,定义两种颜色,分别表示线条两个端点的颜色,如下所示:

var color1 = new THREE.Color( 0x444444 ),
color2 = new THREE.Color( 0xFF0000 );

4、定义2个顶点的位置,并放到geometry中,代码如下:

var p1 = new THREE.Vector3( -100, 0, 100 );
var p2 = new THREE.Vector3(  100, 0, -100 );

geometry.vertices.push(p1);
geometry.vertices.push(p2);

5、为4中定义的2个顶点,设置不同的颜色,代码如下所示:

geometry.colors.push( color1, color2 );

geometry中colors表示顶点的颜色,必须材质中vertexColors等于THREE.VertexColors 时,颜色才有效,如果vertexColors等于THREE.NoColors时,颜色就没有效果了。那么就会去取材质中color的值,这个很重要,大家一定记住。

6、定义一条线

定义线条,使用THREE.Line类,代码如下所示:

var line = new THREE.Line( geometry, material, THREE.LinePieces );

第一个参数是几何体geometry,里面包含了2个顶点和顶点的颜色。第二个参数是线条的材质,或者是线条的属性,表示线条以哪种方式取色。第三个参数是一组点的连接方式,我们会在后面详细讲解。

然后,将这条线加入到场景中,代码如下:

scene.add(line);

这样,场景中就会出现刚才的那条线段了。

各位,先休息一下吧,可以在线编辑一下本课的代码,会有实时的效果显示在你的眼前。哈哈,这可是我们精心为您准备的在线编辑功能啊。本课未完,未完部分见下章。如果在线编辑不管用,可能是浏览器问题,可以在顶部菜单下载代码包,本地运行。

给WebGL中文网团队的女程序员"小果妹妹"发一个鸡腿吧,微信扫一扫赞赏,感谢。

亲爱的读者,如果你觉得WebGL中文网的课程不错,您可以购买《WebGL中文网视频课程》 课程支持我们哦,购买后记得给我们好评哦!我们强烈建议您不要在iphone上的网易云课堂软件中购买,这样苹果会收取31%左右的服务费,虽然这是明码标价,我们也表示认可和理解,具体选择权在您自己了。

感谢大家的支持,下面是课程的截图之一

[1楼] mr.t** 2016-06-24 14:33

Linewidth参数怎么不行呢

WebGL中文网老师回答:

在3D世界中是没有单位的概念的,Linewidth设置为100,webgl也不知道应该在屏幕中占据多少像素。 WebGLRenderer是不支持线宽度的,所以如果要画线并设置宽度请用CanvasRenderer,它是用二维canvas画布模拟3D效果,所以能够设置宽度。

[2楼] ade1** 2016-06-26 22:48

介绍VertexColors:定义线条材质是否使用顶点颜色,这是一个boolean值。这个参数值,教程中代码中是true。但是在后边介绍的时候为什么出现了取值为THREE.VertexColors和THREE.NoColors的情况呢?

WebGL中文网老师回答:

最新版本的定义是:

NoColors: 0,

FaceColors: 1,

VertexColors: 2,

其实就是一个整形,请以相应的版本为准,不同版本的定义不一样。

[3楼] Puls** 2016-07-10 12:08

width\height 都没有提前声明,看的好纠结。。。

WebGL中文网老师回答:

js代码可以事先声明也可以不用声明,纠结的事情很多,请将心情放平,放到重要的事情上。

[4楼] muse** 2016-07-29 09:49

var p1 = new THREE.Vector3( -100, 0, 100 );

这几个参数是什么意思呢?

[5楼] huan** 2016-08-15 11:00

有些问题,学员之间也可以相互沟通解决,建议普通注册用户也能回复其他用户的问题。WebGL中文网老师对答的不好的问题可以补充回答,这样方便问题更快速的解决。

WebGL中文网老师回答:

好的。

[6楼] ange** 2016-08-29 16:23

有点不理解,up是z轴,那么转换成二维,应该是右边X轴正方向,上方是Z轴正方向,画出来的应该是从左向右斜向下的线条啊

[7楼] ange** 2016-08-29 17:27

明白了,因为y的position是1000,所以是从Y轴正方向向负方向看的,还是谢谢

[8楼] drea** 2016-11-01 17:31

老师您好,我请问个问题,我现在版本是最新版83的,运行代码出现一下黄色警告:

three.js:23268 THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead.

画面只有一条线段,请问如何修改呢

[9楼] Blac** 2016-11-02 18:03

@8楼


var line = new THREE.Line( geometry, material, THREE.LinePieces );

换成

var line = new THREE.Line( geometry, material, THREE.LineSegments);

应该是类库升级

[10楼] woni** 2016-12-03 20:15

大家好,6楼的问题我看了7楼的回答还没搞明白为什么不是从左上方指向右下方的线条 啊?camera.up.z=1是什么意思?y轴的正方是垂直于屏幕向内还是向外?

[11楼] woni** 2016-12-03 21:54

10楼的问题解决了,如果还有不懂的去百度 “three.js中camera的属性设置” 就了解了,不然的话后续的教程会越看越迷糊的。谢谢。

[12楼] ging** 2017-01-09 20:26

看看A begin 和A end之间的代码,就是画线的代码。——哪里有A begin和A end 啊?怎么后面的问题都没有老师回答了?

[13楼] fian** 2017-02-08 11:47

camera.position相机的位置

camera.up相机以哪个方向为上方

camera.lookAt相机看向哪个坐标

谢谢11楼的解答~

[14楼] wqiz** 2017-03-12 15:39

<!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>

为什么我这么写不显示,请老师帮忙看下,哪里出错了

[15楼] ohuf** 2017-03-23 10:03

课程代码里好多大小写弄错了,比如LineBasicMaterial( parameters) 的parameters参数,第一个字母都是小写,不应该是大写,例如Color应该是color,大小写写错的话是不会执行的。

[16楼] 梦梦wm** 2017-05-07 14:41

看见好想回 14 <body onload="threeStart()">  写上这个试试

[17楼] bigo** 2017-05-25 15:39

和14楼一样,也是出不来,没报错,只有一个LinePieces的警告,改成了segment,也出不来

[18楼] qaz8** 2017-06-09 15:17

为啥所有 应该有超链接的地方 都没有超链接。。。。这文章体验有问题啊

[19楼] yerl** 2017-07-04 11:58

@14楼

我觉得应该是没有给容器设置初始大小导致的,我给那个div设置高度之后就可以正常显示了

<div id="wq" style="height:300px;">

[20楼] yerl** 2017-07-04 12:01

@16楼

14楼他在</script>前已经执行了threeStart方法

[21楼] joel** 2017-08-02 14:13

@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>

[22楼] ment** 2017-08-16 22:51

"我们这里使用了set方法,为了以后深入学习的方便,这里将Vector3的常用方法列出如下,为了不影响文章的连贯性,我们专门列出了一个网页来介绍它。"  我怎么看不到这个网页链接呢?

[23楼] zch0** 2017-08-28 13:40

老师你好,var p1 = new THREE.Vector3( -100, 0, 100 );这个x,y,z的坐标轴到底是怎样的,不是和c3 3d动画的坐标轴一样的吗,z轴不是垂直于面向我们的平面吗,x轴不是向右越来越大,y轴向下越来越大吗;

[24楼] 飞飞22** 2017-10-17 16:00

您好,这个用最新的three.js就显示不出来线条,需要用以前的three.js才可以。是由于哪块更新了吗?

WebGL中文网老师回答:

不同版本的three.js不一样,仔细F12键看控制台输出情况。

[25楼] knig** 2017-10-21 17:26

24楼的你的线条显示出来了吗?我的也显示不出来

WebGL中文网老师回答:

看有没有报错,F12键看浏览器console对话框输出的内容是什么。

[26楼] cala** 2017-10-23 16:54

更新到最新版(我的是88dev)后无法显示,同楼上,哪里能看到最新版的更新内容

WebGL中文网老师回答:

回答同楼上。

[27楼] echo** 2017-11-01 20:01

应该是camera.lookAt()的方法错了,如果是88dev的版本的话,应该写成:camera.lookAt(0, 0, 0)。官方的文档描述是这样的https://threejs.org/docs/#api/cameras/Camera

WebGL中文网老师回答:

注意版本变迁。

[28楼] gosa** 2017-11-14 17:36


难怪看不到人把能正确显示的code贴出来。。。原来会超出字数哇。。。

通过看各位大神的评论,可以显示出线的正确版本的修改点:

1.THREE.LinePieces 换成 THREE.LineSegments

2.camera.lookAt(0, 0, 0)的写法

WebGL中文网老师回答:

下载我们的源码包,在菜单中,能看到一定能够运行的代码。

[29楼] Barr** 2017-11-16 16:49

30楼正解

[30楼] zzuu** 2017-12-05 12:19

30楼正解

[31楼] cynd** 2017-12-06 17:21

30楼正解,我还说上一节的框架代码不报错也出不来东西呢

[32楼] thre** 2017-12-15 14:45


camera.lookAt(0,0,0); var line = new THREE.Line( geometry, material, THREE.LineSegments );

[33楼] liuk** 2017-12-15 14:51

线出不来的原因是three.js心版本做了更改,要么把three.js换成73版本的,要么向30楼那样改一下就行了。

[34楼] clow** 2018-01-03 16:28

 刚刚接触  报这个错怎么解决THREE.WebGLProgram: gl.getProgramInfoLog() 

[35楼] clow** 2018-01-03 16:42

 刚刚接触  报这个警告怎么解决THREE.WebGLProgram: gl.getProgramInfoLog() 

[36楼] clow** 2018-01-03 16:47

找到了 还是版本问题我的是90dev   把camera.lookAt({x: 0, y: 0,z: 0  });改成camera.lookAt(0,0,0);就好了,

[37楼] 多多怎么** 2018-01-09 20:20

老师您好。我发现90版本的three.js好像不能兼容73版本的,上面这个例子换成73版本的js库就能正确显示了

WebGL中文网老师回答:

你好,感谢你提的问题。不兼容的想象是很常见的,这也是我们一直强调学员,学习必须要学习原理,不看表象,要知其所以然。不兼容,大多数函数的参数变了,这只要看一下源码(js看源码比任何语言都方面),就能够知道了。大多数情况,原理不会变,变的只是函数名,参数等。所以,我们的课程也是注重原理的,这才是学习的捷径。不然,即使你现在学会了90版本,但是100版本,有变了函数名,参数怎么办。

[38楼] acti** 2018-02-12 22:11

老师你好,linewidth参数既然无法使用,那canvas能绘制3维空间的直线吗,canvas绘制直线参数只有x,y,没有z吧?

[39楼] cwby** 2018-03-06 18:11

搞不懂那里出问题,画线的,啥都没显示,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);

}

[40楼] tian** 2018-03-28 17:42

30楼正解

还好我有看评论的习惯

[41楼] fys1** 2018-04-14 13:58

在线编程功能在哪呢?为什么我这没有

[42楼] fys1** 2018-04-14 14:00

额,有,抱歉

[43楼] Mira** 2018-05-05 01:40

最新版本运行有问题的,参考30楼评论:

1.

camera.lookAt({x: 0,y: 0,z: 0})

改为

camera.lookAt(0,0,0)

2.

let line = new THREE.LinegeometrymaterialTHREE.LinePieces);

改为

let line = new THREE.LinegeometrymaterialTHREE.LineSegments);

再次感谢30楼的帮助。

[44楼] 1813** 2018-05-14 20:47

 版本93, 不提示报错,啥也不出来。问题可能在哪?

WebGL中文网老师回答:

我们这边迁移了一下,是可以的,可能你那里有其他错误。

[45楼] 1813** 2018-05-14 20:50

46楼问题   解决了 camera.lookAt(0,0,0)

[46楼] 小码农** 2018-06-06 16:18

老师您好,能不能注释写的多一些,很多代码看不懂,不指定做什么用的

WebGL中文网老师回答:

需要循序渐进,我们尽量多写,但是推荐你看完整视频,多花时间。

[47楼] volc** 2018-06-15 12:00

30楼正解

[48楼] 风卷尘砂** 2018-07-02 14:50

修改了lookAt为lookAt(0,0,0)和THREE.LineSegments还是显示不出来,也没报错。

WebGL中文网老师回答:

相机的位置在哪里,如果在原点,那么自己就不可能看到自己。用你的眼睛,能看到你的眼睛吗?

[49楼] 巫杨锦c** 2018-07-17 14:11

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 );



}

例子是不是过时了呀?

[50楼] Chre** 2018-08-02 10:52

笔者你好呀~THREE.LinePieces参数已经被THREE.LineSegments替代啦

WebGL中文网老师回答:

是的版本更新很快,所以大家知道原理即可,改变的是函数名,原理一百年不变,这也是本套课程上100集的精髓,感谢阅读。

[51楼] 1434** 2018-08-09 15:47

显示不出来的可以看 30 楼

[52楼] 1994** 2018-08-15 10:59

请问      threeStart()函数里边,renderer.clear()这个语句是什么逻辑,如果是清空,具体哪里清空了??

[53楼] torc** 2018-08-19 13:13

请问一下,我在浏览器中打开文件后,控制台并没有报错,但是页面上一片空白,什么效果也没有是什么原因?

通过打桩可以确定所有程序都跑完了

WebGL中文网老师回答:

代码不报错,不代表就能显示东西,看一下必要的组件是否加入到代码中,如物体,相机,相机位置等。不行,就用我们的代码包先学会在自己动手。

[54楼] xiat** 2018-09-07 14:40

【友情提醒】

源码本地打开报错的具体请查看【45楼】

WebGL中文网老师回答:

看扩展阅读第二章,跨域问题是javascript最基本的问题之一。不要怪教程没教哦,因为太基础了。哈哈

[55楼] unit** 2018-09-19 16:31

请问,怎么修改页面背景颜色?修改这里的色值,为什么不起作用?


background-color: #FFB7DD;

WebGL中文网老师回答:

看webglrender是不是占据了整个屏幕,缩小canvas,就能看到背景了,你的背景很可能被挡住了。

[56楼] gcyu** 2018-10-11 15:07

97版本  改了

THREE.LineSements)

camera.lookAt(0, 0, 0);

依然显示不出来

[57楼] gcyu** 2018-10-11 15:07

97版本  改了

THREE.LineSements)

camera.lookAt(0, 0, 0);

依然显示不出来

[58楼] cona** 2018-10-15 10:48

示例中两个点的位置无法理解:

分别创建了两个点,一个是深灰色:

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度的??

Image

[59楼] huyo** 2018-11-20 10:50

@58 坐标轴写错了

你的z是x

x是y,

y是z

[60楼] John** 2018-11-25 19:50

将:camera.lookAt({ x : 0,y : 0, z : 0 })改成camera.lookAt(new THREE.Vector3(0, 0, 0));后在在0.98同0.73上测试均可正常显示

[61楼] 吕哈哈** 2019-01-24 17:29

没有效果也没有 ,控制台也没报错,why????

[62楼] 吕哈哈** 2019-01-24 17:29

没有效果也没有 ,控制台也没报错,why????

[63楼] 吕哈哈** 2019-01-24 17:29

没有效果也没有 ,控制台也没报错,why????

[64楼] 吕哈哈** 2019-01-24 17:29

没有效果也没有 ,控制台也没报错,why????

[65楼] 吕哈哈** 2019-01-24 17:29

没有效果也没有 ,控制台也没报错,why????

[66楼] 吕哈哈** 2019-01-24 17:29

没有效果也没有 ,控制台也没报错,why????

[67楼] 吕哈哈** 2019-01-24 17:29

没有效果也没有 ,控制台也没报错,why????

[68楼] 吕哈哈** 2019-01-24 17:29

没有效果也没有 ,控制台也没报错,why????

[69楼] nang** 2019-02-16 11:09

THREE.WebGLRenderer 102dev

1.THREE.LinePieces 换成 THREE.LineSegments

2.camera.lookAt(0, 0, 0) 

正确运行

[70楼] cjan** 2019-03-22 09:57

老师你好,代码何时更新?

[71楼] hans** 2019-03-25 10:52

@9楼


谢谢你的代码!

[72楼] hans** 2019-03-25 14:42

@58楼


和Camera所处位置、Camera摄像机的机头位置、Camera所聚焦朝向的位置有关系。


camera.position,相机自身所处位置


camera.up,相机的机头,所处的位置


camera.lookAt,相机所聚焦朝向的位置

[73楼] 七月七月** 2019-05-16 20:41

renderer.setClearColorHex(0xFFFFFF, 1.0);新版的threejs似乎已经不支持setClearColorHex方法,我试了这句可以直接删掉。

camera.lookAt(0,0,0);这句现在应该这么写

Line方法里最后一参数改为THREE.LineSegments

这么做就能看见线了

[74楼] luom** 2019-07-11 00:31

老师你好 我看了  教程试着写了实例中的代码   都报错  THREE.Line: parameter THREE.LinePieces no longer supported. Use THREE.LineSegments instead.     我改成这句代码  var line = new THREE.LineSegments( geometry, material, THREE.LinePieces );  什么都没出来   

[75楼] huxi** 2019-09-28 15:34

感谢73 楼 我一开始异味是版本的问题 切换到0.83.0就可以了 没有去查看api

[76楼] mrta** 2019-09-29 14:21

renderer.setClearColorHex is not a function

有报错,这个怎么处理?

[77楼] jeke** 2019-11-08 11:23

老师您好,请问这个教程是用的three.js的什么版本。我用r110版本的three.js实现划线失败了,是函数找不到定义。

[78楼] jeke** 2019-11-08 11:24

老师您好,请问这个教程是用的three.js的什么版本。我用r110版本的three.js实现划线失败了,是函数找不到定义。

[79楼] 5197** 2019-12-04 15:14

threejs版本不同,需要修改东西

[80楼] CGS_** 2019-12-05 17:11

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

[81楼] pow8** 2020-01-10 11:51

一开始我的也画不出先,用的是97版本的three.js

后来发现28楼才是正解

[82楼] shan** 2020-01-22 08:20

@10楼的

不管你看不看得到,我专门注册了账号来感谢你。

我刚开始也看的晕晕乎乎的,也没在意这个坐标系,看了你的搜索之后,发现很有用。

https://www.cnblogs.com/v-weiwang/p/6072235.html

就是上面的这个地址,参考文档,很好用,给后面的人看。

[83楼] 大秦帝国** 2020-05-26 14:59

代码太久了,最新的都不能用了

[84楼] 北回归客** 2020-06-30 21:34

32楼正解!!谢谢

[85楼] Jaso** 2021-07-22 17:19

Geometry这个在three里面不存在,我的three.js 是0.130.1

[86楼] zhq1** 2021-11-08 22:06

geometry.colors.push( color1, color2 ); 新版本这个方式已经失效,

改为:

  geometry.setAttribute('color',new THREE.Float32BufferAttribute(colors,3));

[87楼] 香菇炖熊** 2022-03-28 18:30

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);

[88楼] 南城** 2022-06-13 17:25

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>

[89楼] 南城** 2022-06-13 17:49

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>

[90楼] lyb1** 2022-08-31 10:03

                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提示 不可用,为什么呢? 

提问或评论

登陆后才可留言或提问哦:) 登陆 | 注册 登陆后请返回本课提问
用户名
密   码
验证码