聚光灯可以联系到现实中的手电筒
衰减分为:距离衰减和边缘衰减
.decay : Float(控制的是灯光自身的亮度)
The amount the light dims along the distance of the light. Default is 2
.
In context of physically-correct rendering the default value should not be changed.
.distance : Float(距离衰减)
如果非零,那么光强度将会从最大值当前灯光位置处按照距离线性衰减到0。 缺省值为 0.0。
.penumbra : Float(边缘衰减)
聚光锥的半影衰减百分比。在0和1之间的值。 默认值 — 0.0。
距离衰减
关键代码:
//灯光有效距离,默认0表示不衰减
directionalLight.distance = 0;
gui.add(directionalLight, 'distance').min(0).max(100).step(1).name("灯光有效距离");
完整代码:
<template>
<div id="three_div"></div>
</template><script>
import * as dat from 'dat.gui' //界面控制
import * as THREE from "three";
import {
OrbitControls
} from "three/examples/jsm/controls/OrbitControls";
import {
RGBELoader
} from "three/examples/jsm/loaders/RGBELoader"
export default {
name: "HOME",
components: {
// vueQr,
// glHome,
},
data() {
return {};
},
mounted() {
//使用控制器控制3D拖动旋转OrbitControls
//控制3D物体移动//1.创建场景
const scene = new THREE.Scene();
console.log(scene);//2.创建相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
//设置相机位置
camera.position.set(0, 0, 10);
//将相机添加到场景
scene.add(camera);
//添加物体
//创建一个半径为1,经纬度分段数位20的球
const cubeGeometry = new THREE.SphereBufferGeometry(2, 100, 100);
//纹理加载器加载图片
const cubeMaterial = new THREE.MeshStandardMaterial({
//side: THREE.DoubleSide,
});
//根据几何体和材质创建物体
const mesh = new THREE.Mesh(cubeGeometry, cubeMaterial);
//将物体加入到场景
scene.add(mesh);//创建平面几何体
const planeGeometry = new THREE.PlaneBufferGeometry(50, 50);
//创建平面物体
const planeMesh = new THREE.Mesh(planeGeometry, cubeMaterial);
planeMesh.position.set(0, -2, 0);
planeMesh.rotation.x = -Math.PI / 2;
//场景添加平面物体
scene.add(planeMesh);//给场景所有的物体添加默认的环境贴图
//添加坐标轴辅助器
const axesHepler = new THREE.AxesHelper(5);
scene.add(axesHepler);
//标准材质需要借助灯光//添加周围环境灯光(由物体发出的灯光)参数(灯色,强度0-1)
const light = new THREE.AmbientLight(0xFFFFFF, 0.7);
scene.add(light);
//直线光(由光源发出的灯光)
// const directionalLight = new THREE.DirectionalLight(0xFFFFFF, 0.7);
// directionalLight.position.set(10, 10, 10);
// scene.add(directionalLight);
const directionalLight = new THREE.SpotLight(0xFFFFFF, 0.7);
directionalLight.position.set(10, 10, 10);
scene.add(directionalLight);// scene.add(mesh2);
//初始化渲染器
const render = new THREE.WebGLRenderer();
//设置渲染器的尺寸
render.setSize(window.innerWidth, window.innerHeight);
//使用渲染器,通过相机将场景渲染进来//创建轨道控制器,可以拖动,控制的是摄像头
const controls = new OrbitControls(camera, render.domElement);
//设置控制阻尼,让控制器有更真实的效果
controls.enableDamping = true;
//开启投影
//开启渲染器投影
render.shadowMap.enabled = true;
//开启灯光动态投影
directionalLight.castShadow = true;
//开启物体投影
mesh.castShadow = true;
//开启平面接受投影
planeMesh.receiveShadow = true;
//投影模糊度
directionalLight.shadow.radius = 10;
//设置投影的宽度和高度
// directionalLight.shadow.mapSize.set(1024, 1024);//平行光投射相机的属性
// directionalLight.shadow.camera.near= 0.5;
// directionalLight.shadow.camera.far= 500;
// directionalLight.shadow.camera.top= 3;
// directionalLight.shadow.camera.bottom= -2;
// directionalLight.shadow.camera.left= -2;
// directionalLight.shadow.camera.right= 2;
//灯光跟着物体移动而移动
directionalLight.target = mesh;
//directionalLight.angle = Math.PI/10;
//创建gui
const gui = new dat.GUI();
// gui.add(directionalLight.shadow.camera, 'near').min(1).max(25).step(1).name("相机近距离").onChange( () => {
// directionalLight.shadow.camera.updateProjectionMatrix();
// })
gui.add(mesh.position, 'x').min(-30).max(30).step(1).name("移动位置");
gui.add(directionalLight, 'angle').min(0).max(Math.PI/2).step(0.1).name("灯光弧度");
//灯光有效距离,默认0表示不衰减
directionalLight.distance = 0;
gui.add(directionalLight, 'distance').min(0).max(100).step(1).name("灯光有效距离");
//将webgl渲染的canvas内容添加到body上
document.getElementById("three_div").appendChild(render.domElement);//渲染下一帧的时候就会调用回调函数
let renderFun = () => {
//更新阻尼数据
controls.update();
//需要重新绘制canvas画布
render.render(scene, camera);
//监听屏幕刷新(60HZ,120HZ),每次刷新触发一次requestAnimationFrame回调函数
//但是requestAnimationFrame的回调函数注册生命只有一次,因此需要循环注册,才能达到一直调用的效果
window.requestAnimationFrame(renderFun);
};
// window.requestAnimationFrame(renderFun);
renderFun();//画布全屏
window.addEventListener("dblclick", () => {
if (document.fullscreenElement) {
document.exitFullscreen();
} else {
//document.documentElement.requestFullscreen();
render.domElement.requestFullscreen();
}
});//监听画面变化,更新渲染画面,(自适应的大小)
window.addEventListener("resize", () => {
//更新摄像机的宽高比
camera.aspect = window.innerWidth / window.innerHeight;
//更新摄像机的投影矩阵
camera.updateProjectionMatrix();
//更新渲染器宽度和高度
render.setSize(window.innerWidth, window.innerHeight);
//设置渲染器的像素比
render.setPixelRatio(window.devicePixelRatio);
console.log("画面变化了");
});
},
methods: {
paush(animate) {
animate.pause();
},
},
};
</script><style scoped lang="scss">
</style>
效果图:
灯边缘衰减
关键代码:
//边缘衰减
gui.add(directionalLight, 'penumbra').min(0).max(1).step(0.01).name("灯光边缘衰减");
完整代码:
<template>
<div id="three_div"></div>
</template><script>
import * as dat from 'dat.gui' //界面控制
import * as THREE from "three";
import {
OrbitControls
} from "three/examples/jsm/controls/OrbitControls";
import {
RGBELoader
} from "three/examples/jsm/loaders/RGBELoader"
export default {
name: "HOME",
components: {
// vueQr,
// glHome,
},
data() {
return {};
},
mounted() {
//使用控制器控制3D拖动旋转OrbitControls
//控制3D物体移动//1.创建场景
const scene = new THREE.Scene();
console.log(scene);//2.创建相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
//设置相机位置
camera.position.set(0, 0, 10);
//将相机添加到场景
scene.add(camera);
//添加物体
//创建一个半径为1,经纬度分段数位20的球
const cubeGeometry = new THREE.SphereBufferGeometry(2, 100, 100);
//纹理加载器加载图片
const cubeMaterial = new THREE.MeshStandardMaterial({
//side: THREE.DoubleSide,
});
//根据几何体和材质创建物体
const mesh = new THREE.Mesh(cubeGeometry, cubeMaterial);
//将物体加入到场景
scene.add(mesh);//创建平面几何体
const planeGeometry = new THREE.PlaneBufferGeometry(50, 50);
//创建平面物体
const planeMesh = new THREE.Mesh(planeGeometry, cubeMaterial);
planeMesh.position.set(0, -2, 0);
planeMesh.rotation.x = -Math.PI / 2;
//场景添加平面物体
scene.add(planeMesh);//给场景所有的物体添加默认的环境贴图
//添加坐标轴辅助器
const axesHepler = new THREE.AxesHelper(5);
scene.add(axesHepler);
//标准材质需要借助灯光//添加周围环境灯光(由物体发出的灯光)参数(灯色,强度0-1)
const light = new THREE.AmbientLight(0xFFFFFF, 0.7);
scene.add(light);
//直线光(由光源发出的灯光)
// const directionalLight = new THREE.DirectionalLight(0xFFFFFF, 0.7);
// directionalLight.position.set(10, 10, 10);
// scene.add(directionalLight);
const directionalLight = new THREE.SpotLight(0xFFFFFF, 0.7);
directionalLight.position.set(10, 10, 10);
scene.add(directionalLight);// scene.add(mesh2);
//初始化渲染器
const render = new THREE.WebGLRenderer();
//设置渲染器的尺寸
render.setSize(window.innerWidth, window.innerHeight);
//使用渲染器,通过相机将场景渲染进来//创建轨道控制器,可以拖动,控制的是摄像头
const controls = new OrbitControls(camera, render.domElement);
//设置控制阻尼,让控制器有更真实的效果
controls.enableDamping = true;
//开启投影
//开启渲染器投影
render.shadowMap.enabled = true;
//开启灯光动态投影
directionalLight.castShadow = true;
//开启物体投影
mesh.castShadow = true;
//开启平面接受投影
planeMesh.receiveShadow = true;
//投影模糊度
directionalLight.shadow.radius = 10;
//设置投影的宽度和高度
// directionalLight.shadow.mapSize.set(1024, 1024);//平行光投射相机的属性
// directionalLight.shadow.camera.near= 0.5;
// directionalLight.shadow.camera.far= 500;
// directionalLight.shadow.camera.top= 3;
// directionalLight.shadow.camera.bottom= -2;
// directionalLight.shadow.camera.left= -2;
// directionalLight.shadow.camera.right= 2;
//灯光跟着物体移动而移动
directionalLight.target = mesh;
//directionalLight.angle = Math.PI/10;
//创建gui
const gui = new dat.GUI();
// gui.add(directionalLight.shadow.camera, 'near').min(1).max(25).step(1).name("相机近距离").onChange( () => {
// directionalLight.shadow.camera.updateProjectionMatrix();
// })
gui.add(mesh.position, 'x').min(-30).max(30).step(1).name("移动位置");
gui.add(directionalLight, 'angle').min(0).max(Math.PI/2).step(0.1).name("灯光弧度");
//灯光有效距离,默认0表示不衰减
directionalLight.distance = 0;
gui.add(directionalLight, 'distance').min(0).max(100).step(1).name("灯光有效距离");
//边缘衰减
gui.add(directionalLight, 'penumbra').min(0).max(1).step(0.01).name("灯光边缘衰减");
//将webgl渲染的canvas内容添加到body上
document.getElementById("three_div").appendChild(render.domElement);//渲染下一帧的时候就会调用回调函数
let renderFun = () => {
//更新阻尼数据
controls.update();
//需要重新绘制canvas画布
render.render(scene, camera);
//监听屏幕刷新(60HZ,120HZ),每次刷新触发一次requestAnimationFrame回调函数
//但是requestAnimationFrame的回调函数注册生命只有一次,因此需要循环注册,才能达到一直调用的效果
window.requestAnimationFrame(renderFun);
};
// window.requestAnimationFrame(renderFun);
renderFun();//画布全屏
window.addEventListener("dblclick", () => {
if (document.fullscreenElement) {
document.exitFullscreen();
} else {
//document.documentElement.requestFullscreen();
render.domElement.requestFullscreen();
}
});//监听画面变化,更新渲染画面,(自适应的大小)
window.addEventListener("resize", () => {
//更新摄像机的宽高比
camera.aspect = window.innerWidth / window.innerHeight;
//更新摄像机的投影矩阵
camera.updateProjectionMatrix();
//更新渲染器宽度和高度
render.setSize(window.innerWidth, window.innerHeight);
//设置渲染器的像素比
render.setPixelRatio(window.devicePixelRatio);
console.log("画面变化了");
});
},
methods: {
paush(animate) {
animate.pause();
},
},
};
</script><style scoped lang="scss">
</style>
效果图:
衰减量(属于距离衰减,衰减量越大,距离越近)
关键代码:
//灯光衰减量控制
directionalLight.decay = 2;
gui.add(directionalLight, 'decay').min(-5).max(5).step(1).name("灯光衰减量");
//需要渲染器开启物理渲染
render.physicallyCorrectLights =true;
完整代码:
<template>
<div id="three_div"></div>
</template><script>
import * as dat from 'dat.gui' //界面控制
import * as THREE from "three";
import {
OrbitControls
} from "three/examples/jsm/controls/OrbitControls";
import {
RGBELoader
} from "three/examples/jsm/loaders/RGBELoader"
export default {
name: "HOME",
components: {
// vueQr,
// glHome,
},
data() {
return {};
},
mounted() {
//使用控制器控制3D拖动旋转OrbitControls
//控制3D物体移动//1.创建场景
const scene = new THREE.Scene();
console.log(scene);//2.创建相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
//设置相机位置
camera.position.set(0, 0, 10);
//将相机添加到场景
scene.add(camera);
//添加物体
//创建一个半径为1,经纬度分段数位20的球
const cubeGeometry = new THREE.SphereBufferGeometry(2, 100, 100);
//纹理加载器加载图片
const cubeMaterial = new THREE.MeshStandardMaterial({
//side: THREE.DoubleSide,
});
//根据几何体和材质创建物体
const mesh = new THREE.Mesh(cubeGeometry, cubeMaterial);
//将物体加入到场景
scene.add(mesh);//创建平面几何体
const planeGeometry = new THREE.PlaneBufferGeometry(50, 50);
//创建平面物体
const planeMesh = new THREE.Mesh(planeGeometry, cubeMaterial);
planeMesh.position.set(0, -2, 0);
planeMesh.rotation.x = -Math.PI / 2;
//场景添加平面物体
scene.add(planeMesh);//给场景所有的物体添加默认的环境贴图
//添加坐标轴辅助器
const axesHepler = new THREE.AxesHelper(5);
scene.add(axesHepler);
//标准材质需要借助灯光//添加周围环境灯光(由物体发出的灯光)参数(灯色,强度0-1)
const light = new THREE.AmbientLight(0xFFFFFF, 0.7);
scene.add(light);
//直线光(由光源发出的灯光)
// const directionalLight = new THREE.DirectionalLight(0xFFFFFF, 0.7);
// directionalLight.position.set(10, 10, 10);
// scene.add(directionalLight);
const directionalLight = new THREE.SpotLight(0xFFFFFF, 0.7);
directionalLight.position.set(10, 10, 10);
scene.add(directionalLight);// scene.add(mesh2);
//初始化渲染器
const render = new THREE.WebGLRenderer();
//设置渲染器的尺寸
render.setSize(window.innerWidth, window.innerHeight);
//使用渲染器,通过相机将场景渲染进来//创建轨道控制器,可以拖动,控制的是摄像头
const controls = new OrbitControls(camera, render.domElement);
//设置控制阻尼,让控制器有更真实的效果
controls.enableDamping = true;
//开启投影
//开启渲染器投影
render.shadowMap.enabled = true;
//开启灯光动态投影
directionalLight.castShadow = true;
//开启物体投影
mesh.castShadow = true;
//开启平面接受投影
planeMesh.receiveShadow = true;
//投影模糊度
directionalLight.shadow.radius = 10;
//设置投影的宽度和高度
// directionalLight.shadow.mapSize.set(1024, 1024);//平行光投射相机的属性
// directionalLight.shadow.camera.near= 0.5;
// directionalLight.shadow.camera.far= 500;
// directionalLight.shadow.camera.top= 3;
// directionalLight.shadow.camera.bottom= -2;
// directionalLight.shadow.camera.left= -2;
// directionalLight.shadow.camera.right= 2;
//灯光跟着物体移动而移动
directionalLight.target = mesh;
//directionalLight.angle = Math.PI/10;
//创建gui
const gui = new dat.GUI();
// gui.add(directionalLight.shadow.camera, 'near').min(1).max(25).step(1).name("相机近距离").onChange( () => {
// directionalLight.shadow.camera.updateProjectionMatrix();
// })
gui.add(mesh.position, 'x').min(-30).max(30).step(1).name("移动位置");
gui.add(directionalLight, 'angle').min(0).max(Math.PI/2).step(0.1).name("灯光弧度");
//灯光有效距离,默认0表示不衰减
directionalLight.distance = 0;
gui.add(directionalLight, 'distance').min(0).max(100).step(1).name("灯光有效距离");
//边缘衰减
gui.add(directionalLight, 'penumbra').min(0).max(1).step(0.01).name("灯光边缘衰减");
//灯光强度控制
directionalLight.decay = 2;
gui.add(directionalLight, 'decay').min(-5).max(5).step(1).name("灯光边缘衰减");
//需要渲染器开启物理渲染
render.physicallyCorrectLights =true;//将webgl渲染的canvas内容添加到body上
document.getElementById("three_div").appendChild(render.domElement);//渲染下一帧的时候就会调用回调函数
let renderFun = () => {
//更新阻尼数据
controls.update();
//需要重新绘制canvas画布
render.render(scene, camera);
//监听屏幕刷新(60HZ,120HZ),每次刷新触发一次requestAnimationFrame回调函数
//但是requestAnimationFrame的回调函数注册生命只有一次,因此需要循环注册,才能达到一直调用的效果
window.requestAnimationFrame(renderFun);
};
// window.requestAnimationFrame(renderFun);
renderFun();//画布全屏
window.addEventListener("dblclick", () => {
if (document.fullscreenElement) {
document.exitFullscreen();
} else {
//document.documentElement.requestFullscreen();
render.domElement.requestFullscreen();
}
});//监听画面变化,更新渲染画面,(自适应的大小)
window.addEventListener("resize", () => {
//更新摄像机的宽高比
camera.aspect = window.innerWidth / window.innerHeight;
//更新摄像机的投影矩阵
camera.updateProjectionMatrix();
//更新渲染器宽度和高度
render.setSize(window.innerWidth, window.innerHeight);
//设置渲染器的像素比
render.setPixelRatio(window.devicePixelRatio);
console.log("画面变化了");
});
},
methods: {
paush(animate) {
animate.pause();
},
},
};
</script><style scoped lang="scss">
</style>
效果图: