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)
}
posted on 2022-10-27 16:14  最贵不过坚持  阅读(144)  评论(0)    收藏  举报