光源
为了模拟物体在不同情况下的样式,three.js中提供了多种光源。需要注意光源和材质是相互的,简单来说物体表面的颜色是光源和材质的乘积。在材质中的基础材质是不受灯光影响的。
创建基本场景
import * as THREE from 'https://threejs.org/build/three.module.js'
import { OrbitControls } from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/examples/jsm/controls/OrbitControls.js'
const canvas = document.querySelector('#c2d')
// 渲染器
const renderer = new THREE.WebGLRenderer({ canvas })
const fov = 40 // 视野范围
const aspect = 2 // 相机默认值 画布的宽高比
const near = 0.1 // 近平面
const far = 1000 // 远平面
// 透视投影相机
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
camera.position.set(0, 10, 20)
camera.lookAt(0, 0, 0)
// 控制相机
const controls = new OrbitControls(camera, canvas)
controls.update()
// 场景
const scene = new THREE.Scene()
scene.background = new THREE.Color('white')
{
// 地面 平铺
const planeSize = 20
const loader = new THREE.TextureLoader()
const texture = loader.load('https://threejs.org/manual/examples/resources/images/checker.png')
// THREE.RepeatWrapping 纹理重复
texture.wrapS = THREE.RepeatWrapping
texture.wrapT = THREE.RepeatWrapping
// 当一个纹素覆盖大于一个像素时,贴图将如何采样。 THREE.NearestFilter,它将使用最接近的纹素的值。
texture.magFilter = THREE.NearestFilter
const repeats = planeSize / 2
// 重复次数
texture.repeat.set(repeats, repeats)
const planeGeo = new THREE.PlaneGeometry(planeSize, planeSize)
// Phong材质
const planeMat = new THREE.MeshPhongMaterial({
map: texture,
side: THREE.DoubleSide
})
const mesh = new THREE.Mesh(planeGeo, planeMat)
mesh.rotation.x = Math.PI * -0.5
scene.add(mesh)
}
{
// 方块
const cubeSize = 4
const cubeGeo = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize)
// Phong材质
const cubeMat = new THREE.MeshPhongMaterial({ color: '#8f4b2e' })
const mesh = new THREE.Mesh(cubeGeo, cubeMat)
mesh.position.y = 2
scene.add(mesh)
}
// 渲染
function render() {
renderer.render(scene, camera)
requestAnimationFrame(render)
}
requestAnimationFrame(render)
这里使用了纹理重复创建地板,要了解具体使用可以去看前面的文章。使用Phong材质,在没有灯光的情况下,渲染的物体都是黑色。
环境光 AmbientLight
只是简单地将材质的颜色与光源颜色进行相乘,再乘以光照强度。所以只使用环境光,场景内的物体看起来没有立体感。环境光,它没有方向,无法产生阴影,场景内任何一点受到的光照强度都是相同的。
{
const color = 0xffffff
const intensity = 1
const light = new THREE.AmbientLight(color, intensity)
scene.add(light)
}
半球光 HemisphereLight
颜色是从天空到地面两个颜色之间的渐变,与物体材质的颜色相乘后得到最终的颜色效果。一般都是与其他光源一起使用。
{
const skyColor = 0xb1e1ff // 天空 蓝色
const groundColor = 0xffffff // 地面白色
const intensity = 1
const light = new THREE.HemisphereLight(skyColor, groundColor, intensity)
scene.add(light)
}
方向光 DirectionalLight
方向光表示的是来自一个方向上的光,并不是从某个点发射出来的,而是从一个无限大的平面内,发射出全部相互平行的光线。一般用于模仿太阳光。
{
const color = 0xffffff
const intensity = 1
const light = new THREE.DirectionalLight(color, intensity)
light.position.set(0, 10, 10)
scene.add(light)
// 光源辅助线
const helper = new THREE.DirectionalLightHelper(light)
scene.add(helper)
}
为了能更好的观看光源,这里修该背景为黑色,使用.DirectionalLightHelper()生成方向光辅助线。
点光源 PointLight
表示的是从一个点朝各个方向发射出光线的一种光照效果。一般用于模拟电灯。
{
const color = 0xffffff
const intensity = 1
const light = new THREE.PointLight(color, intensity)
light.position.set(0, 5, 10)
scene.add(light)
// 光源辅助线
const helper = new THREE.PointLightHelper(light)
scene.add(helper)
}
使用.PointLightHelper()生成点光源辅助线。
光源强度
在WebGLRenderer中有一个设置项 .physicallyCorrectLights。开启后可设置随着离光源的距离增加光照如何减弱。点光源和聚光灯等灯光受其影响。在光源上有两个属性。.power以"流明(光通量单位)"为单位的光功率,.decay沿着光照距离的衰退量,默认值1。
renderer.physicallyCorrectLights = true
// 点光源修改
light.power = 800
light.decay = 2
总结
本节介绍了一些常用的光源,在开发中光源是配合使用的。不过需要注意每添加一个光源到场景中,都会降低 three.js渲染的速度,所以要根据需求来判断添加多少光源实现最好的效率。
|