【Threejs基础教程-光影篇】5.1 常用的灯光

2024-03-31 21:12

本文主要是介绍【Threejs基础教程-光影篇】5.1 常用的灯光,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

5.1 常用的灯光

  • 学习ThreeJS的捷径
  • 环境光AmbientLight
    • 环境光介绍
    • 构造器
    • 环境光常用属性和函数
  • 点光源PointLight
    • 点光源介绍
    • 点光源常用属性
  • 平行光DirectionalLight
    • 平行光介绍
    • 平行光常用属性
  • 半球光
    • 半球光介绍
    • 半球光常用属性
  • 聚光灯
    • 聚光灯介绍
    • 聚光灯常用属性
  • 平面光
  • 使用灯光时需要注意的点
  • 光影烘培
    • 如何辨别别人的效果是否是烘培过的
    • 如何烘培

学习ThreeJS的捷径

本段内容会写在0篇以外所有的,本人所编写的Threejs教程中

对,学习ThreeJS有捷径
当你有哪个函数不懂的时候,第一时间去翻一翻文档
当你有哪个效果不会做的时候,第一时间去翻一翻所有的案例,也许就能找到你想要的效果
最重要的一点,就是,绝对不要怕问问题,越怕找找别人问题,你的问题就会被拖的越久

如果你确定要走WebGL/ThreeJS的开发者路线的话,以下行为可以让你更快的学习ThreeJS

  1. 没事就把所有的文档翻一遍,哪怕看不懂,也要留个印象,至少要知道Threejs有什么
  2. 没事多看看案例效果,当你记忆的案例效果足够多时,下次再遇到相似问题时,你就有可能第一时间来找对应的案例,能更快解决你自己的问题
  3. 上述案例不只是官网的案例,郭隆邦技术博客,跃焱邵隼,暮志未晚等站点均有不少优质案例,记得一并收藏
    http://www.yanhuangxueyuan.com/ 郭隆邦技术博客
    https://www.wellyyss.cn/ 跃焱邵隼
    http://www.wjceo.com/ 暮志未晚
    这三个站点是我最常逛的站点,推荐各位有事没事逛一下,看看他们的案例和写法思路,绝对没坏处

环境光AmbientLight

环境光介绍

环境光最主要的功能是照亮全场,大多数的场景都需要一个环境光来照亮,只要我们使用StandradMaterial材质以及其他会收到光照影响的材质,那么,我们的场景就最好添加一个环境光

几乎前面所有的demo都有用到环境光,所以这里就不细讲了,后续在阴影介绍中还会简单介绍环境光在阴影处理方面的作用

构造器

AmbientLight( color : Integer, intensity : Float )
color - (参数可选)颜色的rgb数值。缺省值为 0xffffff。
intensity - (参数可选)光照的强度。缺省值为 1。

环境光常用属性和函数

color:光源颜色,一个THREE.Color对象,注意,构造器中可以填写字符串的css颜色,但是对灯光直接修改颜色不能这样,因为颜色本质上是一个THREE.Color对象,其实这个是所有光源的通用属性

	//修改灯光颜色的代码ambientLight.color = new THREE.Color("#ff0000");

intensity:光源亮度,一个浮点数,其实这个也是所有光源的通用属性,默认值为1

在这里插入图片描述
根据官方的继承结构,我们可以得知,AmbientLight是继承了light,然后light继承了Object3D,所以AmbientLight可以使用所有的Object3D的属性和函数

点光源PointLight

点光源介绍

点光源可以理解为是一个灯泡
在这里插入图片描述
点光源的实际照亮区域,是一个球形,在球形范围内的物体均会被照亮,也可以让点光源随着距离而光照强度做衰减

我们在前面的代码中,一直都给相机添加了一个点光源,所以当我们移动相机时,相机内的点光源也会跟随移动,所以相机到达物体的背面时,点光源也会跟着到达,最终照亮物体

		//相机灯let light = new THREE.PointLight();camera.add(light);scene.add(camera);

点光源常用属性

灯光强度和颜色是通用的,这里不在赘述

在这里插入图片描述
decay和distance要放到一起来看,如果distance是0的话,那么decay的设置也会无效,这两个值一个会影响光照的最大距离,一个会影响光照的衰减效果,这里我们使用lil.gui来调试这两属性,建议看到这里的同学自己写一下这个demo

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>地板效果</title><style>canvas{display: block;}body {margin: 0;overscroll-behavior: none;}#btns{position: absolute;top:10%;width: 500px;height: 100px;left: 50%;transform:translateX(-50%);}</style>
</head>
<body>
<div id="btns"></div><!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script><script type="importmap">{"imports": {"three": "../three.js-master/build/three.module.js"}}</script>
<script type="module">import * as THREE from '../three.js-master/build/three.module.js';import {OrbitControls} from "../three.js-master/examples/jsm/controls/OrbitControls.js";import {GUI} from "../three.js-master/examples/jsm/libs/lil-gui.module.min.js";let scene,renderer,camera,orbitControls;let mesh;function init(){scene = new THREE.Scene();renderer = new THREE.WebGLRenderer({alpha:true,antialias:true});renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);camera = new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,1,1000);camera.position.set(10,10,10);orbitControls = new OrbitControls(camera,renderer.domElement);let helper = new THREE.AxesHelper(5);scene.add(helper);}function addMesh(){let geometry = new THREE.PlaneGeometry(100,100).rotateX(-Math.PI/2);let material = new THREE.MeshStandardMaterial({color:0xffffff});let mesh = new THREE.Mesh(geometry,material);scene.add(mesh);let pointLight = new THREE.PointLight();pointLight.decay = 0.1;pointLight.distance = 10;pointLight.position.y = 2;scene.add(pointLight);let pointLightHelper = new THREE.PointLightHelper(pointLight,1,0xff0000);scene.add(pointLightHelper);let gui = new GUI();gui.add(pointLight,'decay',0).step(0.1);gui.add(pointLight,'distance',1).step(0.1);}function render(){renderer.render(scene,camera);requestAnimationFrame(render);}init();addMesh();render();
</script>
</body>
</html>

在这里插入图片描述

power 这个属性笔者目前为止没有用过,推测主要用途是模拟更真实的光照效果

power这个属性可以参考下面这个案例
power的相关demo

shadow 让点光源能够产生阴影,这个在后续讲解阴影的时候再细致讲解

平行光DirectionalLight

平行光介绍

官方翻译为平行光,其实我觉得,翻译为方向光更合理,平行光像射线一样,一个发光点,一个发光方向,然后以一个无限大的 Box为照亮区域
在这里插入图片描述

        let geometry = new THREE.BoxGeometry(100,100,100);let material = new THREE.MeshStandardMaterial({color:0xffffff,side:THREE.BackSide});let mesh = new THREE.Mesh(geometry,material);scene.add(mesh);//添加平行光并改变其位置let directionLight = new THREE.DirectionalLight();scene.add(directionLight)directionLight.position.set(10,10,10);//添加平行光辅助器展示平行光的位置let directionLightHelper = new THREE.DirectionalLightHelper(directionLight,1,0xff0000);scene.add(directionLightHelper);

在这里插入图片描述
平行光的照亮范围是一个方向上的所有的平面,这里我们用了一个Backside的box来做演示,可以看到,光源背面的面完全是黑色,而正面的都是灰色

平行光常用属性

在这里插入图片描述

castShadow 产生阴影,该属性放到阴影部分讲解

positiontarget,一个决定平行光的位置,一个决定平行光的照射方向,一般来说常用的方式是,把target设置到指定要照射的物体或者世界中心,然后来改变平行光的位置来更改其光照方式

半球光

半球光介绍

在这里插入图片描述
半球光的照射范围很有意思

		//由于半球光是一种球形的光,所以我们使用球体来演示效果let geometry = new THREE.SphereGeometry(50,32,32);let material = new THREE.MeshStandardMaterial({color:0xffffff,side:THREE.BackSide});let mesh = new THREE.Mesh(geometry,material);scene.add(mesh);//创建半球光let hemisphereLight = new THREE.HemisphereLight(0x000000,0xffffff,1.0);scene.add(hemisphereLight);//创建半球光辅助线let hemisphereLightHelper = new THREE.HemisphereLightHelper(hemisphereLight,1,0xff0000);scene.add(hemisphereLightHelper);

在这里插入图片描述
如gif图所示,我们创建的半球光,是上面白色下面黑色,如果你的场景需要两种不同的光照颜色渐变的话,半球光可以作为一个选择来用

半球光常用属性

在这里插入图片描述

基本上就只需要关注 colorgroundColor即可,color决定天空的颜色,groundColor决定地面的颜色

聚光灯

聚光灯介绍

这里的聚光灯和现实中的聚光灯是一个概念,包括手电筒,舞台灯等都是聚光灯

聚光灯的照射范围其实就是一个圆锥,圆锥的尖尖处是光源位置,圆锥的高和底面半径决定照射范围

在这里插入图片描述
聚光灯看demo更容易理解

聚光灯官方案例

聚光灯常用属性

在这里插入图片描述
在这里插入图片描述

angle 决定聚光灯的圆锥的开合角度,取值范围是0~ Math.PI/2
castShadow,后续讲阴影的时候讲解,用于开启灯光的投射阴影
decay 参考上面点光源,距离越远越暗
distance 参考上面点光源,光线照射的距离
intensitypower参考上面点光源,光照强度的两种定义
shadow聚光灯的阴影,后续讲解阴影时讲解
target,参考上面平行光,target决定光线的照射方向
map: 聚光灯可以投射一张map下来,如官方的案例中的效果
在这里插入图片描述

平面光

平面光目前为止笔者仅写过一个案例,这个光源目前为止笔者没有发现用途,可能在线上展厅中用的到

平面光主要用于模拟一个明亮的平面,如果你刚好需要这样一个明亮的平面,可以使用这种方式来模拟
在这里插入图片描述

在这里插入图片描述

上述是官方提供的平面光案例

注意:
1. 平面光不产生阴影
2. 平面光仅对:MeshStandard材质和MeshPhysical材质生效,部分模型加载出来是Phong材质,所以注意区分

使用灯光时需要注意的点

  1. 灯光越多,场景越卡,而且卡顿程度是指数级增长的,所以没有特殊要求的情况下,绝对不要添加过多的灯光
  2. 一般情况下,场景至少要添加一个环境光,亮度设置低一点,然后再添加一个平行光模拟太阳,或者添加一个点光源模拟灯泡,这是最常见的场景搭建打光
  3. 添加灯光时,尽量添加一个helper来提示灯光的位置,更方便于调试

光影烘培

这里要涉及一个技术叫 Render To Texture(渲染到纹理)

这个技术主要由做烘培的建模师,以及TA所有,通过可以烘培的软件,将光影效果烘培到你的模型贴图上,来达成极高的光影效果,这个时候,我们只需要把贴图贴到模型上即可,同时场景中不需要添加光源,将贴图贴到emissive上即可,一般导出后,还会存在一张LightMap,贴到lightMap上即可,这些内容在前面介绍StandardMaterial的时候已经介绍过,这里不再赘述

如何辨别别人的效果是否是烘培过的

threejs官网上的作品
这个作品就是烘培后的效果
在这里插入图片描述
判断依据1:一般情况下,无论你怎么加灯光,调整灯光,调整光影,都不可能达到这个效果,这种效果基本上就是烘培效果

判断依据2:打开F12,然后打开网络选项卡,如果里面没有内容可以在这里先刷新一下页面

在这里插入图片描述
然后随意点开一张png格式的图片,如果图片上面已经带有明显的光影效果,这种的就是已经烘培过的模型

如何烘培

先强调三遍,烘培是美术的工作,烘培是美术的工作,烘培是美术的工作

如果你未来的目标是TA,或者长久从业WebGL,那么烘培技术也是你要学的

烘培的基本要求:

  1. 你的模型,必须是低模,且必须高质量,如果存在大量点线面不连续或者零零散散,这种的模型烘培下来会大幅加重你的渲染压力,模型面数也必须要低
  2. 必须展开uv
  3. 对光影系统和渲染要有一定了解,不懂光影系统的,渲染出来的也未必好看,逼真度未必比普通的实时光影好多少

上述是笔者的粗略了解,如果想深入了解烘培技术,请自行百度 RTT 技术

这篇关于【Threejs基础教程-光影篇】5.1 常用的灯光的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/865357

相关文章

python判断文件是否存在常用的几种方式

《python判断文件是否存在常用的几种方式》在Python中我们在读写文件之前,首先要做的事情就是判断文件是否存在,否则很容易发生错误的情况,:本文主要介绍python判断文件是否存在常用的几种... 目录1. 使用 os.path.exists()2. 使用 os.path.isfile()3. 使用

华为鸿蒙HarmonyOS 5.1官宣7月开启升级! 首批支持名单公布

《华为鸿蒙HarmonyOS5.1官宣7月开启升级!首批支持名单公布》在刚刚结束的华为Pura80系列及全场景新品发布会上,除了众多新品的发布,还有一个消息也点燃了所有鸿蒙用户的期待,那就是Ha... 在今日的华为 Pura 80 系列及全场景新品发布会上,华为宣布鸿蒙 HarmonyOS 5.1 将于 7

Java实现本地缓存的常用方案介绍

《Java实现本地缓存的常用方案介绍》本地缓存的代表技术主要有HashMap,GuavaCache,Caffeine和Encahche,这篇文章主要来和大家聊聊java利用这些技术分别实现本地缓存的方... 目录本地缓存实现方式HashMapConcurrentHashMapGuava CacheCaffe

Python将字符串转换为小写字母的几种常用方法

《Python将字符串转换为小写字母的几种常用方法》:本文主要介绍Python中将字符串大写字母转小写的四种方法:lower()方法简洁高效,手动ASCII转换灵活可控,str.translate... 目录一、使用内置方法 lower()(最简单)二、手动遍历 + ASCII 码转换三、使用 str.tr

Spring Boot 常用注解整理(最全收藏版)

《SpringBoot常用注解整理(最全收藏版)》本文系统整理了常用的Spring/SpringBoot注解,按照功能分类进行介绍,每个注解都会涵盖其含义、提供来源、应用场景以及代码示例,帮助开发... 目录Spring & Spring Boot 常用注解整理一、Spring Boot 核心注解二、Spr

Java中的内部类和常用类用法解读

《Java中的内部类和常用类用法解读》:本文主要介绍Java中的内部类和常用类用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录内部类和常用类内部类成员内部类静态内部类局部内部类匿名内部类常用类Object类包装类String类StringBuffer和Stri

MySQL连接池(Pool)常用方法详解

《MySQL连接池(Pool)常用方法详解》本文详细介绍了MySQL连接池的常用方法,包括创建连接池、核心方法连接对象的方法、连接池管理方法以及事务处理,同时,还提供了最佳实践和性能提示,帮助开发者构... 目录mysql 连接池 (Pool) 常用方法详解1. 创建连接池2. 核心方法2.1 pool.q

Spring Boot 常用注解详解与使用最佳实践建议

《SpringBoot常用注解详解与使用最佳实践建议》:本文主要介绍SpringBoot常用注解详解与使用最佳实践建议,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录一、核心启动注解1. @SpringBootApplication2. @EnableAutoConfi

SQL常用操作精华之复制表、跨库查询、删除重复数据

《SQL常用操作精华之复制表、跨库查询、删除重复数据》:本文主要介绍SQL常用操作精华之复制表、跨库查询、删除重复数据,这些SQL操作涵盖了数据库开发中最常用的技术点,包括表操作、数据查询、数据管... 目录SQL常用操作精华总结表结构与数据操作高级查询技巧SQL常用操作精华总结表结构与数据操作复制表结

JavaScript时间戳与时间的转化常用方法

《JavaScript时间戳与时间的转化常用方法》在JavaScript中,时间戳(Timestamp)通常指Unix时间戳,即从1970年1月1日00:00:00UTC到某个时间点经过的毫秒数,下面... 目录1. 获取当前时间戳2. 时间戳 → 时间对象3. 时间戳php → 格式化字符串4. 时间字符