Three.js搭建小米SU7三维汽车实战(4)场景搭建

news2025/6/1 12:43:05

场地搭建

```javascript // 导入threejs import * as THREE from "three"; // 导入轨道控制器 import { OrbitControls } from "three/addons/controls/OrbitControls.js";

// 1. 创建场景
const scene = new THREE.Scene();
// 2. 创建相机
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
1000
);

camera.position.z = 50;

// 5. 创建立方体(几何+材质)
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshNormalMaterial();
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
// 添加到场景
scene.add(cube);

// 6. 显示坐标轴(x轴: 红色; y轴: 绿色; z轴: 蓝色 rgb)
// x轴水平方向(右正); y轴垂直方向(上正); z轴垂直xy平面即屏幕(外正)
const axesHelper = new THREE.AxesHelper(10);
scene.add(axesHelper);

// 3. 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 7. 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);

// 4. 动态渲染
function animation() {
controls.update();
renderer.render(scene, camera);

requestAnimationFrame(animation);
}
animation();
// 监听window的resize事件, 在回调中重绘canvas
window.addEventListener(“resize”, () => {
// 设置相机宽高比
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();

// 设置渲染器
renderer.setSize(window.innerWidth, window.innerHeight);
});


![](https://cdn.nlark.com/yuque/0/2025/png/8435413/1746754347219-0af5675d-ed2e-4896-85f1-f9dbe2683e48.png?x-oss-process=image%2Fformat%2Cwebp)

<h1 id="Tnwb7"><font style="color:rgb(38, 38, 38);">汽车模型获取</font></h1>
[SU7 - Download Free 3D model by s1657270997](https://sketchfab.com/3d-models/su7-7296a91633d74c6eb113010e2ed75eda)

<h1 id="B3RKC"><font style="color:rgb(38, 38, 38);">设置展厅</font></h1>
<h2 id="uzbYV"><font style="color:rgb(38, 38, 38);">添加地板</font></h2>
<font style="color:rgb(38, 38, 38);">我们可以将立方体删掉,换成一个圆形的面,这个面就是我们的展厅地板</font>

```javascript
const geom = new THREE.CircleGeometry(20, 29);
const material = new THREE.MeshBasicMaterial({
    color:new THREE.Color(0xffffff)
});
const mesh = new THREE.Mesh(geom, material);
scene.add(mesh)

现在我们发现这个面是立着的,我们需要给它旋转一下

mesh.rotation.x -= (90 * Math.PI) / 180;

修改一下材质为双面渲染

const material = new THREE.MeshBasicMaterial({
    color:new THREE.Color(0xffffff),
    side:THREE.DoubleSide
});

设置背景

我们将当前的背景修改一下,懂车帝使用的是一个渐变图作为背景,我们将其拿过来用一下
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1920px" height="500px" viewBox="0 0 1418 344" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
	<title>bg新</title>
	<defs>
		<radialGradient cx="50%" cy="0%" fx="50%" fy="0%" r="100%" gradientTransform="translate(0.500000,0.000000),scale(0.224457,1.000000),rotate(90.000000),scale(1.000000,3.681004),translate(-0.500000,-0.000000)" id="radialGradient-1">
			<stop stop-color="#B4B9C5" offset="0%"></stop>
			<stop stop-color="#F7F8FC" offset="100%"></stop>
		</radialGradient>
		<rect id="path-2" x="0" y="0" width="1388" height="311.545631"></rect>
		<linearGradient x1="44.08867%" y1="43.6422414%" x2="100%" y2="43.6422414%" id="linearGradient-4">
			<stop stop-color="#F7F8FC" offset="0%"></stop>
			<stop stop-color="#F2F4FA" stop-opacity="0" offset="100%"></stop>
		</linearGradient>
		<rect id="path-5" x="0" y="0" width="1388" height="311.545631"></rect>
		<linearGradient x1="44.08867%" y1="43.6422414%" x2="100%" y2="43.6422414%" id="linearGradient-7">
			<stop stop-color="#F2F4FA" stop-opacity="0" offset="0%"></stop>
			<stop stop-color="#F7F8FC" offset="100%"></stop>
		</linearGradient>
		<radialGradient cx="50%" cy="0%" fx="50%" fy="0%" r="100%" gradientTransform="translate(0.500000,0.000000),scale(0.024115,1.000000),rotate(90.000000),scale(1.000000,27.956600),translate(-0.500000,-0.000000)" id="radialGradient-8">
			<stop stop-color="#B8BDC9" offset="0%"></stop>
			<stop stop-color="#F7F8FC" offset="100%"></stop>
		</radialGradient>
		<filter x="-1.1%" y="-44.8%" width="102.2%" height="189.6%" filterUnits="objectBoundingBox" id="filter-9">
			<feGaussianBlur stdDeviation="5" in="SourceGraphic"></feGaussianBlur>
		</filter>
	</defs>
	<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
		<g id="bg新" transform="translate(15.000000, 0.000000)">
			<g id="椭圆形-+-椭圆形-蒙版">
				<g id="蒙版" transform="translate(694.000000, 155.772816) scale(-1, 1) rotate(-180.000000) translate(-694.000000, -155.772816) translate(0.000000, 0.000001)" fill="url(#radialGradient-1)" fill-rule="nonzero">
					<rect id="path-2" x="0" y="0" width="1388" height="311.545631"></rect>
				</g>
				<g id="椭圆形-Clipped">
					<mask id="mask-3" fill="white">
						<use xlink:href="#path-2"></use>
					</mask>
					<g id="path-2"></g>
					<ellipse id="椭圆形" fill="url(#linearGradient-4)" fill-rule="nonzero" mask="url(#mask-3)" cx="-7.73019802" cy="241.168932" rx="234.482673" ry="234.302913"></ellipse>
				</g>
				<g id="椭圆形-Clipped">
					<mask id="mask-6" fill="white">
						<use xlink:href="#path-5"></use>
					</mask>
					<g id="path-2"></g>
					<ellipse id="椭圆形" fill="url(#linearGradient-7)" fill-rule="nonzero" mask="url(#mask-6)" cx="1177.56683" cy="241.168932" rx="234.482673" ry="234.302913"></ellipse>
				</g>
			</g>
			<path d="M694,328.71068 C1077.28562,328.71068 1388,321.217752 1388,311.974757 C1388,302.731763 1077.28562,295.238835 694,295.238835 C310.714384,295.238835 0,302.731763 0,311.974757 C0,321.217752 310.714384,328.71068 694,328.71068 Z" id="椭圆形" fill="url(#radialGradient-8)" fill-rule="nonzero" opacity="0.960278888" filter="url(#filter-9)"></path>
		</g>
	</g>
</svg>

threejs中加载材质使用的是TextureLoader,加载之后还可以设置一下背景的平铺方式,避免背景重复平铺或者拉伸

const backgoundTexture = new THREE.TextureLoader().load(
	"/src/assets/images/background.svg"
);
backgoundTexture.wrapS = backgoundTexture.wrapT = THREE.RepeatWrapping;
backgoundTexture.repeat.set(1, 1);

得到材质数据之后,将其赋予场景的背景

这样场景就搭建好了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2392589.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Excel 统计某个字符串在指定区域出现的次数

【本文概要】 Excel 统计某个字符串在指定区域出现的次数&#xff1a; 1、Excel 统计一个单元格内的某字符串的出现次数 2、Excel 统计某一列所有单元格内的某字符串的出现次数 3、Excel 统计某一区域所有单元格内的某字符串的出现次数 1、Excel 统计一个单元格内的某字符串的出…

【Linux我做主】进度条小程序深度解析

Linux下C语言进度条程序深度解析 进度条小程序GitHub地址 前言前置知识回车换行&#xff08;CR/LF&#xff09;的深度解析历史渊源与技术规范在进度条/倒计时中的应用 缓冲区机制的全面剖析缓冲区引入缓冲类型对比进度条开发中的关键控制 进度条实现以小见大——倒计时倒计时最…

从Homebrew找到openssl.cnf文件并拷贝到Go项目下使用

安装OpenSSL 在 macOS 上下载和安装 OpenSSL 最常见和推荐的方式是使用 Homebrew&#xff0c;这是一个 macOS 缺失的包管理器。 如果您还没有安装 Homebrew&#xff0c;请先安装它。安装 Homebrew 后&#xff0c;安装 OpenSSL 只需要一条命令。 步骤 1&#xff1a;安装 Home…

微信小程序一次性订阅封装

封装代码如下&#xff1a; export async function subscribeMessage(tmplIds: string[]): Promise<ISubscribeMessagePromise> {// 模板ID// 1、获取设置状态const settings (await wx.getSetting({ withSubscriptions: true })).subscriptionsSetting || {}console.log…

安全帽检测算法AI智能分析网关V4守护工地/矿山/工厂等多场景作业安全

一、方案概述​ 在工业生产与建筑施工场景中&#xff0c;安全帽是保障人员安全的重要装备。但传统人工巡检效率低、易疏漏&#xff0c;难以满足现代安全管理需求。AI智能分析网关V4安全帽检测方案&#xff0c;借助人工智能与计算机视觉技术&#xff0c;实现作业现场安全帽佩戴…

Python自动化之selenium语句——打开、关闭浏览器和网页

目录 一、打开谷歌浏览器 1.双击桌面的Pycharm工具 2.新建Python文件&#xff0c;输入文件名 3.新建的Python文件如下 4.安装selenium库 5.导入包 二、打开网页、关闭网页、关闭浏览器 1.导入增加一个时间包 2.使用函数打包之前写的浏览器的配置 3.调用 4.打开百度网…

【数据结构】--二叉树--堆(上)

一、树的概念和结构 概念&#xff1a; 树是一种非线性的数据结构&#xff0c;他是由n(n>0)个有限结点组成一个具有层次关系的集合。其叫做树&#xff0c;是因为他倒过来看就和一棵树差不多&#xff0c;其实际上是根在上&#xff0c;树枝在下的。 树的特点&#xff1a; 1…

多线程(5)——单例模式,阻塞队列

目录 单例模式饿汉模式懒汉模式—单线程版懒汉模式—多线程版&#xff08;经典面试题&#xff09;懒汉模式—多线程版&#xff08;改进&#xff09; 阻塞队列阻塞队列是什么生产者消费者模型标准库中的阻塞队列-BlockingQueue阻塞队列实现 单例模式 单例模式是一种设计模式&am…

视频监控汇聚平台EasyCVR工业与安全监控:防爆摄像机的安全应用与注意事项

石油、化工、煤矿等行业存在易燃易爆气体、粉尘&#xff0c;普通监控设备易因电火花、高温引发爆炸火灾。随着工业规模扩大&#xff0c;安全生产监控需求激增&#xff0c;防爆摄像机成为保障安全的关键。加之国家法规与行业标准对危险环境监控设备要求严格&#xff0c;规范其应…

基于 Redis 实现分布式锁:原理及注意事项

文章目录 基于 Redis 实现分布式锁&#xff1a;原理及注意事项基于 Redis 实现分布式锁的原理Redis 分布式锁的过期时间和锁续期机制如何防止锁被其他 goroutine 删除&#xff1f;Redis 分布式锁存在的单点故障问题&#xff1a;基于 RedLock 的解决方案高并发场景中 Redis 分布…

手机设备多?怎样设置IP保证不关联

在移动互联网时代&#xff0c;多设备运营&#xff08;如电商、游戏工作室、社交媒体矩阵&#xff09;常面临IP关联风险&#xff0c;轻则账号受限&#xff0c;重则封禁。以下提供6种高效设置独立IP的方法&#xff0c;结合技术原理与实操建议&#xff0c;助您打造稳定合规的运营环…

哈尔滨工业大学计算机系统大作业程序人生-Hello’s P2P

摘 要 文章以C语言程序设计经典案例hello.c为研究对象&#xff0c;系统解析程序在计算机系统中的完整生命周期。剖析源代码通过预处理、编译、汇编、链接四阶段演化为可执行目标程序的编译系统工作机制&#xff0c;继而从进程视角揭示程序运行时计算机体系结构的协同运作&…

Linux系统管理与编程24:基础条件准备-混搭“本地+阿里云”yum源

兰生幽谷&#xff0c;不为莫服而不芳&#xff1b; 君子行义&#xff0c;不为莫知而止休。 1.添加宿主机共享文件夹 Linux虚拟机可以和宿主机共享文件夹&#xff0c;这样有利于工具文件的共享。具体操作如下&#xff1a; 1&#xff09;vmware workstation共享文件夹 虚拟机…

如何在 Windows 10 PC 上获取 iPhone短信

您可以轻松地将媒体数据从 iPhone 传输到 Windows 计算机&#xff0c;并直接访问计算机上的数据。但是&#xff0c;您可以在 Windows 10 PC 上接收 iPhone 短信吗&#xff1f;有什么功能或工具支持它吗&#xff1f;如果您发现在 Windows 10 PC 上接收 iPhone 消息很困难&#x…

Linux 系统中的软链接与硬链接

目录 一、什么是软链接&#xff1f; 1. 创建软链接 2. 软链接的特性 3. 软链接的用途 二、什么是硬链接&#xff1f; 1. 创建硬链接 2. 硬链接的特性 3. 硬链接的用途 4. 目录硬链接的特殊性 ​编辑 三、软链接与硬链接的区别 1. inode 编号 2. 路径依赖 3. 删除行…

Python爬虫第22节- 结合Selenium识别滑动验证码实战

目录 一、引言 二、滑动验证码原理与反爬机制 2.1 验证码原理 2.2 反爬机制 三、工程实战&#xff1a;滑动验证码识别全流程 3.1 工程准备 3.1.1 环境依赖 3.1.2 目标网站与验证码识别案例 3.2 核心破解流程 3.2.1 自动化打开网页与登录 3.2.2 获取验证码图片&#…

Escrcpy(安卓手机投屏软件) v1.29.6 中文绿色版

在数字设备日益普及的今天&#xff0c;用户对于设备的控制和管理需求也在不断增加。对于Android设备用户来说&#xff0c;Escrcpy这款强大的工具无疑是一个福音。它不仅提供了直观的图形化界面&#xff0c;让用户能够轻松显示和控制自己的Android设备&#xff0c;还以完全免费开…

Linux:深入理解网络层

网络层在复杂的网络环境中确定一个合适的路径.传输到指定的网络中 一、网络层的理解 问题1&#xff1a;为什么要有网络层的概念呢&#xff1f;&#xff1f; ——>我们先来讲一个故事&#xff1a; 假设我在学校里被誉为数学大神&#xff0c;是因为我的数学有考满分的能力&…

Linux_编辑器Vim基本使用

✨✨ 欢迎大家来到小伞的大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;LInux_st 小伞的主页&#xff1a;xiaosan_blog 制作不易&#xff01;点个赞吧&#xff01;&#xff01;谢谢喵&#xff01;&a…

vue展示修改前后对比,并显示修改标注diff

动态父组件 <template><el-buttontype"primary"size"small"plainclick"showDiffDialog(subItem)">查看修改内容</el-button><TextDiffDialogv-model:visible"diffDialogVisible":before"currentDiffItem?.…