本文主要是介绍【Threejs基础教程-光影篇】5.1 常用的灯光,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
5.1 常用的灯光
- 学习ThreeJS的捷径
- 环境光AmbientLight
- 环境光介绍
- 构造器
- 环境光常用属性和函数
- 点光源PointLight
- 点光源介绍
- 点光源常用属性
- 平行光DirectionalLight
- 平行光介绍
- 平行光常用属性
- 半球光
- 半球光介绍
- 半球光常用属性
- 聚光灯
- 聚光灯介绍
- 聚光灯常用属性
- 平面光
- 使用灯光时需要注意的点
- 光影烘培
- 如何辨别别人的效果是否是烘培过的
- 如何烘培
学习ThreeJS的捷径
本段内容会写在0篇以外所有的,本人所编写的Threejs教程中
对,学习ThreeJS有捷径
当你有哪个函数不懂的时候,第一时间去翻一翻文档
当你有哪个效果不会做的时候,第一时间去翻一翻所有的案例,也许就能找到你想要的效果
最重要的一点,就是,绝对不要怕问问题,越怕找找别人问题,你的问题就会被拖的越久
如果你确定要走WebGL/ThreeJS的开发者路线的话,以下行为可以让你更快的学习ThreeJS
- 没事就把所有的文档翻一遍,哪怕看不懂,也要留个印象,至少要知道Threejs有什么
- 没事多看看案例效果,当你记忆的案例效果足够多时,下次再遇到相似问题时,你就有可能第一时间来找对应的案例,能更快解决你自己的问题
- 上述案例不只是官网的案例,郭隆邦技术博客,跃焱邵隼,暮志未晚等站点均有不少优质案例,记得一并收藏
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
产生阴影,该属性放到阴影部分讲解
position
和target
,一个决定平行光的位置,一个决定平行光的照射方向,一般来说常用的方式是,把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图所示,我们创建的半球光,是上面白色下面黑色,如果你的场景需要两种不同的光照颜色渐变的话,半球光可以作为一个选择来用
半球光常用属性
基本上就只需要关注 color
和groundColor
即可,color决定天空的颜色,groundColor决定地面的颜色
聚光灯
聚光灯介绍
这里的聚光灯和现实中的聚光灯是一个概念,包括手电筒,舞台灯等都是聚光灯
聚光灯的照射范围其实就是一个圆锥,圆锥的尖尖处是光源位置,圆锥的高和底面半径决定照射范围
聚光灯看demo更容易理解
聚光灯官方案例
聚光灯常用属性
angle
决定聚光灯的圆锥的开合角度,取值范围是0~ Math.PI/2
castShadow
,后续讲阴影的时候讲解,用于开启灯光的投射阴影
decay
参考上面点光源,距离越远越暗
distance
参考上面点光源,光线照射的距离
intensity
和power
参考上面点光源,光照强度的两种定义
shadow
聚光灯的阴影,后续讲解阴影时讲解
target
,参考上面平行光,target决定光线的照射方向
map
: 聚光灯可以投射一张map下来,如官方的案例中的效果
平面光
平面光目前为止笔者仅写过一个案例,这个光源目前为止笔者没有发现用途,可能在线上展厅中用的到
平面光主要用于模拟一个明亮的平面,如果你刚好需要这样一个明亮的平面,可以使用这种方式来模拟
上述是官方提供的平面光案例
注意:
1. 平面光不产生阴影
2. 平面光仅对:MeshStandard材质和MeshPhysical材质生效,部分模型加载出来是Phong材质,所以注意区分
使用灯光时需要注意的点
- 灯光越多,场景越卡,而且卡顿程度是指数级增长的,所以没有特殊要求的情况下,绝对不要添加过多的灯光
- 一般情况下,场景至少要添加一个环境光,亮度设置低一点,然后再添加一个平行光模拟太阳,或者添加一个点光源模拟灯泡,这是最常见的场景搭建打光
- 添加灯光时,尽量添加一个helper来提示灯光的位置,更方便于调试
光影烘培
这里要涉及一个技术叫 Render To Texture(渲染到纹理)
这个技术主要由做烘培的建模师,以及TA所有,通过可以烘培的软件,将光影效果烘培到你的模型贴图上,来达成极高的光影效果,这个时候,我们只需要把贴图贴到模型上即可,同时场景中不需要添加光源,将贴图贴到emissive上即可,一般导出后,还会存在一张LightMap,贴到lightMap上即可,这些内容在前面介绍StandardMaterial的时候已经介绍过,这里不再赘述
如何辨别别人的效果是否是烘培过的
threejs官网上的作品
这个作品就是烘培后的效果
判断依据1:一般情况下,无论你怎么加灯光,调整灯光,调整光影,都不可能达到这个效果,这种效果基本上就是烘培效果
判断依据2:打开F12,然后打开网络选项卡,如果里面没有内容可以在这里先刷新一下页面
然后随意点开一张png格式的图片,如果图片上面已经带有明显的光影效果,这种的就是已经烘培过的模型
如何烘培
先强调三遍,烘培是美术的工作,烘培是美术的工作,烘培是美术的工作
如果你未来的目标是TA,或者长久从业WebGL,那么烘培技术也是你要学的
烘培的基本要求:
- 你的模型,必须是低模,且必须高质量,如果存在大量点线面不连续或者零零散散,这种的模型烘培下来会大幅加重你的渲染压力,模型面数也必须要低
- 必须展开uv
- 对光影系统和渲染要有一定了解,不懂光影系统的,渲染出来的也未必好看,逼真度未必比普通的实时光影好多少
上述是笔者的粗略了解,如果想深入了解烘培技术,请自行百度 RTT 技术
这篇关于【Threejs基础教程-光影篇】5.1 常用的灯光的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!