前言
本篇继续给大家分享一下在three.js中,环境光(AmbientLight),平行光(DirectionalLight),点光源(PointLight),聚光灯(SpotLight)在项目中如何去使用
首先在上一篇 Three.js加载外部glb,fbx,gltf,obj,stl模型文件 的文章基础上
新加入一个创建灯光的函数 createLight 方法
// 创建光源
createLight() {
// 创建环境光
this.ambientLight = new THREE.AmbientLight('#fff', .8)
this.ambientLight.visible = true
this.scene.add(this.ambientLight)
// 创建平行光
this.directionalLight = new THREE.DirectionalLight('#1E90FF', 1)
this.directionalLight.position.set(-1.44, 2.2, 1)
this.directionalLight.castShadow = true
this.directionalLight.visible = false
this.scene.add(this.directionalLight)
// 创建平行光辅助线
this.directionalLightHelper = new THREE.DirectionalLightHelper(this.directionalLight, .5)
this.directionalLightHelper.visible = false
this.scene.add(this.directionalLightHelper)
// 创建点光源
this.pointLight = new THREE.PointLight(0xff0000, 1, 100)
this.pointLight.visible = false
this.scene.add(this.pointLight)
// 创建点光源辅助线
this.pointLightHelper = new THREE.PointLightHelper(this.pointLight, .5)
this.pointLightHelper.visible = false
this.scene.add(this.pointLightHelper)
// 创建聚光灯
this.spotLight = new THREE.SpotLight('#323636', 440);
this.spotLight.visible = false
this.spotLight.map = new THREE.TextureLoader().load(require('@/assets/image/model-bg-1.jpg'));
this.spotLight.decay = 2;
this.spotLight.shadow.mapSize.width = 1920;
this.spotLight.shadow.mapSize.height = 1080;
this.spotLight.shadow.camera.near = 1;
this.spotLight.shadow.camera.far = 10;
this.scene.add(this.spotLight);
//创建聚光灯辅助线
this.spotLightHelper = new THREE.SpotLightHelper(this.spotLight);
this.spotLightHelper.visible = false
this.scene.add(this.spotLightHelper)
// 创建一个光源平面
const geometry = new THREE.PlaneGeometry(4, 4);
var groundMaterial = new THREE.MeshStandardMaterial({ color: '#939393' });
this.planeGeometry = new THREE.Mesh(geometry, groundMaterial);
this.planeGeometry.rotation.x = -Math.PI / 2
this.planeGeometry.position.set(0, -.59, 0)
// 让地面接收阴影
this.planeGeometry.receiveShadow = true;
this.planeGeometry.visible = true
this.scene.add(this.planeGeometry);
}
如何去动态的修改灯光和辅助线的参数信息?
一.首先根据对应的灯光配置添加不同的四个函数方法:
- 修改环境光参数方法:onSetModelAmbientLight
- 修改平行光参数方法:onSetModelDirectionalLight
- 修改点光源参数方法:onSetModelPointLight
- 修改聚光灯参数方法:onSetModelSpotLight
import { lightPosition } from '@/utils/utilityFunction'
// 设置环境光
function onSetModelAmbientLight({ ambientLight, ambientLightColor, ambientLightIntensity }) {
this.ambientLight.visible = ambientLight
this.ambientLight.intensity = ambientLightIntensity
this.ambientLight.color.set(ambientLightColor)
}
// 设置平行光
function onSetModelDirectionalLight(config) {
const { directionaShadow, directionalHorizontal, directionalVertical, directionalSistance, directionalLight, directionalLightColor, directionalLightIntensity, directionalLightHelper } = config
this.directionalLight.visible = directionalLight
this.directionalLightHelper.visible = directionalLightHelper && directionalLight
this.directionalLight.intensity = directionalLightIntensity
this.directionalLight.castShadow = directionaShadow
this.directionalLight.color.set(directionalLightColor)
const { x, y, z } = lightPosition(directionalHorizontal, directionalVertical, directionalSistance)
this.directionalLight.position.set(x, y, z)
this.directionalLightHelper.update()
}
// 设置点光源
function onSetModelPointLight(config) {
const { pointHorizontal, pointVertical, pointSistance, pointLight, pointLightColor, pointLightIntensity, pointLightHelper } = config
this.pointLight.visible = pointLight
this.pointLightHelper.visible = pointLight && pointLightHelper
this.pointLight.intensity = pointLightIntensity
this.pointLight.color.set(pointLightColor)
const { x, y, z } = lightPosition(pointHorizontal, pointVertical, pointSistance)
this.pointLight.position.set(x, y, z)
this.pointLightHelper.update()
}
// 设置聚光灯
function onSetModelSpotLight(config) {
const { spotDistance, spotCastShadow, spotLightHelper, spotFocus, spotPenumbra, spotAngle, spotLight, spotLightColor, spotLightIntensity, spotHorizontal, spotVertical, spotSistance } = config
this.spotLight.visible = spotLight
this.spotLightHelper.visible = spotLight && spotLightHelper
this.spotLight.intensity = spotLightIntensity
this.spotLight.angle = spotAngle
this.spotLight.penumbra = spotPenumbra
this.spotLight.shadow.focus = spotFocus
this.spotLight.castShadow = spotCastShadow
this.spotLight.distance = spotDistance
this.spotLight.color.set(spotLightColor)
const { x, y, z } = lightPosition(spotHorizontal, spotVertical, spotSistance)
this.spotLight.position.set(x, y, z)
this.spotLightHelper.update()
}
二.封装一个修改灯光位置(position)的方法 lightPosition
/**
* 计算光源垂直和水平方向的定位
*
* @param {Number} horizontal 水平方向值
* @param {Number} vertical 垂直方向值
* @param {Number} distance 光源距离
* @return {x , y , z} 返回光源坐标轴位置
*/
export function lightPosition(horizontal, vertical, distance) {
const x = distance * Math.sin(horizontal) * Math.cos(vertical);
const y = distance * Math.sin(vertical);
const z = distance * Math.cos(horizontal) * Math.cos(vertical);
return {x,y,z}
}
三.在页面中去使用
<script setup>
import { reactive, computed } from "vue";
const store = useMeshEditStore();
const config = reactive({
//光源平面
planeGeometry: false,
planeColor: "#000000",
planeWidth: 7,
planeHeight: 7,
//环境光
ambientLight: true,
ambientLightColor: "#fff",
ambientLightIntensity: 0.8,
//平行光
directionalLight: false,
directionalLightHelper: true,
directionalLightColor: "#fff",
directionalLightIntensity: 5,
directionalHorizontal: -1.26,
directionalVertical: -3.85,
directionalSistance: 2.98,
directionaShadow: true,
//点光源
pointLight: false,
pointLightHelper: true,
pointLightColor: "#1E90FF",
pointLightIntensity: 10,
pointHorizontal: -4.21,
pointVertical: -4.1,
pointSistance: 2.53,
//聚光灯
spotLight: false,
spotLightColor: "#00BABD",
spotLightIntensity: 900,
spotHorizontal: -3.49,
spotVertical: -4.37,
spotSistance: 4.09,
spotAngle: 0.5,
spotPenumbra: 1,
spotFocus: 1,
spotCastShadow: true,
spotLightHelper: true,
spotDistance: 20
});
const state = reactive({
modelApi: computed(() => store.modelApi)
});
// 设置环境光
const onChangeAmbientLight = () => {
state.modelApi.onSetModelAmbientLight(config);
};
// 设置平行光
const onChangeDirectionalLight = () => {
if (config.directionalLight) {
config.planeGeometry = true;
state.modelApi.onSetModelPlaneGeometry(config);
}
state.modelApi.onSetModelDirectionalLight(config);
};
// 设置点光源
const onChangePointLight = () => {
state.modelApi.onSetModelPointLight(config);
};
// 设置聚光灯
const onChangeSpotLight = () => {
if (config.spotLight) {
config.planeGeometry = true;
state.modelApi.onSetModelPlaneGeometry(config);
}
state.modelApi.onSetModelSpotLight(config);
};
<script>
完整的代码可参考:gitee.com/ZHANG_6666/…
界面效果: