Threejs写的渐变发亮半球

马上就要毕业了,实习进入了一个GIS公司,任务要求使用Threejs写个渐变的发光半球小特效,我完成后决定写出这篇文章。给那些刚刚接触Threejs的朋友们。

首先了解过Threejs的朋友们肯定知道threejs最重要的三个对象scene(场景)、camera(相机)、render(渲染)。如果不知道这些也没事,我推荐一个网站,我一开始也是在那里学习的。WebGL中文网看过这个一般对threejs和webGL有了初步的映像。

废话不多说,直接进入代码,我会在代码里写出注释并附上解释。代码非常简单所以就用notepaid++写了,首先加入我们的threejs库。建议下载threejs开源代码,因为里面还有其他模块后面会用到,比如转动镜头等等。

添加js库

创建一个div叫做ThreeJS让他来存放我们的3维模型。

创建div

接下来编写js代码,首先创建scene,camera,render全局对象然后写一个初始化和动画函数。

js代码

1、创建场景

scene = new THREE.Scene();

2、创建相机

camera = new THREE.PerspectiveCamera( angle, ASPECT, NEAR, FAR);

第一个参数为俯角度,第二个为相机可视化范围的长宽比,第三个参数为相机离物体的最近距离,第四个参数为相机离物体的最远距离。(注意threejs的坐标系与我们日常用到的不一样,上下为y轴,横向为x轴,里外为z轴)。

之后很重要的一点就是把相机放入到场景中去。

scene.add(camera);

并初始化给他一个观察点。不然还是没有相机的(好比你去拍风景,带了相机去没有拿出来)。

camera.position.set(0,150,400);(注意坐标轴的问题,而且这个camera是全局变量的相机)

camera.lookAt(scene.position);//设置一个观察点

3、创建渲染

renderer = new THREE.WebGLRenderer( {antialias:true} );

其中的属性为抗锯齿效果设置为有效 ,也可以不加。定义完之后我们需要设定渲染的大小以及将其联系到我们的HTML中去。

renderer.setSize(width,height);

container = document.getElementById( 'ThreeJS' );

container.appendChild( renderer.domElement );

上述代码设置了renderer的大小,其次通过appendChild方法将渲染连接到dom元素上去。(container设置成全局变量)。这样我们就创建好了我们三大最基本的ThreeJS元素。接下来我们创建我们的半球。

我们使用球体也就是sphereGeometry,其中有6各参数。

var sphereGeom = new THREE.SphereGeometry( 40, 40, 40 ,0,Math.PI*2,0,Math.PI/2);//半球几何

SphereGeometry(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength);radius是球的半径,默认为50;widthSegments是水平分割面的数量(最小为3,默认为8),heightSegments是垂直分割面的数量(最小为2,默认为6)。这个越多就越接近真正的球体。下图可以清楚的分辨2者的不同。

phiStart是水平起始角度,默认为0;phLength是指定水平扫描角度大小,默认是Math.PI*2也就是一整圆;thetaStart为指定垂直的起始角度;最后一个为thetaLength指定垂直扫描角度大小,默认值为Math.PI。为什么不是2PI呢?我猜想是水平已经扫了一个圆,垂直只要半圆就能完成一个球的绘制。反过来垂直扫了整圆,水平也只要半圆就够了。我们完成几何体的创建后只需要在几何外表上铺一层皮才能显示。这里threejs提供了许多不同的“皮”,要选择适合自己的材料。这里我们多用几种,首先是兰伯特网孔材料(MeshLambertMaterial)它是一种自身并不会发光    受光源影响大的一种材料。这里我们创建一个红色半透明的材质。还有其他许多种属性,这里我们就不全部举例。需要的同学可以再官网api上查找,我以我自己的例子为主。

var redMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000, transparent: true, opacity: 0.5 ,side: THREE.DoubleSide});//一个颜色为红色,开启透明度,透明度为0.5,双面渲染的一个半球。

然后创建一个object,类型为Mesh。他的参数使我们之前创的几何模型以及材料

var sphere = new THREE.Mesh(sphereGeom.clone(),redMaterial);

sphere.position.set(0,0,0);

scene.add(sphere);

我们将它坐标设置为0,0,0。并且让场景去加载他。之前也说了兰伯特材料是不发光的,所以要给他一个光源我们才能看到物体。就像黑漆漆的夜晚我们无法看到绚丽多彩的世界。光源的种类也有很多种,官网的例子也丰富多彩。一不小心可能一下午就过去了(〃'▽'〃)。这里我用的是最基础的平行光源,就像太阳照射进来的效果一样。

var directionalLight = new THREE.DirectionalLight( 0xffffff, 100 );

directionalLight.position.set( 0, 1000, 0 );

scene.add( directionalLight );

上述代码是创建一种平行光,100的光照强度位置在0,1000,0的位置,并且场景去添加这个光源。最后我们将场景和相机都渲染出来,这样我们就能看到我们的半球了。代码是

requestAnimationFrame(animate);//不断回调渲染函数

renderer.render( scene, camera );//渲染场景和相机

创建的半球

那么如何去观察半球,以及这半球是不是半透明的呢?

这里我们添加辅助工具,可以控制相机角度的控件以及坐标系的辅助设施。非常简单,我们添加空间的js库然后实例化鼠标控制相机角度的对象就行了。js库为OrbitControls.js。

controls = new THREE.OrbitControls( camera, renderer.domElement );//实例化参数为相机和dom对象。

之后我们就能随意的用鼠标调整相机的位置了,就不用自己去写函数了,是不是非常方便?回到正题我们创建坐标轴的辅助对象,这回不需要控件js。

var helpers = new THREE.Group();//实例化辅助对象组

helpers.add( new THREE.AxesHelper( 200 ) );//添加坐标系控件长度为200

scene.add( helpers );//添加到场景

效果图:

效果图

然后我们添加渐变球的效果。我提一个问题考考大家,我双面设置后为啥反面还是黑色的,答案很简单的。

var green = new THREE.SphereGeometry( 40., 100, 100 ,0,Math.PI*2,0,Math.PI/2);//几何体

var greenMaterial = new THREE.MeshBasicMaterial( { color: 0xffffff, vertexColors: THREE.VertexColors,transparent: true, opacity: 0.5 ,side: THREE.DoubleSide } );//创建材质其中将定点颜色设置为THREE.VertexColors

sphere1 = new THREE.Mesh( green, greenMaterial );

sphere1.position.set(0, 0, 0);

sphere1.scale.multiplyScalar(1.07);//等比例放大

scene.add( sphere1 );

创建后最基础的之后我们要把渐变特效给写出来,效果通常是写到不断渲染过程中的。代码如下

动画

最终效果图

效果图
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,290评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,107评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,872评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,415评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,453评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,784评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,927评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,691评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,137评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,472评论 2 326
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,622评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,289评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,887评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,316评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,490评论 2 348

推荐阅读更多精彩内容