首页 > 其他分享 >Three.js教程:常见光源类型

Three.js教程:常见光源类型

时间:2023-06-09 11:47:15浏览次数:47  
标签:网格 教程 颜色 光源 Three js 点光源 设置 position

推荐:将NSDT场景编辑器加入你的3D工具链
其他系列工具:NSDT简石数字孪生

常见光源类型

Threejs虚拟光源是对自然界光照的模拟,threejs搭建虚拟场景的时候,为了更好的渲染场景,往往需要设置不同的光源,设置不同的光照强度,就像摄影师给你拍照要设置各种辅助灯光一样。

环境光AmbientLight

环境光是没有特定方向的光源,主要是均匀整体改变Threejs物体表面的明暗效果,这一点和具有方向的光源不同,比如点光源可以让物体表面不同区域明暗程度不同。

//环境光:环境光颜色RGB成分分别和物体材质颜色RGB成分分别相乘
var ambient = new THREE.AmbientLight(0x444444);
scene.add(ambient);//环境光对象添加到scene场景中

你可以把光源颜色从0x444444更改为0x888888,可以看到threejs场景中的网格模型表面变的更亮。

点光源PointLight

点光源就像生活中的白炽灯,光线沿着发光核心向外发散,同一平面的不同位置与点光源光线入射角是不同的,点光源照射下,同一个平面不同区域是呈现出不同的明暗效果。

和环境光不同,环境光不需要设置光源位置,而点光源需要设置位置属性.position,光源位置不同,物体表面被照亮的面不同,远近不同因为衰减明暗程度不同。

你可以把案例源码中点光源位置从(400, 200, 300)位置改变到(-400, -200, -300),你会发现网格模型被照亮的位置从前面变到了后面,这很正常,光源只能照亮面对着光源的面,背对着光源的无法照射到,颜色会比较暗。

//点光源
var point = new THREE.PointLight(0xffffff);
//设置点光源位置,改变光源的位置
point.position.set(400, 200, 300);
scene.add(point);

平行光DirectionalLight

平行光顾名思义光线平行,对于一个平面而言,平面不同区域接收到平行光的入射角一样。

点光源因为是向四周发散,所以设置好位置属性.position就可以确定光线和物体表面的夹角,对于平行光而言,主要是确定光线的方向,光线方向设定好了,光线的与物体表面入射角就确定了,仅仅设置光线位置是不起作用的。

在三维空间中为了确定一条直线的方向只需要确定直线上两个点的坐标即可,所以Threejs平行光提供了位置.position和目标.target两个属性来一起确定平行光方向。目标.target的属性值可以是Threejs场景中任何一个三维模型对象,比如一个网格模型Mesh,这样Threejs计算平行光照射方向的时候,会通过自身位置属性.position.target表示的物体的位置属性.position计算出来。

// 平行光
var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
// 设置光源的方向:通过光源position属性和目标指向对象的position属性计算
directionalLight.position.set(80, 100, 50);
// 方向光指向对象网格模型mesh2,可以不设置,默认的位置是0,0,0
directionalLight.target = mesh2;
scene.add(directionalLight);

平行光如果不设置.position.target属性,光线默认从上往下照射,也就是可以认为(0,1,0)(0,0,0)两个坐标确定的光线方向。

注意一点平行光光源的位置属性.position并不表示平行光从这个位置向远处照射,.position属性只是用来确定平行光的照射方向,平行光你可以理解为太阳光,从无限远处照射过来。

聚光源SpotLight

聚光源可以认为是一个沿着特定方会逐渐发散的光源,照射范围在三维空间中构成一个圆锥体。通过属性.angle可以设置聚光源发散角度,聚光源照射方向设置和平行光光源一样是通过位置.position和目标.target两个属性来实现。

// 聚光光源
var spotLight = new THREE.SpotLight(0xffffff);
// 设置聚光光源位置
spotLight.position.set(200, 200, 200);
// 聚光灯光源指向网格模型mesh2
spotLight.target = mesh2;
// 设置聚光光源发散角度
spotLight.angle = Math.PI / 6
scene.add(spotLight);//光对象添加到scene场景中

光源辅助对象

Threejs提供了一些光源辅助对象,就像AxesHelper可视化显示三维坐标轴一样显示光源对象,通过这些辅助对象可以方便调试代码,查看位置、方向。

辅助对象构造函数名
聚光源辅助对象 SpotLightHelper
点光源辅助对象 PointLightHelper
 
平行光光源辅助对象 DirectionalLightHelper

光照计算算法

Three.js渲染的时候光照计算还是比较复杂的,这里不进行深入介绍,只给大家说下光源颜色和网格模型Mesh颜色相乘的知识,如果你有兴趣可以学习计算机图形学或者WebGL教程。

Threejs在渲染的时候网格模型材质的颜色值mesh.material.color和光源的颜色值light.color会进行相乘,简单说就是RGB三个分量分别相乘。

平行光漫反射简单数学模型:漫反射光的颜色 = 网格模型材质颜色值 x 光线颜色 x 光线入射角余弦值

漫反射数学模型RGB分量表示:(R2,G2,B2) = (R1,G1,B1) x (R0,G0,B0) x cosθ

R2 = R1 * R0 * cosθ
G2 = G1 * G0 * cosθ
B2 = B1 * B0 * cosθ

颜色相乘测试

你可以通过下面代码验证上面颜色相乘的算法,比如把网格模型的颜色设置为白色0xffffff,也就意味着可以反射任意光照颜色,然后把环境光和点光源只保留红色成分,绿色和蓝色成分都设置为0。你可以看到网格模型会把渲染为红色。

// 网格模型材质设置为白色
var geometry = new THREE.BoxGeometry(100, 100, 100); //
var material = new THREE.MeshLambertMaterial({
  color: 0xffffff
});
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

//环境光   环境光颜色RGB成分分别和物体材质颜色RGB成分分别相乘
var ambient = new THREE.AmbientLight(0x440000);
scene.add(ambient);//环境光对象添加到scene场景中
//点光源
var point = new THREE.PointLight(0xff0000);
//设置点光源位置  光源对象和模型对象的position属性一样是Vector3对象
//PointLight的基类是Light  Light的基类是Object3D  点光源对象继承Object3D对象的位置属性position
point.position.set(400, 200, 300);
scene.add(point);

你还可以尝试把网格模型设置为纯蓝色0x0000ff,光源颜色只保留红色成分不变,你可以看到网格模型的渲染效果是黑色,因为这两个颜色相乘总有一个RGB分量为0,相乘的结果是0x00000,也就是黑色。这也符合实际的物理规律,蓝色的物体不会反射红色的光线,熙然就是黑色效果。

如果你想模拟一个舞台的各种颜色灯光效果,可以用这种思路设置RGB各个分量值来实现特定颜色光源,不过一般渲染的时候RGB三个分量是相同的,也就是表示白色光源,0xffffff表示最高强度的白色光源,0x000000相当于没有光照。

3D建模学习工作室    

上一篇:Three.js教程:对象克隆、复制 (mvrlink.com)

下一篇:Three.js教程:透视投影相机 (mvrlink.com)

标签:网格,教程,颜色,光源,Three,js,点光源,设置,position
From: https://www.cnblogs.com/mvrlink/p/17468774.html

相关文章

  • jmeter-json断言
    1.JSON断言所在位置:断言->JSON断言2.JSON断言中的字段解析AssertJSONPathexists:json表达式,判断所字段是否存在,存在则为True,否则为FalseAdditionallyassertvalue:附加断言字段对应的值,匹配则为True,否则为FalseMatchasregularexpression:断言表达式,判断字段是否存在,......
  • JSON是什么?JSON的简单介绍及使用
    一、JSON介绍JSON(JavaScriptObjectNotation)是一种数据结构,当我们需要在不同的应用程序之间传递数据时,我们需要一种通用的格式来表示数据。相比xml交换格式来说,因为解析xml比较的复杂且需要编写大段的代码,而JSON数据更小,也更容易解析。1、JSON基本语法JSON数据与JAVA中......
  • url中的jsessionid解释
    url中的jsessionid解释(1)这是一个保险措施因为Session默认是需要Cookie支持的但有些客户浏览器是关闭Cookie的这个时候就需要在URL中指定服务器上的session标识,也就是5F4771183629C9834F8382E23BE13C4C用一个方法(忘了方法的名字)处理URL串就可以得到这个东西这个方法......
  • Node.js
    Node.js学习是为了更好地表达自己的思想,而这是机器代替不了的--尘风初识Node.jsNode.js是什么Node.js是运行在服务端的JavaScriptNode.js是一个基于ChromeJavaScript运行时建立的一个平台Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎Node.js前......
  • JSOI2018 部分题解
    目录潜入行动防御网络列队潜入行动一眼直接DP。设\(f_{i,j,0/1,0/1}\)表示\(i\)子树内放了\(j\)个监听设备,\(i\)是否被子结点覆盖,\(i\)是否放了监听设备,\(i\)子树内除了\(i\)都被覆盖的方案数。转移是一个树形背包,时间复杂度\(\mathcal{O}(nk)\),只是常数有点大。......
  • 新斗罗大陆游戏详细图文架设教程
    前言“我叫小舞,跳舞的舞”,唐三不知道的是,这个叫做小舞的十万年魂兽会成为他一生的羁绊。在星斗大森林被武魂殿追杀生死存亡之际,小舞毅然决然进行了死亡献祭,将魂环魂骨和灵魂毫无保献祭留给了唐三,这是我听斗罗大陆小说最感人虐泪也是最不愿意二刷的一段。就像唐三的母亲蓝银皇阿银......
  • JS 将form表单数据快速转化为object对象(json对象)
    JS将form表单数据快速转化为object对象(json对象)jaymou于2020-03-0311:11:05发布3534收藏3分类专栏:前端文章标签:javascriptjquery版权前端专栏收录该内容5篇文章0订阅订阅专栏直接上代码/***将Form的数据转化成Javascript的Json对象*/$.fn.seri......
  • pdf.js 预览功能
    一、官网地址https://mozilla.github.io/pdf.js/   二、样例的代码目录截图 效果截图和访问路径:http://localhost:63342/web-code/html/pdfjs-3.7.107-dist/web/viewer.html?file=pdf-demo.pdf ......
  • Java Kafka简单地将Map对象序列化为json
    最近用到kafka,想简单地把Map对象序列化为json发送到主题,直接用string序列化,生成的结果不是json,虽然格式很像,key都没有引号,可能是直接调用的toString方法。但是网上搜了一圈,都是spring组合或者其他不太简单的方案。在哔站看了一段视频受到启发,就实现了一个自定义json序列化类,......
  • graalvm nodejs + spire office 实现office 处理
    实际上是一个比较简单的处理,主要是利用了graalvm的nodejs可以方便的使用外部jar,我们就可以使用其他nodejsweb框架,结合spireoffice实现专业可靠的office转换处理预备主要是安装graalvm以及nodejsgraalvm已经不支持包含nodejs了,需要独立安装参考对于grralvm安装......