THREEJS灯光 阴影 雾化 GUI

115 阅读2分钟

基础光

image.png

特殊光

image.png

image.png

聚光灯光源

new THREE.SpotLight(color?: ColorRepresentation,intensity?: number,distance?: number,angle?: number,penumbra?: number,decay?: number,)

image.png

import { onMounted, ref } from 'vue';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';


const canvasbox = ref(null)

// 创建场景
var scene = new THREE.Scene();

// 创建相机
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

// 创建渲染器
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建立方体
var geometry = new THREE.BoxGeometry();
var material = new THREE.MeshPhongMaterial({ color: 0xff0000 });
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// 创建球体
const spherGeometry = new THREE.SphereGeometry(1, 30, 30)
const spherMaterial = new THREE.MeshBasicMaterial({ color: '#f00', wireframe: true })
const spherCube = new THREE.Mesh(spherGeometry, spherMaterial)
spherCube.position.set(1, 2, 0)
scene.add(spherCube)

// 创建光源
var light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(-10, 10, 90)
scene.add(light);

// 创建阴影
const planeGeometry = new THREE.PlaneGeometry(10, 20)
const planeMaterial = new THREE.MeshBasicMaterial({ color: 0x999999 })
const planCube = new THREE.Mesh(planeGeometry, planeMaterial)
planCube.rotateZ(20)
planCube.position.x = 3
planCube.position.z = -10
scene.add(planCube)

// 添加阴影
planCube.receiveShadow = true
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
cube.castShadow = true;
light.castShadow = true;

// 添加雾化效果
scene.fog = new THREE.Fog(0x999999,1,100)

const control = new OrbitControls(camera, renderer.domElement)
control.addEventListener('change', () => {
  renderer.render(scene, camera)
})

// 渲染循环
function animate() {
  requestAnimationFrame(animate);

  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;

  spherCube.rotation.x += 0.01
  spherCube.rotation.y += 0.01

  renderer.render(scene, camera);
}
animate();

1.gif

GUI

import { onMounted, ref } from 'vue';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min.js";


const canvasbox = ref(null)

// 创建场景
var scene = new THREE.Scene();

// 创建相机
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

// 创建渲染器
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建立方体
var geometry = new THREE.BoxGeometry();
var material = new THREE.MeshPhongMaterial({ color: 0xff0000 });
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// 创建球体
const spherGeometry = new THREE.SphereGeometry(1, 30, 30)
const spherMaterial = new THREE.MeshBasicMaterial({ color: '#f00', wireframe: true })
const spherCube = new THREE.Mesh(spherGeometry, spherMaterial)
spherCube.position.set(1, 2, 0)
scene.add(spherCube)

// 创建光源
var light = new THREE.SpotLight(0xffffff,1);
light.position.set(-1, 2, 4)
light.intensity = 50
scene.add(light);

// 创建阴影
const planeGeometry = new THREE.PlaneGeometry(10, 20)
const planeMaterial = new THREE.MeshBasicMaterial({ color: 0x999999 })
const planCube = new THREE.Mesh(planeGeometry, planeMaterial)
planCube.rotateZ(20)
planCube.position.x = 3
planCube.position.z = -10
scene.add(planCube)

// 添加阴影
planCube.receiveShadow = true
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
cube.castShadow = true;
light.castShadow = true;


// 添加雾化效果
scene.fog = new THREE.Fog(0x999999, 1, 100)

const controls = new OrbitControls(camera, renderer.domElement)
// controls.enableDamping = true;
// // 设置阻尼系数
// controls.dampingFactor = 0.05;
// // 设置旋转速度
// // controls.autoRotate = true;
// controls.autoRotateSpeed = 10;


// 添加世界坐标辅助器
// const axesHelper = new THREE.AxesHelper(5);
// scene.add(axesHelper);

// 渲染循环
function animate() {
  controls.update()
  requestAnimationFrame(animate);

  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;

  spherCube.rotation.x += 0.01
  spherCube.rotation.y += 0.01

  renderer.render(scene, camera);
}
animate();

window.addEventListener('resize', () => {
  // 重置渲染器宽高比
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 重置相机宽高比
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新相机投影矩阵
  camera.updateProjectionMatrix();
})

const gui = new GUI()

let cubePositionFolder = gui.addFolder("盒子定位");
cubePositionFolder.add(cube.position, "x", -10, 10, 1).name("x");
cubePositionFolder.add(cube.position, "y", -10, 10, 1).name("y");
cubePositionFolder.add(cube.position, "z", -10, 10, 1).name("z");


const lightFolder = gui.addFolder('光源');
lightFolder.add(light.position, 'x', -100, 100).onChange((value) => {
  light.position.x = value;
});
lightFolder.add(light.position, 'y', -100, 100).onChange((value) => {
  light.position.y = value;
});
lightFolder.add(light.position, 'z', -100, 100).onChange((value) => {
  light.position.z = value;
});
lightFolder.add(light, 'intensity', 0, 100).onChange((value) => {
  light.intensity = value;
});
lightFolder.add(light, 'distance', 0, 100).onChange((value) => {
  light.distance = value;
});

const obj = {
  color: 0x00ffff,
};
// .addColor()生成颜色值改变的交互界面
gui.addColor(obj, 'color').onChange(function (value) {
  console.log(value,material);
  material.color.set(value);
  spherMaterial.color.set(value);
});

录屏2024-04-26 16.40.40.gif