Matrix 矩阵 controls 控制 PerspectiveCamera 透视相机
axesHelper 轴帮助器 hesLight hes浅 updateProjectionMatrix 更新投影矩阵
dirLight 方向灯 boxes 盒 intensity 强烈
Meshes 网格 Lambert 兰伯特 enableShadow 启用阴影
enable 使可能 Shadow 阴影 ShadowMaterial 阴影材质
shadowMap 阴影贴图 receiveShadow 接收阴影 cast 铸造
physics 物理学 shperes 球体 detai 详细信息
import * as THREE from "three";
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { OimoPhysics } from 'three/examples/jsm/physics/OimoPhysics'
let camera, scene, renderer;
let axesHelper;
let hesLight, dirLight; // 光
let floor, boxes, spheres;
let controls;
let physics;
let position = new THREE.Vector3();
initRenderer()
initCamera()
initScene()
initLight()
initMeshes()
initAxesHelper()
initControls()
enableShadow()
await enablePhysics()
animate()
window.addEventListener('resize', function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
})
function initRenderer() {
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.outputEncoding = THREE.sRGBEncoding;
document.body.appendChild(renderer.domElement)
}
// 创建 相机
function initCamera() {
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.01, 1000)
camera.position.set(2, 2, 12)
}
// 创建 场景
function initScene() {
scene = new THREE.Scene()
scene.background = new THREE.Color(0x888888)
}
// 辅助线
function initAxesHelper() {
axesHelper = new THREE.AxesHelper(1)
scene.add(axesHelper)
}
// 初始化 光
function initLight() {
// 环境光
hesLight = new THREE.HemisphereLight() // 白色光
hesLight.intensity = 0.3
scene.add(hesLight)
// 平行光(太阳光)
dirLight = new THREE.DirectionalLight()
dirLight.position.set(5, 5, -5)
scene.add(dirLight)
}
// 创建 物体(材质+架子)
function initMeshes() {
// 设置地板(为了接受影子的存在)
floor = new THREE.Mesh(
new THREE.BoxGeometry(10, 1, 10),
new THREE.ShadowMaterial({ color: 0x111111 }) //阴影的颜色
)
floor.position.set(0, -1, 0)
scene.add(floor)
// 正方形
boxes = new THREE.InstancedMesh(
new THREE.BoxGeometry(0.1, 0.1, 0.1),
new THREE.MeshLambertMaterial(), // 对镜面的反色不好,如木头
100
)
boxes.instanceMatrix.setUsage(THREE.DynamicDrawUsage) //提高画质
const color = new THREE.Color()
const matrix = new THREE.Matrix4()
for (let i = 0; i < boxes.count; i++) {
matrix.setPosition(
Math.random() - 0.5, // x: -0.5 ~ 0.5
Math.random() * 2, // 0 ~ 2
Math.random() - 0.5)// - 0.5 ~ 0.5
boxes.setMatrixAt(i, matrix)
boxes.setColorAt(i, color.setHex(Math.random() * 0xffffff))
}
scene.add(boxes)
// 球
spheres = new THREE.InstancedMesh(
new THREE.IcosahedronGeometry(0.075, 3),
new THREE.MeshBasicMaterial(),
50
)
spheres.instanceMatrix.setUsage(THREE.DynamicDrawUsage) //提高画质
for (let i = 0; i < spheres.count; i++) {
matrix.setPosition(
Math.random() - 0.5, // x: -0.5 ~ 0.5
Math.random() * 2, // 0 ~ 2
Math.random() - 0.5)// - 0.5 ~ 0.5
spheres.setMatrixAt(i, matrix)
spheres.setColorAt(i, color.setHex(Math.random() * 0xffffff))
}
scene.add(spheres)
}
// 设置阴影
function enableShadow() {
renderer.shadowMap.enabled = true
dirLight.castShadow = true
dirLight.shadow.camera.zoom = 2 // 控制灯光阴影范围的大小
floor.receiveShadow = true
boxes.castShadow = true
boxes.receiveShadow = true
spheres.castShadow = true
spheres.receiveShadow = true
}
// 启用物理 OimoPhysics是一个异步方法(async, await)
async function enablePhysics() {
physics = await OimoPhysics()
physics.addMesh(floor)
physics.addMesh(boxes, 1)
physics.addMesh(spheres, 1)
}
// 控制(轨道)
function initControls() {
controls = new OrbitControls(camera, renderer.domElement)
}
function animate() {
renderer.render(scene, camera)
let index = Math.floor(Math.random() * boxes.count)
position.set(0, Math.random() + 1, 0)
physics.setMeshPosition(boxes, position, index)
index = Math.floor(Math.random() * spheres.count)
position.set(0, Math.random() + 1, 0)
physics.setMeshPosition(spheres, position, index)
requestAnimationFrame(animate)
}
浙公网安备 33010602011771号