推荐:将NSDT 编辑器加入你3D工具链
其他工具系列:NSDT简石数字孪生
下面的代码完整展示了通过three.js引擎创建的一个三维场景,在场景中绘制并渲染了一个立方体的效果,为了大家更好的宏观了解three.js引擎,尽量使用了一段短小但完整的代码实现一个实际的三维效果图。
学习建议刚一开始学习,不需要完全看懂下面的代码,能够修改增删部分代码就可以,随着时间的推移就能够很好的使用三维引擎three.js。
本课程风格和大多数课程风格不同,注意一定要结合案例代码学习,在案例代码的基础上调试体验总结,就像做化学实验一样,不要仅仅阅读文字。
.html文件引入three.js引擎在.html文件中引入three.js就像前端经常使用的jquery.js一样引入即可。
<!--相对地址加载--><script src="./three.js"></script>
我已经把three.js文件上传到了我的博客服务器, 可以通过下面的URL地址去加载。
<!--http绝对地址远程加载--><script src="http://www.yanhuangxueyuan/versions/threejsR92/build/three.js"></script>案例源码
第一个Three.js案例,麻雀虽小,五脏俱全,整体展示了Three.js的整套渲染系统。
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>第一个three.js文件_WebGL三维场景</title> <style> body { margin: 0; overflow: hidden; /* 隐藏body窗口区域滚动条 */ } </style> <!--引入three.js三维引擎--> <script src="http://www.yanhuangxueyuan/versions/threejsR92/build/three.js"></script> <!-- <script src="./three.js"></script> --> <!-- <script src="http://www.yanhuangxueyuan/threejs/build/three.js"></script> --></head><body> <script> /** * 创建场景对象Scene */ var scene = new THREE.Scene(); /** * 创建网格模型 */ // var geometry = new THREE.SphereGeometry(60, 40, 40); //创建一个球体几何对象 var geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry var material = new THREE.MeshLambertMaterial({ color: 0x0000ff }); //材质对象Material var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh scene.add(mesh); //网格模型添加到场景中 /** * 光源设置 */ //点光源 var point = new THREE.PointLight(0xffffff); point.position.set(400, 200, 300); //点光源位置 scene.add(point); //点光源添加到场景中 //环境光 var ambient = new THREE.AmbientLight(0x444444); scene.add(ambient); // console.log(scene) // console.log(scene.children) /** * 相机设置 */ var width = windownerWidth; //窗口宽度 var height = windownerHeight; //窗口高度 var k = width / height; //窗口宽高比 var s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大 //创建相机对象 var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000); camera.position.set(200, 300, 200); //设置相机位置 camera.lookAt(scene.position); //设置相机方向(指向的场景对象) /** * 创建渲染器对象 */ var renderer = new THREE.WebGLRenderer(); renderer.setSize(width, height);//设置渲染区域尺寸 renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色 document.bodyendChild(renderer.domElement); //body元素中插入canvas对象 //执行渲染操作 指定场景、相机作为参数 rendererder(scene, camera); </script></body></html>体验测试
直接看上面的代码大家可能不太理解,如果是第一次接触会比较陌生,可以尝试更改代码的参数看看有什么效果,代码的功能都有注释, 看着注释也能大概猜出一个参数的含义。通过修改代码,同时刷新浏览器查看效果形成一个互动来提高自己学习的驱动力。
几何体Geometry//创建一个立方体几何对象Geometryvar geometry = new THREE.BoxGeometry(100, 100, 100);
代码var box=new THREE.BoxGeometry(100,100,100);通过构造函数THREE.BoxGeometry()创建了一个长宽高都是100的立方体,通过构造函数名字BoxGeometry也能猜出这个构造函数的意义,利用new关键字操作构造函数可以创建一个对象, 这都是Javascript语言的基本知识,至于THREE.BoxGeometry()构造函数具体是什么可以不用关心, 就像你使用前端使用JQuery库一样查找官方文档就可以,你可以把代码THREE.BoxGeometry(100,100,100)中的第一个参数更改为为50,刷新浏览器查看数据更改后长方体的效果图,可以看到已经不是长宽高一样的立方体, 而是普通的长方体。
你也可以用下面一段代码代替上面的长方体代码,你会发现会渲染出来一个球体效果。
//创建一个球体几何对象var geometry = new THREE.SphereGeometry(60, 40, 40);材质Material
代码var material=new THREE.MeshLambertMaterial({color:0x0000ff});通过构造函数THREE.MeshLambertMaterial()创建了一个可以用于立方体的材质对象, 构造函数的参数是一个对象,对象包含了颜色、透明度等属性,本案例中只定义了颜色color,颜色属性值0x0000ff表示蓝色,可以把颜色值改为0x00ff00,可以看到是绿色的立方体效果, 这里使用的颜色值表示方法是16进制RGB三原色模型。使用过渲染类软件、设计过网页或者学习过图形学应该能知道RGB三原色模型,这里就不再详述。
光源Light代码var point=new THREE.PointLight(0xffffff);通过构造函数THREE.PointLight()创建了一个点光源对象,参数0xffffff定义的是光照强度, 你可以尝试把参数更改为为0x444444,刷新浏览器你会看到立方体的表面颜色变暗,这很好理解,实际生活中灯光强度变低了,周围的景物自然暗淡,three.js引擎对WebGL光照模型算法都进行了封装,不需要你了解计算机图形学, 可以直接使用调用three.js光源相关API直接创建一个光源对象,就像你使用普通的三维建模渲染软件一样,只是这里多了一个Javascript编程语言而已。
相机Camera代码var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);通过构造函数THREE.OrthographicCamera()创建了一个正射投影相机对象, 什么是“正射投影”,什么是“相机对象”,每个人的基础不一样,或许你不太理解,或许你非常理解,如果不清楚还是那句话,刚一开始不用深究,改个参数测试一下看看视觉效果你就会有一定的感性认识。 比如把该构造函数参数中用到的参数s,也就是代码var s = 200;中定义的一个系数,可以把200更改为300,你会发现立方体显示效果变小,这很好理解,相机构造函数的的前四个参数定义的是拍照窗口大小, 就像平时拍照一样,取景范围为大,被拍的人相对背景自然变小了。camera.position.set(200, 300, 200);和camera.lookAt(scene.position);定义的是相机的位置和拍照方向,可以更改camera.position.set(200,300,200);参数重新定义的相机位置,把第一个参数也就是x坐标从200更改为250, 你会发现立方的在屏幕上呈现的角度变了,这就像你生活中拍照人是同一个人,但是你拍照的位置角度不同,显示的效果肯定不同。这些具体的参数细节可以不用管, 至少你知道相机可以缩放显示三维场景、对三维场景的不同角度进行取景显示。
整个程序的结构场景——相机——渲染器从实际生活中拍照角度或是使用三维渲染软件角度理解本节课的案例代码,立方体网格模型和光照组成了一个虚拟的三维场景,相机对象就像你生活中使用的相机一样可以拍照,只不过一个是拍摄真实的景物,一个是拍摄虚拟的景物,拍摄一个物体的时候相机的位置和角度需要设置,虚拟的相机还需要设置投影方式,当你创建好一个三维场景,相机也设置好,就差一个动作“咔”,通过渲染器就可以执行拍照动作。
对象、方法和属性从面向对象编程的角度理解上面的程序,使用three.js和使用其它传统前端Javascript库或框架一样,通过框架提供的构造函数可以创建对象,对象拥有方法和属性,只不过three.js是一款3D引擎, 如果你对HTML、Javascript语言、三维建模渲染软件都能够理解应用,即使你不懂计算机图形学和WebGL,也能够学习three.js引擎,创建可以在线预览的三维场景。
案例源码分别使用构造函数THREE.Scene()、THREE.OrthographicCamera()、THREE.WebGLRenderer()创建了场景、相机、渲染器三个最顶层的总对象,然后通过总对象的子对象、方法和属性进行设置, 相机对象和渲染对象相对简单,最复杂的是场景对象,new THREE.Mesh(box,material);使用构造函数Mesh()创建了一个网格模型对象,该对象把上面两行含有顶点位置信息的几何体对象和含有颜色信息的材质对象作为参数,网格模型创建好之后, 需要使用场景对象的方法.add()把三维场景的子对象添加到场景中,new THREE.PointLight(0xffffff);、new THREE.AmbientLight(0x444444);定义了两个点光源、环境光对象,然后作为场景的子对象插入场景中。 场景、相机、渲染器设置完成后,设置代码rendererder(scene,camera)把场景、相机对象作为渲染器对象方法render()的参数,这句代码的意义相当于告诉浏览器根据相机的放置方式拍摄已经创建好的三维场景对象。
WebGL封装如果你有WebGL基础,可以通过下面介绍了解Three.js对WebGL的封装,如果不了解WebGL或计算机图形学,随便阅读一下或者直接跳过。
从WebGL的角度来看,three.js提供的构造函数基本是对原生WebGL的封装,如果你有了WebGL的基础,在学习three.js的很多对象、方法和属性是很容易理解的。在three.js入门教程中不会去过多讲解WebGL的基础知识, 但是为了大家更好的理解three.js的很多命令,与three.js相关的WebGL API知识、GPU渲染管线的知识。图形学可能很多人会觉得比较难,其实主要是算法部分,大家先可以学习一些基本的WebGL知识,初学的时候尽量不关注算法,主要了解顶点数据处理的过程,GPU渲染管线的基本功能单元。实际的工作中如果不是开发3D引擎可能不会使用原生WebGL API,但是学习了这些之后,对于three.js的深度开发学习很有好处,如果你了解你WebGL知识,可以联系绘制函数drawArrays()来理解渲染器的渲染操作方法render()。
3D建模学习工作室
金木水火土五行涵盖了世间万物的种种特性,从实际可探的到看不见摸不着的,均具有五行的内涵之意。作为我们肉眼可见的东西中最熟知的莫过于色彩,我们每日都会见由各色各样的东西组成的视觉世界,而这些色彩本身也是五行力量的体现。
五行对应的五种颜色分别是木-青、火-赤、金-白、水-黑、土-黄。《尚书·虞书·益稷》中有言:“以五采彰施於五色,作服,汝明。” 孙星衍疏中说:“五色,东方谓之青,南方谓之赤,西方谓之白,北方谓之黑,天谓之玄,地谓之黄,玄出於黑,故六者有黄无玄为五也。”中国神话中女娲补天用的五色石也分别对应青、赤、白、黑、黄五色。这说明中国传统文化中对于颜色的定义与五行理论息息相关,那为什么偏偏选择了青、赤、白、黑、黄这五种颜色对应木火金水土这五行呢?同时,五色又是如何与五行一一对应起来的呢?接下来就有我给大家分享一下。
五色
1、五色与色彩斑斓的视觉世界
五行对应的五色分别是青、赤、白、黑、黄,用现在的话来说就是蓝、红、白、黑、黄。仔细看不难得出这五种颜色可以分为两类:三原色(红黄蓝)和黑白。三原色是各种彩颜色的最基本单位。黑白两色则是非彩色的最基本单位,同时也是所有色彩明暗程度的标尺。而五色本身能量的大小又是“饱和度”这一概念的体现。所以色彩三要素便由五色完整地体现出来了。
色彩三要素是色相、饱和度和明度,是颜色的基本性质,也是所有颜色都必须具有的特性,有了色彩三要素才能算是颜色。
色相:顾名思义就是颜色的相貌,比如黄色,红色,蓝色,可以理解为颜色的类型。
明度:平衡色彩亮与暗的一个指标,当明度最大的时候就是白色,明度最小的时为黑色。
饱和度:颜色的鲜艳或鲜明的程度,饱和度高可以理解为红的更红、绿的更绿,色彩的程度更明显。
色彩三要素
所以五行对应的五色构成了颜色所需要的三种要素,也是万千色彩的基本组成。在物理层面上,五色是颜色之母,所有颜色皆可由五色衍生。
2、五色与五行本质
木-青、火-赤、金-白、水-黑、土-黄的对应关系其实是五行本质在色彩上的反映,那是如何反映的呢?接下来我们一起看看吧。
木对应青色,青色清脆而不张扬,伶俐而不圆滑,清爽而不单调,象征着坚强、希望、古朴和庄重。清脆伶俐是木曲直屈伸特点的体现,不单调的清爽以及希望的象征是木生发特性的体现。青色按照我们现代人的分类是蓝色和绿色的结合,而蓝色经常象征水,绿色则是草木的颜色,草木加上水,代表着万物生长、生生不息。伶俐清爽和希望代表着时间发展上的动态(阳),古朴庄重代表着物质空间上的静(阴),此为少阳(阳上阴下)之象,是木的象征。而这些均是“木”本质的象征,即“整体存在”之意,同时从宇宙中看地球是个蓝色的星球,在古人的眼里,地球就是他们的世界,所以地球是世界的整体,也有“整体存在”之意,符合木的本质。
木之青色
火对应赤色,赤为红,红色代表着吉祥、喜庆、热烈、奔放、勇气、斗志、革命、轰轰烈烈、澎湃等,也代表积极乐观而热情,情绪明显波动,真诚主动,勇于挑战。是一种好动且积极向上的颜色,在时间发展与物质空间均表现为动(阳)的力量,为太阳,这些都符合“火”的本质——“运动变化”。同时红色象征着火焰,火焰也一样具有“火”的性质。
火之赤色
金对应白色,白色象征明亮干净、畅快、朴素、单纯、雅致、贞洁、寒冷与严峻,其实这些形容词都突出了一个特征——纯净。纯净乃无瑕疵污浊,乃利落不拖泥带水,纯粹清净如同金之肃杀和凌冽的特性。符合金的本质——“影响效果”
金之白色
水对应黑色,黑色有深远幽妙之义,庄重而神秘,这种深远幽妙和庄重的感觉是静(阴)的力量,为太阴;而将所有颜色混合在一起后我们会得到黑色,说明黑色是各种颜色的终归和根,是万千色彩世界潜藏的另一面。这些均符合水的本质——“组成成分”,黑色就像影子一样参与了所有色调的构成,就算是白色,也是黑的反面,就像镜子一样倒映出黑色优雅庄重的性质。
水之黑色
土对应黄色,黄色给人愉快、辉煌、温暖、充满活力、丰收与希望的感觉,这种感觉是和谐且融洽的,此为阴阳相和,符合古人对五行中土的理解(土旺四季,土贯穿始终,联系金木水火也承载金木水火)。同时愉快、温暖与充满活力都是和谐关系的象征,而丰收与希望则表现了一种承载一切的力量(青色的希望是一种蓬勃生长的力量,黄色的希望是一种温暖而有力量支持的力量,这种力量与支持就是承载与和谐关系)这些是土本质——“结构关系”的体现。
土之黄色
注:上述中对五行本质的解释是来自于万物之元素——五行的本质及象征
3、五色的来源与地理位置之间的关系
五色的概念来源于古人对世界的理解,有关五色为哪五种颜色的最早记载则在《周礼·考工记》:“杂五色,东方谓之青,南方谓之赤,西方谓之白,北方谓之黑,天谓之玄,地谓之黄”。而《三辅黄图》称,苍龙、白虎、朱雀、玄武,天之四灵,以正四方。即左青龙、右白虎、前朱雀、后玄武,四大灵兽镇守东西南北四宫,辟邪恶、调阴阳,为四方之神。《淮南子》提到五龙之一的黄龙,也即应龙位居中央,乃四兽之长。而苍龙、白虎、朱雀、玄武以及应龙分别对应木、金、火、水、土。
那古人为何认定东青、南赤、西白、北黑、中黄,除了五行理论上的解释之外,还有就来自于古人对自然现象的观察。华夏文明起源于中原大地,自然以此为认知的中心,向东为东方、西为西方、南为南方、北为北方。同时古人交通能力有限只能徒步或是利用动物行进,在路上也只能以观察地面自然景观作为认识世界的手段,而在地面自然景观中土地土壤就是最明显的观察对象,所以青、赤、白、黑、黄五色的来源也一定与东南西北中这五个地方的土壤特点存在密切关系。
最好的证据就是明朝建立的社稷坛,社稷坛中分别用来自东方的青色、南方的红色、西方的白色、北方的黑色及中原大地的黄色五种不同颜色的土壤,表示普天之下莫非王土。而这些土的颜色及来源正一一与五行相对应。而且我们以中原大地为中心,分别向东南西北走就可以发现,东南西北方的主要土壤类型恰巧与五色相对应。
其中东方最终会到大海,虽然大海不算是土壤,但却也是地上的东西,是古人能看到的能给出定义的,而大海是蓝色,蓝对应青。同时青色的土壤叫潜育土,因为长时间缺氧处于还原态,使得里面的铁变为二价亚铁的氧化物,呈现出青灰色,而这种潜育土最容易出现在长江中下游平原中的水稻土下层,而长江中下游平原恰巧位于中国东方,且是较容易从中原出发所到达的地方。
中原地区的西方正是现在的甘肃省中南部,土壤类型以淡黄发灰的灰钙土为主,淡色且发灰相比较其他地方的土,此为白土。同时西部地区土壤易沙化,也会形成颜色较浅的土壤,呈现白调。
南方和北方就不用多说了,中国南方地区常见的红壤和东北地区的黑土地就是最好的证明。
4、小结
中国传统文化中青、赤、白、黑、黄五色不是随随便便选出来的五种颜色,它们是色彩世界的基本构成;是五行理论精华的外在体现;是客观世界、四方大地的真实表现;更是中国古人那深不可测的智慧和传统文化博大精深的体现!
杭州市钱塘区景苑中学科学老师 项洋洋
夏日里,我们很容易在雨后看到天空中出现一道七色的彩虹。许多行人会趁此机会用手机拍下这美丽的自然景观,发到朋友圈表达对自然界馈赠的赞美。那么你知道彩虹的成因和颜色的由来吗?
彩虹的成因
彩虹最常在雨后刚转天晴时出现,这时空气内尘埃少而充满小水滴,天空的一边因为仍有雨云而较暗,而观察者头上或背后已没有云的遮挡而可见阳光,这样彩虹便会较容易被看到。
太阳光其实是一种复合光,包括可见光和不可见光两部分。其中不可见光主要指红外线和紫外线,而我们所看见的彩虹其实是可见光照射到空气中接近球形的小水滴,造成折射及反射而成的。具体的过程如下:
阳光照射到水滴表面,先折射一次
阳光中的可见光是白光,是由不同的单色光构成的。而球形的水滴对光有色散的作用,不同的单色光由于频率、波长不同,其折射率也有所不同。而红光的折射率比蓝紫色光小,导致蓝紫光的偏向角度比红光大。因此复合的白光在经过第一次折射之后变成了不同的单色光形成了我们常说的七种色光带——红橙黄绿蓝靛紫。
其实人类很早就可以通过棱镜让白光发生色散,但最早是由牛顿设计了相关的棱镜实验,并通过“实验归纳——假说理论——实验检验”的典型的科学规律的研究方法,并渗透着分析(把白光分解为单色光研究)和综合的方法(把单色光复合为白光)。
折射后的不同色光在水滴的背面发生反射
光经过第一次折射后在水滴内会再发生反射,所以观察者看见的光谱是会和第一次折射后产生的光谱分布刚好相反。
最后离开水滴时再折射一次
经过第二次折射后的色光进入人的眼睛,最终在人的大脑皮层形成视觉,即我们看到的不同颜色的光。(如使大脑产生“红色”视觉的光波长大概是620~760nm,而产生“绿色”的光波长大概是520~560nm)
物体的颜色
随着对光谱和色彩研究的不断深入,我们发现:世界上的万物色彩斑斓主要是因为太阳光照射到物体表面,其中反射到我们眼里的色光决定了物体的颜色。如当我们观察叶子时,是因为照射到叶子的绿色光被叶片反射,而其他色光均被吸收了,导致我们看到的叶子是绿色的。
相对特殊的是,当一个物体能吸收所有的色光时,我们的大脑接收不到任何的可见光,就将其认知为了“黑色”。好比我们在没有灯光的晚上观察叶片时,此时由于没有光照,因此不会有任何光反射到我们的眼睛,我们看到的也变成了漆黑一片。而当某个物体不能吸收任何色光,将所有色光全部反射时,我们就会将其认知为“白色”。
随着研究的深入,我们发现色彩中存在不能再分解的三种基本颜色,即我们现在所提的三原色(红绿蓝)。将三原色的色光以不同的比例相加,可以产生多种多样的色光。
扩展思考题:为什么可见光光谱中没有棕色?
其实“棕色”根本就不存在!棕色只是人的大脑所认知出的一种颜色,它的形成还和其背景色彩有关。事实上,棕色本身其实是颜色较暗的“橙色”,在背景偏黒的环境中呈现“暗橙”,但在背景偏白的环境中,我们的大脑为错认其为一种新的颜色——“棕色”。
为什么美术中的三原色是指红黄蓝,而非红绿蓝?
光的三原色属于物理的研究范畴,是物理学家根据光的色散理论及实验得来的。光学三原色其色彩的混合属于加法显色,光线会越加越亮,两两混合可以得到更亮的中间色。如红和绿混合成黄色,因为完全不含蓝色,所以黄色就是蓝色的补色。两个等量补色混合也形成白色。两色光混合后,其光线增强,光亮度高于两色光的起初亮度。另外,合色越多,其光线越多,色度就越接近于白色。
而美术中所讲的颜料三原色是色彩学家的研究体系,其研究表明色料的三原色是红色、黄色、蓝色。颜料色彩的混合属于减法显色,颜料自身并不能发光,必须依靠白光照射产生反光从而被眼睛看见。如把黄色颜料和蓝色颜料混合起来,因为黄色颜料吸收蓝光,蓝色颜料吸收红光,因此只有绿色光反射出来,这就是黄色颜料加上蓝色颜料形成绿色的道理。两种颜色的颜料混合后,其光度会低于两色起初的光度。另外,合色越多,其被吸收的光线就会越多,颜色就越接近于黑色。
为什么我们平时看到的铁块是白色的,而铁粉是黑色的?
对于铁块、铁片来说,光线照在上面,其表面形成成镜面反射,因此许多可见光反射入眼,形成白色。而铁粉的表面积小,没有固定的几何形状,因此光照到铁粉表面形成的是漫反射,并没有许多可见光能反射入眼,因此显黑色。
本文为钱江晚报原创作品,未经许可,禁止转载、复制、摘编、改写及进行网络传播等一切作品版权使用行为,否则本报将循司法途径追究侵权人的法律责任。