Three加载3D模型贴图

Three加载3D模型贴图

准备阶段

  1. 3D模型
  2. three 库文件
  3. 纹理图片

相关资料

效果图

效果图1

核心代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>房屋平面室内图</title>
	</head>
	<body>

	</body>
	<script type="importmap">
		{
		"imports": {
			"three":"/js/three.module.js",
			"three/addons/": "/examples/jsm/"
			}
		}
	</script>
	<script type="module">
		import GUI from 'https://cdn.jsdelivr.net/npm/lil-gui@0.18/+esm';
		import * as THREE from 'three';
		// 加载 gltf 模型
		import {
			GLTFLoader
		} from 'three/addons/loaders/GLTFLoader.js';
		// 加载 obj 模型
		import {
			OBJLoader
		} from 'three/addons/loaders/OBJLoader.js';

		// 轨道控制器
		import {
			OrbitControls
		} from 'three/addons/controls/OrbitControls.js';

		
		
		// 创建场景
		const scene = new THREE.Scene();
		// 创建透视相机
		const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000)
		camera.position.set(0, 20, 200)
		camera.scale.x = 1
		camera.scale.y = 1
		camera.scale.z = 1
		// camera.zoom=0.5
		
		
		// 更新相机
		camera.updateProjectionMatrix()
		// 创建渲染器,透明背景
		const renderer = new THREE.WebGLRenderer({
			alpha: true
		});
		


		// 场景灯光
		const directionalLight = new THREE.DirectionalLight()
		directionalLight.penumbra = 0.4
		directionalLight.position.set(10, 14, 5)
		directionalLight.distance = 0
		directionalLight.castShadow = true
		directionalLight.intensity = 1
		directionalLight.shadow.camera.near = 1
		directionalLight.shadow.camera.far = 25
		directionalLight.shadow.camera.right = 10
		directionalLight.shadow.camera.left = -10
		directionalLight.shadow.camera.top = 10
		directionalLight.shadow.camera.bottom = -10
		directionalLight.shadow.mapSize.width = 2048
		directionalLight.shadow.mapSize.height = 2048
		directionalLight.shadow.bias = -0.01
		scene.add(directionalLight);

		// 纹理可以加载。TextureLoader
		const textureLoader = new THREE.TextureLoader();
		textureLoader.load('/assets/wood/floor-parquet-pattern-172292.jpg', (loaded) => {
			loaded.encoding = THREE.sRGBEncoding
			scene.background = loaded
			scene.environment = null
		})

		renderer.setSize(window.innerWidth, window.innerHeight);
		document.body.appendChild(renderer.domElement);
		
		const gui = new GUI();
		
		const obj = {
			left: '/model/textures/12.jpg',
			right: '/model/textures/12.jpg',
			bottom: '/model/textures/9.jpg',
			back: '/model/textures/13.jpg',
			bed: '/model/textures/5.jpg',
			table: '/model/textures/1.jpg',
		}
		const mm = {
			'material1': '/model/textures/1.jpg',
			'material2': '/model/textures/2.png',
			'material3': '/model/textures/3.jpg',
			'material4': '/model/textures/4.png',
			'material5': '/model/textures/5.jpg',
			'material6': '/model/textures/6.jpg',
			'material7': '/model/textures/7.jpg',
			'material8': '/model/textures/8.jpg',
			'material9': '/model/textures/9.jpg',
			'material10': '/model/textures/10.jpg',
			'material11': '/model/textures/11.jpg',
			'material12': '/model/textures/12.jpg',
			'material13': '/model/textures/13.jpg',
			'material14': '/model/textures/14.jpg',
		}
		const folder = gui.addFolder( 'textures' );
		folder.add(obj, 'left', mm)
		folder.add(obj, 'right', mm)
		folder.add(obj, 'bottom', mm)
		folder.add(obj, 'back', mm)
		folder.add(obj, 'bed', mm)
		folder.add(obj, 'table', mm)
		folder.onChange(event => {
			console.log(event)
			const key = event.property;
			const value = event.value;
			const mesh = scene.getObjectByName(key);
			if (mesh) {
				const material = new THREE.MeshBasicMaterial({
					map: textureLoader.load(value)
				});
				mesh.material = material;
				mesh.castShadow=true;
			}
		});
		const backgroundColor = gui.addFolder( 'scene' );
		backgroundColor.add({'backGround':'White'},'backGround', ['White', 'Black', 'Null', 'Color', 'Texture','自定义纹理', 'Cubemap'])
			.onChange((event) => handleBackgroundChange(event, scene))
		
		const handleBackgroundChange = (setting, scene) => {
			switch (setting) {
				case 'White':
					scene.background = new THREE.Color(0xffffff)
					break
				case 'Black':
					scene.background = new THREE.Color(0x000000)
					break
				case 'Null':
					scene.background = null
					break
				case 'Color':
					scene.background = new THREE.Color(0x44ff44)
					break
				case 'Texture':
					textureLoader.load('/assets/wood/abstract-antique-backdrop-164005.jpg', (loaded) => {
						loaded.encoding = THREE.sRGBEncoding
						scene.background = loaded
						scene.environment = null
					})
					break
				case '自定义纹理':
					textureLoader.load('/assets/wood/floor-parquet-pattern-172292.jpg', (loaded) => {
						loaded.encoding = THREE.sRGBEncoding
						scene.background = loaded
						scene.environment = null
					})
					break
				case 'Cubemap':
					textureLoader.load('/assets/equi.jpeg', (loaded) => {
						loaded.mapping = THREE.EquirectangularReflectionMapping
						scene.background = loaded
						scene.environment = loaded
					})
					break
				default:
					break
			}
		}

		const loader = new GLTFLoader();
		// 滑轨控制
		const controller = new OrbitControls(camera, renderer.domElement)
		controller.enableDamping = true
		controller.dampingFactor = 0.05
		controller.minDistance = 1
		controller.maxDistance = 100
		controller.minPolarAngle = 0
		controller.maxPolarAngle = Math.PI

		loader.load(
			'/model/plan_room.gltf',
			function(gltf) {
				gltf.scene.traverse(function(child) {
					if (child instanceof THREE.Mesh) {
						// 加载模型时,添加对于的纹理贴图
						for (let key in obj) {
							if (child.name === key) {
								const material = new THREE.MeshBasicMaterial({
									map: textureLoader.load(obj[key])
								});
								child.material = material;
								continue;
							}
						}
					}
				})
				gltf.scene.scale.x = 0.5
				gltf.scene.scale.y = 0.5
				gltf.scene.scale.z = 0.5
				scene.add(gltf.scene);
			},
			function(xhr) {
				console.log((xhr.loaded / xhr.total * 100) + '% loaded');
			},
			function(error) {
				console.error(error);
			}
		);

		function animate() {
			requestAnimationFrame(animate);
			controller.update();
			renderer.render(scene, camera);
		}
		animate();
	</script>
</html>

源码传送

下载:https://864000.lanzouy.com/ipX7D0woxeqf 密码:3bi0

根目录执行http-server -p9001 浏览器访问 http://127.0.0.1:9001

C:\Users\mac\OneDrive\three-1>http-server -p9001
Starting up http-server, serving ./

http-server version: 14.1.1

http-server settings:
CORS: disabled
Cache: 3600 seconds
Connection Timeout: 120 seconds
Directory Listings: visible
AutoIndex: visible
Serve GZIP Files: false
Serve Brotli Files: false
Default File Extension: none

Available on:
  http://192.168.31.156:9001
  http://127.0.0.1:9001
posted @ 2023-05-20 16:52  天葬  阅读(96)  评论(0编辑  收藏  举报