使用vue学习three.js之加载和使用纹理-设置material.lightMap属性使用光照贴图创建假阴影
Posted 点燃火柴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用vue学习three.js之加载和使用纹理-设置material.lightMap属性使用光照贴图创建假阴影相关的知识,希望对你有一定的参考价值。
1.demo效果
如上图通过光照贴图实现了物体的阴影
2. 相关知识点
在场景中为物体添加阴影,可以增加物体的立体感,但是通过计算实现阴影非常耗费性能,人们总会想办法通过其他方式实现相同的效果,比如通过光照贴图创建假阴影,通过这种方式创建阴影,有优点也有缺点,优点是可以创建出解析度很高的阴影而且不损耗性能,缺点 是只能用于静态场景
3. 实现要点
3.1 创建模型
这一步将会创建一个大方块,一个小方块,代码如下
// 创建模型
createModels() {
//加载纹理贴图
const publicPath = process.env.BASE_URL
const texture = new THREE.TextureLoader().load(
`${publicPath}textures/general/stone.jpg`
)
const material = new THREE.MeshBasicMaterial()
material.map = texture
//创建大方块
this.cube1 = new THREE.Mesh(new THREE.BoxGeometry(12, 12, 12), material)
this.cube1.position.set(0.9, 6, -12)
this.scene.add(this.cube1)
//创建小方块
this.cube2 = new THREE.Mesh(new THREE.BoxGeometry(6, 6, 6), material)
this.cube2.position.set(-13.2, 3, -6)
this.scene.add(this.cube2)
// console.log(this.cube2.geometry.faceVertexUvs)
this.createFloor()
}
3.2 创建带阴影的地板
这里首先需要加载地板的木质地板纹理和光照贴图纹理,然后把它们分别设置为材质的map属性和lightMap属性,之后使用这个材质创建网格对象,还有一点需要注意,要为光照贴图指定UV映射,这样可以将光照贴图与其他纹理独立开来
createFloor() {
const publicPath = process.env.BASE_URL
const groundGeom = new THREE.PlaneGeometry(95, 95, 1, 1)
//加载光照贴图
const lightMap = new THREE.TextureLoader().load(
`${publicPath}textures/lightmap/lm-1.png`
)
//加载创建底板的纹理贴图
const wood = new THREE.TextureLoader().load(
`${publicPath}textures/general/floor-wood.jpg`
)
const groundMaterial = new THREE.MeshBasicMaterial({
color: 0x777777,
lightMap: lightMap,
map: wood
})
groundGeom.faceVertexUvs[1] = groundGeom.faceVertexUvs[0] //为光照贴图指定UV映射
const groundMesh = new THREE.Mesh(groundGeom, groundMaterial)
groundMesh.rotation.x = -Math.PI / 2
groundMesh.position.y = 0
this.scene.add(groundMesh)
}
4. demo代码
<template>
<div id="container" />
</template>
<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
export default {
data() {
return {
cube1: null,
cube2: null,
camera: null,
scene: null,
renderer: null,
controls: null
}
},
mounted() {
this.init()
},
methods: {
// 初始化
init() {
this.createScene() // 创建场景
this.createModels() // 创建模型
this.createLight() // 创建光源
this.createCamera() // 创建相机
this.createRender() // 创建渲染器
this.createControls() // 创建控件对象
this.render() // 渲染
},
// 创建场景
createScene() {
this.scene = new THREE.Scene()
},
// 创建模型
createModels() {
//加载纹理贴图
const publicPath = process.env.BASE_URL
const texture = new THREE.TextureLoader().load(
`${publicPath}textures/general/stone.jpg`
)
const material = new THREE.MeshBasicMaterial()
material.map = texture
//创建大方块
this.cube1 = new THREE.Mesh(new THREE.BoxGeometry(12, 12, 12), material)
this.cube1.position.set(0.9, 6, -12)
this.scene.add(this.cube1)
//创建小方块
this.cube2 = new THREE.Mesh(new THREE.BoxGeometry(6, 6, 6), material)
this.cube2.position.set(-13.2, 3, -6)
this.scene.add(this.cube2)
// console.log(this.cube2.geometry.faceVertexUvs)
this.createFloor()
},
createFloor() {
const publicPath = process.env.BASE_URL
const groundGeom = new THREE.PlaneGeometry(95, 95, 1, 1)
//加载光照贴图
const lightMap = new THREE.TextureLoader().load(
`${publicPath}textures/lightmap/lm-1.png`
)
//加载创建底板的纹理贴图
const wood = new THREE.TextureLoader().load(
`${publicPath}textures/general/floor-wood.jpg`
)
const groundMaterial = new THREE.MeshBasicMaterial({
color: 0x777777,
lightMap: lightMap,
map: wood
})
groundGeom.faceVertexUvs[1] = groundGeom.faceVertexUvs[0] //为光照贴图指定UV映射
const groundMesh = new THREE.Mesh(groundGeom, groundMaterial)
groundMesh.rotation.x = -Math.PI / 2
groundMesh.position.y = 0
this.scene.add(groundMesh)
},
// 创建光源
createLight() {
// 环境光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.1) // 创建环境光
this.scene.add(ambientLight) // 将环境光添加到场景
},
// 创建相机
createCamera() {
const element = document.getElementById('container')
const width = element.clientWidth // 窗口宽度
const height = element.clientHeight // 窗口高度
const k = width / height // 窗口宽高比
// PerspectiveCamera( fov, aspect, near, far )
this.camera = new THREE.PerspectiveCamera(45, k, 0.1, 1000)
this.camera.position.set(-20, 20, 30) // 设置相机位置
this.camera.lookAt(new THREE.Vector3(0, 0, 0)) // 设置相机方向
this.scene.add(this.camera)
},
// 创建渲染器
createRender() {
const element = document.getElementById('container')
this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸
this.renderer.shadowMap.enabled = true // 显示阴影
// this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
this.renderer.setClearColor(0xeeeeee, 1) // 设置背景颜色
element.appendChild(this.renderer.domElement)
},
render() {
this.renderer.render(this.scene, this.camera)
requestAnimationFrame(this.render)
},
// 创建控件对象
createControls() {
this.controls = new OrbitControls(this.camera, this.renderer.domElement)
}
}
}
</script>
<style>
#container {
position: absolute;
width: 100%;
height: 100%;
}
.controls-box {
position: absolute;
right: 5px;
top: 5px;
width: 300px;
padding: 10px;
background-color: #fff;
border: 1px solid #c3c3c3;
}
.label-col {
padding: 8px 5px;
}
.vertice-span {
line-height: 38px;
padding: 0 2px 0 10px;
}
</style>
以上是关于使用vue学习three.js之加载和使用纹理-设置material.lightMap属性使用光照贴图创建假阴影的主要内容,如果未能解决你的问题,请参考以下文章
使用vue学习three.js之加载和使用纹理-用视频输出作为纹理,使用VideoTexture视频纹理实现物体表面播放视频
使用vue学习three.js之加载和使用纹理- 通过设置纹理的wrapSwrapTrepeat属性实现纹理的重复平铺,纹理的重复映射
使用vue学习three.js之加载和使用纹理-使用canvas画布上的绘画作为纹理渲染到方块上,使用动态绘画纹理
使用vue学习three.js之加载和使用纹理-设置material.bumpMap属性使用凹凸贴图创建皱纹