import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
`导入 - lil.gui`
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'
const scence = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(0, 0, 10)
const renderer = new THREE.WebGLRenderer({
antialias: true
})
renderer.shadowMap.enabled = true
renderer.toneMapping = THREE.ReinhardToneMapping
renderer.toneMappingExposure = 1
renderer.setSize(window.innerWidth / 2, window.innerHeight / 2)
document.body.appendChild(renderer.domElement)
const axesHelper = new THREE.AxesHelper(5)
scence.add(axesHelper)
const gridHelper = new THREE.GridHelper(50, 50)
gridHelper.material.transparent = true
gridHelper.material.opacity = 0.3
scene.add(gridHelper)
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
controls.dampingFactor = 0.01
controls.autoRotate = true `开启后,相机绕着y轴,顺时针自动旋转`
function render() {
controls.update()
requestAnimationFrame(render)
renderer.render(scence, camera)
}
render()
let rgbeLoader = new RGBELoader()
rgbeLoader.load('../public/assets/texture/Alex_Hart-Nature_Lab_Bones_2k.hdr', envMap => {
envMap.mapping = THREE.EquirectangularRefractionMapping
scene.background = new THREE.Color(0xcccccc)
scene.environment = envMap
})
const gltfLoader = new GLTFLoader()
const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('../public/draco/')
gltfLoader.setDRACOLoader(dracoLoader)
gltfLoader.load('../public/assets/model/house/house-scene-min.glb', gltf => {
basicScene = gltf.scene
})
---------------------------------------------------------------------------------------------------
let basicScene
let eventObj = {
addScene: () => scene.add(basicScene),
isLight: true `开关灯效果`
}
---------------------------------------------------------------------------------------------------
const gui = new GUI()
gui.add(eventObj, 'addScene').name('添加户型基础模型')
gui.add(eventObj, 'isLight')
.name('开关灯')
.onChange(value => {
if (value) {
renderer.toneMappingExposure = 1
} else {
renderer.toneMappingExposure = 0.1
}
})
`引入three.js`
import * as THREE from 'three'
`导入 - 轨道控制器`
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
`导入 - hdr加载器`
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js'
`导入 - gltf加载器`
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
`导入 - draco解码器`
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
`导入 - lil.gui`
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'
【场景】
const scence = new THREE.Scene()
【相机】`视角、宽高比、近平面、远平面]`
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(0, 0, 10)
【渲染器】
const renderer = new THREE.WebGLRenderer({
antialias: true `【抗锯齿】`
})
renderer.shadowMap.enabled = true `阴影`
renderer.toneMapping = THREE.ReinhardToneMapping `色调映射`
renderer.toneMappingExposure = 1 `色调映射的曝光度`
renderer.setSize(window.innerWidth / 2, window.innerHeight / 2)
document.body.appendChild(renderer.domElement)
【世界坐标辅助器】'红色-X轴; 绿色-Y轴; 蓝色-Z轴'
const axesHelper = new THREE.AxesHelper(5)
scence.add(axesHelper)
【网格辅助器】
第一个50:网格的边长是50个单位长度
第二个50:网格被分割成50x50的小格
const gridHelper = new THREE.GridHelper(50, 50)
gridHelper.material.transparent = true `只有网格材质的【transparent = true】,opacity属性的设置才会生效`
gridHelper.material.opacity = 0.3 `网格材质的透明度`
scene.add(gridHelper)
【创建轨道控制器】
'参数一':相机,让哪一个相机围绕目标运动;'默认目标是原点'
'参数二':渲染的画布dom对象,用于监听鼠标事件控制相机的围绕运动
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true `带阻尼的惯性`
controls.dampingFactor = 0.01 `阻尼系数(值越小,运动越平滑,但响应越慢)`
controls.autoRotate = true `开启后,相机绕着y轴,顺时针自动旋转`
【每一帧,根据控制器更新画面】
function render() {
如果,需要控制器带有阻尼效果,或者,自动旋转等效果,就需要加入`controls.update()`
controls.update()
`【requestAnimationFrame】`在屏幕渲染下一帧画面时,触发回调函数,来执行画面的渲染
requestAnimationFrame(render)
renderer.render(scence, camera)
}
render()
【RGBELoader,加载hdr贴图】
let rgbeLoader = new RGBELoader()
rgbeLoader.load('../public/assets/texture/Alex_Hart-Nature_Lab_Bones_2k.hdr', envMap => {
envMap.mapping = THREE.EquirectangularRefractionMapping `折射`
scene.background = new THREE.Color(0xcccccc)
scene.environment = envMap
})
【实例化 - gltf加载器】
const gltfLoader = new GLTFLoader()
【实例化 - draco加载器】
const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('../public/draco/')
gltfLoader.setDRACOLoader(dracoLoader) `设置 - gltf的解码器draco`
gltfLoader.load('../public/assets/model/house/house-scene-min.glb', gltf => {
basicScene = gltf.scene
})
---------------------------------------------------------------------------------------------------
let basicScene
let eventObj = {
addScene: () => scene.add(basicScene),
isLight: true `开关灯效果`
}
---------------------------------------------------------------------------------------------------
const gui = new GUI()
gui.add(eventObj, 'addScene').name('添加户型基础模型')
gui.add(eventObj, 'isLight')
.name('开关灯')
.onChange(value => {
if (value) {
renderer.toneMappingExposure = 1
} else {
renderer.toneMappingExposure = 0.1
}
})
---------------------------------------------------------------------------------------------------
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(window.devicePixelRatio)
})