在阴影映射材质中,alphaMap map displacementMap 程现的效果没有什么大的区别就是用来对光照进行一定程序的遮挡,一般这个材质在内部使用,还有一种用法可以在材质在使用下面给出了使用示例并将three中官网的属性注解进行了描述
MeshDistanceMaterial 阴影映射材质 五个属性
- alphaMap alpha贴图是一张灰度纹理,用于控制整个表面的不透明度。(黑色:完全透明;白色:完全不透明)。 默认值为null。
- displacementMap 位移贴图会影响网格顶点的位置,与仅影响材质的光照和阴影的其他贴图不同,移位的顶点可以投射阴影,阻挡其他对象,以及充当真实的几何体。 位移纹理是指:网格的所有顶点被映射为图像中每个像素的值(白色是最高的),并且被重定位。
- displacementScale 位移贴图对网格的影响程度(黑色是无位移,白色是最大位移)。如果没有设置位移贴图,则不会应用此值。默认值为1。
- displacementBias 位移贴图在网格顶点上的偏移量。如果没有设置位移贴图,则不会应用此值。默认值为0。
- map 颜色贴图。可以选择包括一个alpha通道,通常与.transparent 或.alphaTest。默认为null。
<template>
<div id="parkingLot" ref="parkingLot">
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import * as THREE from 'three';
import imgPng from "@public/person.jpg"
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
const parkingLot = ref();
onMounted(() => {
const DOMEl = parkingLot.value;
// 获取 DOMEl 的宽度和高度,以设置渲染器的大小。
const width = DOMEl.clientWidth;
const height = DOMEl.clientHeight;
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize( width, height );
renderer.shadowMap.enabled = true; // 启用阴影映射
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 选择阴影类型
DOMEl.appendChild( renderer.domElement );
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, width / height, 0.1, 1000 );
camera.position.set( 0, 80, 0 );
camera.lookAt( 0, 0, 0 );
const geometryCube = new THREE.BoxGeometry( 30, 30, 30 );
const materialCube = new THREE.MeshPhongMaterial( {
color: 0xffffff,
shininess: 10,
specular: 0x111111,
side: THREE.BackSide
} );
// 创建点光源并启用阴影
const pointLight = new THREE.PointLight(0x0000ff, 1000, 500);
pointLight.position.set(0, 0, 0); // 调整光源位置
pointLight.castShadow = true;
// 0.6 为物体半径 当物体半径为1时产生的遮挡就越大,否则越小为0无遮挡
let geometry = new THREE.SphereGeometry( 0.6, 12, 6 );
let material = new THREE.MeshBasicMaterial( { color: 0xff0000,opacity: 0.5 } );
let sphere = new THREE.Mesh( geometry, material );
// 产生投影
sphere.castShadow = true;
// 接收投影
sphere.receiveShadow = true;
pointLight.add( sphere );
// 创建自定义的 MeshDistanceMaterial
const distanceMaterial = new THREE.MeshDistanceMaterial({
depthTest: true,
transparent: true,
});
// 加载位移贴图
distanceMaterial.displacementMap = new THREE.TextureLoader().load(imgPng);
distanceMaterial.displacementScale = 0.5;
distanceMaterial.displacementBias = 0.1;
// 将 MeshDistanceMaterial 指定给自定义材质以确保阴影处理
sphere.customDistanceMaterial = distanceMaterial;
// 场景中添加灯光
scene.add( pointLight );
const meshCube = new THREE.Mesh( geometryCube, materialCube );
// 接收投影
meshCube.receiveShadow = true;
// 产生投影
meshCube.castShadow = true;
scene.add( meshCube );
const helper = new THREE.BoxHelper( meshCube, 0xffff00 );
scene.add( helper );
// 创建 OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 渲染循环
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
animate();
});
</script>
<style lang="scss" scoped="scoped">
#parkingLot {
width: 940px;
height: 940px;
border: 1px solid #ccc;
margin: 30px auto;
}
</style>