详解Threejs中的光源对象
光源的分类
AmbientLight(环境光),PointLight(点光源),SpotLight(聚光源) 和DirectionalLight(平行光)是基础光源HemisphereLight(半球光源),AreaLight(区域光源),LensFlare(镜头光晕) 是有特殊用途的光源
半球光源 HemisphereLight
- 半球光直接放置于场景之上,光照颜色从天空光线颜色颜色渐变到地面光线颜色
- 半球光不能投射阴影
- 半球光可以创建出更加贴近自然的户外光照效果,就是为了模拟在户外场景中的反光效果
半球光源的应用
如果不使用 THREE.HemisphereLight,要模拟户外光照,通常是创建一个 THREE.DirectionalLight 来模拟太阳光,并且可能再添加一个 THREE.AmbientLight 来为场景提供基础色
半球光源的常用属性
- color:从天空发出的光线的颜色
- groundColor:从地面发出的光线的颜色
- intensity:光源照射的强度。默认值为:1。
- position:光源在场景中的位置。默认值为:(0, 100, 0)
- visible:设为 ture(默认值),光源就会打开。设为 false,光源就会关闭。
半球光源的代码示例
var hemiLight = new THREE.HemisphereLight(天空的反光颜色,地面的反光颜色,光的强度)
// 这个也是默认位置
hemiLight.position.set(0, 100, 0)
scene.add(hemiLight)
环境光 AmbientLight
- 环境光是没有特定方向的光源,会均匀的照亮场景中的所有物体,主要是均匀整体改变Threejs物体表面的明暗效果,这一点和具有方向的光源不同,比如点光源可以让物体表面不同区域明暗程度不同
- 环境光影响整个场景,它的光线没有特定来源但是又无处不在,它不能影响阴影生成,因为它没有方向,并且不能作为唯一光源,使用其他光源的同时使用
THREE.AmbientLight,目的是弱化阴影和添加一些颜色
环境光的代码示例
// THREE.AmbientLight不需要指定位置,只需要指定颜色(十六进制)
var ambientLight = new THREE.AmbientLight(0x0c0c0c)
scene.add(ambientLight)
环境光和半球光源的区别
- 环境光分为
THREE.AmbientLight&THREE.HemisphereLight THREE.AmbientLight物体明暗对比无法呈现THREE.HemisphereLight物体明暗对比比较明显- 如果想模拟真实世界,建议用
THREE.HemisphereLight,如果对三维的展现不是特别苛刻,可以用THREE.AmbientLight和THREE.DirectionalLight
点光源 PointLight
- 点光源就像生活中的白炽灯,光线沿着发光核心向外发散,同一平面的不同位置与点光源光线入射角是不同的,点光源照射下,同一个平面不同区域是呈现出不同的明暗效果
- 和环境光不同,环境光不需要设置光源位置,而点光源需要设置位置属性
.position,光源位置不同,物体表面被照亮的面不同,远近不同因为衰减明暗程度不同
点光源的代码示例
var point = new THREE.PointLight(0xffffff)
//设置点光源位置,改变光源的位置
point.position.set(400, 200, 300)
scene.add(point)
平行光 DirectionalLight
- 平行光顾名思义光线平行,对于一个平面而言,平面不同区域接收到平行光的入射角一样
- 点光源因为是向四周发散,所以设置好位置属性
.position就可以确定光线和物体表面的夹角 - 对于平行光而言,主要是确定光线的方向,光线方向设定好了,光线的与物体表面入射角就确定了,仅仅设置光线位置是不起作用的
- 在三维空间中为了确定一条直线的方向只需要确定直线上两个点的坐标即可,所以平行光提供了位置
.position和目标.target两个属性来一起确定平行光方向 - 目标
.target的属性值可以是场景中任何一个三维模型对象,比如一个网格模型Mesh,平行光会通过自身位置属性.position和.target表示的物体的位置属性.position计算出来 - 平行光如果不设置
.position和.target属性,光线默认从上往下照射,也就是可以认为(0,1,0)和(0,0,0)两个坐标确定的光线方向 - 注意一点平行光光源的位置属性
.position并不表示平行光从这个位置向远处照射,.position属性只是用来确定平行光的照射方向,平行光你可以理解为太阳光,从无限远处照射过来
平行光的代码示例
var directionalLight = new THREE.DirectionalLight(0xffffff, 1)
// 设置光源的方向:通过光源position属性和目标指向对象的position属性计算
directionalLight.position.set(80, 100, 50)
// 方向光指向对象网格模型mesh,可以不设置,默认的位置是0,0,0
directionalLight.target = mesh
scene.add(directionalLight)
聚光源 SpotLight
- 聚光源可以认为是一个沿着特定方会逐渐发散的光源,照射范围在三维空间中构成一个圆锥体
- 通过属性
.angle可以设置聚光源发散角度,聚光源照射方向设置和平行光光源一样是通过位置.position和目标.target两个属性来实现
聚光源的代码示例
var spotLight = new THREE.SpotLight(0xffffff)
spotLight.position.set(200, 200, 200)
spotLight.target = mesh
// 设置聚光光源发散角度
spotLight.angle = Math.PI / 6
scene.add(spotLight)//光对象添加到scene场景中
什么是光投影
在具有方向光源的作用下,物体会形成阴影投影效果
如何光投影计算
Three.js物体投影模拟计算主要设置三部分
- 一个是设置产生投影的模型对象
- 一个是设置接收投影效果的模型
- 最后一个是光源对象本身的设置,光源如何产生投影
平行光投影计算代码示例
// 创建方向光光源
var directionalLight = new THREE.DirectionalLight(0xffffff, 1)
directionalLight.position.set(60, 100, 40)
scene.add(directionalLight)
// 设置用于计算阴影的光源对象
directionalLight.castShadow = true
// 设置计算阴影的区域,最好刚好紧密包围在对象周围,如果计算阴影的区域过大:模糊,如果过小:看不到或显示不完整
directionalLight.shadow.camera.near = 0.5
directionalLight.shadow.camera.far = 300
directionalLight.shadow.camera.left = -50
directionalLight.shadow.camera.right = 50
directionalLight.shadow.camera.top = 200
directionalLight.shadow.camera.bottom = -100
// 设置mapSize属性可以使阴影更清晰,不那么模糊
// directionalLight.shadow.mapSize.set(1024,1024)
聚光源投影计算代码示例
// 创建聚光光源
var spotLight = new THREE.SpotLight(0xffffff)
spotLight.position.set(50, 90, 50)
spotLight.angle = Math.PI /6
scene.add(spotLight)
// 设置用于计算阴影的光源对象
spotLight.castShadow = true
// 设置计算阴影的区域,注意包裹对象的周围
spotLight.shadow.camera.near = 1
spotLight.shadow.camera.far = 300
spotLight.shadow.camera.fov = 20
光投影计算的常用属性
- 模型
.castShadow属性,.castShadow属性值是布尔值,默认false,用来设置一个模型对象是否在光照下产生投影效果 - 模型
.receiveShadow属性,.receiveShadow属性值是布尔值,默认false,用来设置一个模型对象是否在光照下接受其它模型的投影效果 - 光源
.castShadow属性,如果属性设置为true, 光源将投射动态阴影,警告: 这需要很多计算资源,需要调整以使阴影看起来正确 - 光源
.shadow属性
平行光
DirectionalLight的.shadow属性值是平行光阴影对象DirectionalLightShadow
聚光源SpotLight的.shadow属性值是聚光源阴影对象SpotLightShadow - 阴影对象基类
LightShadow
LightShadow属性.camera,观察光源的相机对象,从光的角度来看,以相机对象的观察位置和方向来判断,其他物体背后的物体将处于阴影中
LightShadow属性.mapSize,定义阴影纹理贴图宽高尺寸的一个二维向量Vector2,
较高的值会以计算时间为代价提供更好的阴影质量,宽高分量值必须是2的幂直到给定设备的WebGLRenderer.capabilities.maxTextureSize
尽管宽度和高度不必相同 (例如,(512, 1024)是有效的),默认值为 ( 512, 512 )
LightShadow属性.map,该属性的值是WebGL渲染目标对象WebGLRenderTarget,使用内置摄像头生成的深度图,超出像素深度的位置在阴影中,在渲染期间内部计算
参考文档一 ———— Threejs光源对象
参考文档二 ———— HemisphereLight和AmbientLight 区别
参考文档三 ———— Threejs官方示例
我是 fx67ll.com,如果您发现本文有什么错误,欢迎在评论区讨论指正,感谢您的阅读!
如果您喜欢这篇文章,欢迎访问我的 本文github仓库地址,为我点一颗Star,Thanks~
转发请注明参考文章地址,非常感谢!!!
详解Threejs中的光源对象的更多相关文章
- 详解javascript中的this对象
详解javascript中的this对象 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的 ...
- 详解HTML中的window对象和document对象
Window -- 代表浏览器中一个打开的窗口: 对象属性 window //窗口自身 window.self //引用本窗户window=window.self window.name //为窗口命 ...
- 详解JavaScript中的Object对象
Object是在javascript中一个被我们经常使用的类型,而且JS中的所有对象都是继承自Object对象的.虽说我们平时只是简单地使用了Object对象来存储数据,并没有使用到太多其他功能,但是 ...
- 详解Javascript中的Array对象
基础介绍 创建数组 和Object对象一样,创建Array也有2种方式:构造函数.字面量法. 构造函数创建 使用构造函数的方式可以通过new关键字来声明,如下所示: 12 var arr = new ...
- 详解es6中Proxy代理对象的作用
在es6中新添加了Proxy,那么它有什么作用啊?Proxy本意为代理,而es6中的Proxy也就是代理对象,那么代理对象感觉听起来很模糊,在这里就解释一下Proxy代理对象的作用. Proxy的主要 ...
- 详解CorelDRAW中如何合并与拆分对象
合并两个或多个对象可以创建带有共同填充和轮廓属性的单个对象,以便将这些对象转换为单个曲线对象.可以合并的对象包括矩形.椭圆形.多边形.星形.螺纹.图形或文本等,本教程将详解CorelDRAW中关于合并 ...
- jQuery:详解jQuery中的事件(二)
上一篇讲到jQuery中的事件,深入学习了加载DOM和事件绑定的相关知识,这篇主要深入讨论jQuery事件中的合成事件.事件冒泡和事件移除等内容. 接上篇jQuery:详解jQuery中的事件(一) ...
- 【转】详解C#中的反射
原帖链接点这里:详解C#中的反射 反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子: 1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内 ...
- 详解Webwork中Action 调用的方法
详解Webwork中Action 调用的方法 从三方面介绍webwork action调用相关知识: 1.Webwork 获取和包装 web 参数 2.这部分框架类关系 3.DefaultAction ...
随机推荐
- 【二食堂】Beta - 事后分析
事后分析 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? Beta阶段我们首先要对文本标注方式进行优化,其次时添加好友系统,实现邀请好友共同标注的功能. ...
- [Beta]the Agiles Scrum Meeting 12
会议时间:2020.5.27 21:00 1.每个人的工作 今天已完成的工作 成员 已完成的工作 issue yjy 帮助解决技术问题 tq 撰写技术博客 wjx 博客评分界面美化 dzx 博客评分界 ...
- 转:基于 xilinx vivado 的PCIE ip核设置与例程代码详解
连接:https://blog.csdn.net/u014586651/article/details/103826967#comments
- QT判断文件/目录是否存在
最近在用qt写一个ui,遇到删除sd卡中的文件失败情况,有些时候是存在删除链表里面的文件在sd卡上已经不存在了,导致失败,以为我的链表是定时刷新的,但是文件是实时更新会同步覆盖的.这样就存在可能上一秒 ...
- 矩阵中的路径 牛客网 剑指Offer
矩阵中的路径 牛客网 剑指Offer 题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下 ...
- SPOJ GSS8 - Can you answer these queries VIII | 平衡树
题目链接 这一道题的修改操作用平衡树都很容易实现,难处理的是询问操作. 要想解决询问操作,只要知道如何在平衡树上快速合并左右两个区间的答案即可. 设$Ans_{[l,r]}^k=\sum\limits ...
- 第10课 OpenGL 3D世界
加载3D世界,并在其中漫游: 在这一课中,你将学会如何加载3D世界,并在3D世界中漫游.这一课使用第一课的代码,当然在课程说明中我只介绍改变了代码. 这一课是由Lionel Brits (βtelge ...
- Red Hat Enterprise Linux (RHEL) 9 更新了什么,即 Rocky Linux 9 和 AlmaLinux 9 展望
请访问原文链接:https://sysin.org/blog/rhel-9-vision/,查看最新版.原创作品,转载请保留出处. 作者:gc(at)sysin.org,主页:www.sysin.or ...
- Jenkins file一行代码部署.NET程序到K8S
什么是Jenkins共享库 随着微服务的增多,每个项目的都需要pipline文件,这样的话Pipeline代码冗余度高,并且pipeline的功能越来越复杂. jenkins可以使用Shared Li ...
- Mysql教程:(四)连接查询
连接查询 1.左连接查询: mysql> select stu.*,sc.*,maths+sc.chinese+sc.english from student stu left join sco ...