效果
![在这里插入图片描述](https://img-blog.csdnimg.cn/97439a9ebc4e487897af8710c5b12382.png#pic_center)
源码
import * as T from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { AsciiEffect } from 'three/examples/jsm/effects/AsciiEffect'
import { useState, useEffect, useRef } from 'react'
import Stats from 'stats.js'
import { GUI } from 'dat.gui'
const Demo1 = () => {
let stats, scene, camera, renderer, axes, plane, orbitControls, gui, controls, effect
useEffect(() => {
init()
}, [])
const ThreeContainer = useRef()
// 创建界面组件,修改代码中的变量
const initGui = () => {
controls = {
rotationSpeed: 0.01
}
gui = new GUI()
// 旋转速度为0~0.1
gui.add(controls, 'rotationSpeed', 0, 0.1)
}
// 检测动画运行的帧频
const initStats = () => {
stats = new Stats()
stats.showPanel(1)
ThreeContainer.current.append(stats.dom)
}
// 场景,作为容器,保存并跟踪所有渲染的物体
const initScene = () => {
scene = new T.Scene()
}
// 相机
const initCamera = () => {
camera = new T.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(-30, 40, 30)
camera.lookAt(scene.position)
}
// 渲染器,计算指定相机角度下,浏览器中scene的样子
const initRenderer = () => {
renderer = new T.WebGLRenderer()
renderer.setClearColor(0xeeeeee)
renderer.setSize(window.innerWidth, window.innerHeight)
// 允许阴影映射
renderer.shadowMap.enabled = true
// 将render的输出挂载到HTML页面框架中的元素上
ThreeContainer.current.append(renderer.domElement)
// Ascii风格化
// effect = new AsciiEffect(renderer)
// effect.setSize(window.innerWidth, window.innerHeight)
// ThreeContainer.current.append(effect.domElement)
}
// 坐标轴
const initAxes = () => {
axes = new T.AxesHelper(20)
scene.add(axes)
}
// 控制器
const initOrbitControls = () => {
}
// 创建平面
const createPlane = () => {
const planeGeometry = new T.PlaneGeometry(60, 20, 1, 1)
// const planeMaterial = new T.MeshBasicMaterial({
// color: 0xffffff
// })
const planeMaterial = new T.MeshLambertMaterial({
color: 0xffffff
})
plane = new T.Mesh(planeGeometry, planeMaterial)
plane.rotation.x = -0.5 * Math.PI
plane.position.set(15, 0, 0)
// 接受阴影
plane.receiveShadow = true
scene.add(plane)
}
// 创建立方体
const createBox = () => {
const boxGeometry = new T.BoxGeometry(4, 4, 4)
// 基础材质,对光源不产生反应,整体颜色不变
const boxBasicMaterial = new T.MeshBasicMaterial({
color: 0xff0000,
// 开启线框
wireframe: true
})
const boxBasic = new T.Mesh(boxGeometry, boxBasicMaterial)
boxBasic.position.set(-4, 3, 0)
// 光源材质
// const boxLambertMaterial = new T.MeshLambertMaterial({
// color: 0xff0000,
// })
// const boxLambert = new T.Mesh(boxGeometry, boxLambertMaterial)
// boxLambert.position.set(-10, 3, 0)
// 高光材质
// const boxPhongMaterial = new T.MeshPhongMaterial({
// color: 0xff0000,
// })
// const boxPhong = new T.Mesh(boxGeometry, boxPhongMaterial)
// boxPhong.position.set(2, 3, 0)
scene.add(boxBasic)
// scene.add(boxLambert)
// scene.add(boxPhong)
}
// 创建球体
const createSphere = () => {
const sphereGeometry = new T.SphereGeometry(4, 20, 20)
const sphereMaterial = new T.MeshBasicMaterial({
color: 0x7777ff,
wireframe: true
})
const sphere = new T.Mesh(sphereGeometry, sphereMaterial)
sphere.position.set(20, 4, 2)
// 产生阴影
sphere.castShadow = true
scene.add(sphere)
}
// 添加光源
const addLight = () => {
const spotLight = new T.SpotLight(0xffffff)
spotLight.position.set(-40, 60, -10)
spotLight.castShadow = true
scene.add(spotLight)
}
// 渲染场景
const renderScene = () => {
stats.update()
plane.rotation.z += controls.rotationSpeed
// 以一定的时间间隔进行渲染
requestAnimationFrame(renderScene)
renderer.render(scene, camera)
// Ascii渲染替换renderer渲染
// effect.render(scene, camera)
}
// 初始化
const init = () => {
initStats()
initGui()
initScene()
initCamera()
initRenderer()
initAxes()
createPlane()
createBox()
createSphere()
addLight()
renderScene()
}
return (
<div ref={ThreeContainer} />
)
}
export default Demo1```