Three.js搭建小米SU7三维汽车实战(5)su7登场

news2025/5/29 9:27:57

汽车模型加载

我们在sktechfab上下载的汽车是glb的文件格式,所以使用gltfLoader进行加载。这里将小车直接加载进来看看效果;
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
....其余代码省略
const gltfLoader = new GLTFLoader();
gltfLoader.load("/src/assets/models/su7.glb", (gltf) => {
  const model = gltf.scene;
  scene.add(model);
});

我们会发现小车是黑的,这是因为我们当前场景中并没有光照信息,我们需要为场景添加光照。

无光照时的模型

const ambientLight = new THREE.AmbientLight(0xf7f8fc, 0.2);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xf7f8fc, 1);
directionalLight.position.set(0, 5, 0);
scene.add(directionalLight);

添加光照之后小车有了颜色,但是细微观察还缺少了一些效果,比如汽车漆面上的反射效果。

表面反射

我们可以给当前的场景设置环境属性,来为场景中所有的物体添加环境反射,这需要我们准备一张**全景图**

全景图概念

全景图的原理其实很简单,如下图所示,假设我们所处的空间在一个很大的立方体内部,那么全景图就是用六张图片,赋予立方体六个面的纹理,我们在立方体内部观察,每个方向的图片都不一样,这样就有了身临其境的感觉

全景图下的观察效果

一般全景图是由6张图片组成,也可以使用hdr格式的压缩图片,两者都可以实现全景图
本案例中给大家提供的是hdr的全景图,我们使用RGBELoader来进行加载,并且设置环境属性,注意不要设置背景

const texture = new THREE.CubeTextureLoader()
  .setPath('/src/assets/texture/park/')
  .load([
    'posx.jpg',
    'negx.jpg',
    'posy.jpg',
    'negy.jpg',
    'posz.jpg',
    'negz.jpg',
  ])
// 创建一个纹理加载器, 加载纹理图片
const texture = new RGBELoader().load('/src/assets/hdr/city.hdr', () => {
  texture.mapping = THREE.EquirectangularReflectionMapping
  scene.background = texture
})

可以看到我们的油漆表面有了一层反射效果

细心的同学不难发现,我们的小车一部分在地下,这是建模的问题,我们可以在three中进行调整,将平面往下走0.02个单位即可

mesh.position.set(0, -0.02, 0);

我们还可以观察到,和懂车帝官网对比,我们的su7没有在地面上展示出来阴影,接下来我们设置一下阴影效果。

添加阴影

添加阴影需要几个步骤 1. 设置渲染器支持阴影贴图 2. 设置物体支持投射阴影 3. 设置平面能够接受阴影 4. 设置灯光支持投射阴影 5. 设置平面为standard材质 这五个步骤对应的源码为:
renderer.shadowMap.enabled=true

我们的模型是不能直接设置投射阴影的,模型是一棵树的结构,需要遍历到每一个叶子节点,然后设置投射阴影

gltfLoader.load("/src/assets/models/su7.glb", (gltf) => {
    const model = gltf.scene;
    model.traverse((mesh) => {
        if (mesh.isMesh) {
          mesh.castShadow = true;
        }
    });
    scene.add(model);
});
const geom = new THREE.CircleGeometry(20, 150);
const material = new THREE.MeshStandardMaterial({
  color: new THREE.Color(0xffffff),
  side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(geom, material);
mesh.rotation.x -= (90 * Math.PI) / 180;
mesh.position.set(0, -0.02, 0);
scene.add(mesh);
mesh.receiveShadow=true
directionalLight.castShadow=true

实现效果,我们发现和懂车帝官网的阴影比较起来,第一是颜色不够深,第二是边缘没有进行柔滑,我们很难和懂车帝做的一模一样,只能尽量去模拟这个效果,因为懂车帝官网的效果是用一张图片做的,我们没有这样的图片资源

懂车帝官网效果

提高阴影的质量

阴影本质上其实是一张贴图,贴图的分辨率是最能提高质量的方法 提高之后可以看到阴影更细致了,但是颜色还没有加深

我们可以通过aoMap加深阴影颜色
aoMap叫做环境遮挡贴图,通过设置aoMap,我们可以加深阴影的颜色,这个aoMap我们需要设置在地板上
可以看到阴影的颜色更深了,这是aoMap的功劳

const floorTexture = new THREE.TextureLoader().load(
  "/src/assets/images/changjing2.jpg"
);
floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
floorTexture.repeat.set(1, 1);

const geom = new THREE.CircleGeometry(20, 29);
const material = new THREE.MeshStandardMaterial({
  // 强制three使用双面渲染这个平面
  side: THREE.DoubleSide,
  transparent: true,
//   aoMap能让有阴影的地方更明显
  aoMap: floorTexture,
  aoMapIntensity:1.5
});
const mesh = new THREE.Mesh(geom, material);
mesh.position.set(0, -0.02, 0);
scene.add(mesh);
mesh.rotation.x -= (90 * Math.PI) / 180;
mesh.receiveShadow = true;

然后我们设置一下柔和阴影,让其边缘变的模糊

directionalLight.shadow.radius = 8; // 柔化阴影边缘

阴影的最终效果到这里差不多了,剩下的参数大家可以自己调整一下

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

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

相关文章

格恩朗管段超声波流量计:流量测量先锋

在流量测量技术不断迭代的浪潮中,格恩朗自 2019 年创立起,便以开拓者的姿态投身其中,致力于为全球用户提供先进、精准的流量测量解决方案。其旗下的管段超声波流量计,一经推出,便迅速吸引了行业的目光,成为…

图论 判断是否有环

前言:有点忘记是怎么判断一个图中是否是有环 如果是一个无向图,其实可以直接dfs,加上一个vis数组来一起判断 如果是有向图呢, class Solution:def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool…

EasyDarwin的配置与使用

一.语言配置 准备go语言 All releases - The Go Programming Language 增加系统环境变量 让其生效 二.项目配置 Clone项目并解压 git clone https://github.com/EasyDarwin/EasyDarwin.git cd EasyDarwin go mod tidy 紧接着 make build/linux cd build cd EasyDarwin-lin-&qu…

【Android】基于SurfaceControlViewHost实现跨进程渲染

1 前言 本文将介绍基于 SurfaceControlViewHost 实现跨进程渲染普通 View 和 GlSurfaceView,力求用最简单的 Demo,介绍 SurfaceControlViewHost 的应用,方便读者轻松扣出核心代码应用到自己的业务中。 核心代码片段如下。 1)服务端…

vue+ThreeJs 创造自动选择的甜甜圈(圆环)

嗨,我是小路。今天主要和大家分享的主题是“vueThreeJs 创造自动选择的甜甜圈”。 一个漂浮在页面中央的 3D 圆环,多个图标/文本/图片均匀分布在圆周上。它会自动缓慢旋转,形成动态视觉焦点。这就是今天要搭建的项目,并对…

能说一下JVM的内存区域吗

根据Java虚拟机的规范,JVM的内存区域可以细分为程序计数器、虚拟机栈、本地方法栈、堆和方法区。 其中方法区和线程是共享的,虚拟机栈、本地方法区和程序计数器是线程私有的。 介绍一下程序计数器? 程序计数器也被称为PC寄存器。是一块较小…

东方仙盟_灵颜妙手——表单样式——仙盟创梦IDE

代码 .东方仙盟_灵颜妙手 {background-color: #f0f8ff;padding: 10px;display: block;width:100%;height: 100%;}.东方仙盟_灵颜妙手 .表单 {max-width: 800px;margin: 0 auto;background-color: white;border-radius: 8px;box-shadow: 0 0 10px rgba(0, 123, 255, 0.1);paddin…

输入一串字符,统计其中字母的个数

#include <stdio.h> int main() { char ch; int count 0; printf("请输入一串字符&#xff1a;\n"); while ((ch getchar())! \n) { if ((ch > a && ch < z) || (ch > A && ch < Z)) { count; } } printf("字母的个数为&a…

进程IO之 进程

一、进程相关概念 1.什么是进程 程序&#xff1a;静态的&#xff0c;编译好的可执行文件&#xff0c;存放在磁盘中的指令和数据的集合 进程&#xff1a;动态的&#xff0c;是程序的一次执行过程&#xff0c;是独立的可调度的任务 2.进程的特点 &#xff08;1&#xff09;对…

OpenGL Chan视频学习-5 Vertex Attributes and Layouts in OpenGL

bilibili视频链接&#xff1a; 【最好的OpenGL教程之一】https://www.bilibili.com/video/BV1MJ411u7Bc?p5&vd_source44b77bde056381262ee55e448b9b1973 一、知识点整理 1.1.OpenGL管线工作流程 为显卡提供绘制的所有数据&#xff0c;并将数据存储在GPU内存使用着色器&…

ESP32学习笔记_Peripherals(3)——ADC

摘要 本博客介绍了ESP32-S3芯片内置SAR ADC的原理、参考电压、分辨率、信号衰减等基础知识&#xff0c;并讲解了如何使用ESP-IDF驱动库实现ADC的连续采样&#xff08;DMA&#xff09;功能&#xff0c;演示了多通道模拟信号&#xff08;如摇杆模块&#xff09;的采集与处理流程…

QT学习一

对于选择qmake还是cmake&#xff0c;现在写的暂时先用qmake 1.命名规范和快捷键 2.按钮控件常用API //创建第一个按钮QPushButton * btn new QPushButton;//让btn对象 依赖在mywidget窗口中btn->setParent(this);//显示文本btn->setText("第一个按钮");//创建…

黑马点评Reids重点详解(Reids使用重点)

目录 一、短信登录&#xff08;redisseesion&#xff09; 基于Session实现登录流程 &#x1f504; 图中关键模块解释&#xff1a; 利用seesion登录的问题 设计key的具体细节 整体访问流程 二、商户查询缓存 reids与数据库主动更新的三种方案 缓存穿透 缓存雪崩问题及…

小米2025年校招笔试真题手撕(一)

一、题目 小A每天都要吃a,b两种面包各一个。而他有n个不同的面包机&#xff0c;不同面包机制作面包的时间各不相同。第i台面包机制作a面包 需要花费ai的时间&#xff0c;制作b面包则需要花费bi的时间。 为能尽快吃到这两种面包&#xff0c;小A可以选择两个不同的面包机x&…

《软件工程》第 11 章 - 结构化软件开发

结构化软件开发是一种传统且经典的软件开发方法&#xff0c;它强调将软件系统分解为多个独立的模块&#xff0c;通过数据流和控制流来描述系统的行为。本章将结合 Java 代码示例、可视化图表&#xff0c;深入讲解面向数据流的分析与设计方法以及实时系统设计的相关内容。 11.1 …

Neo4j(三) - 使用Java操作Neo4j详解

文章目录 前言一、创建项目二、导入依赖三、节点和关系数据打印四、创建节点与关系五、查询数据方法六、更新数据方法七、删除节点与关系方法八、合并数据方法九、完整代码1. 完整代码2. 项目下载 前言 本文介绍通过 Java 操作 Neo4j 图数据库的完整流程。主要涵盖开发环境搭建…

蓝桥杯3503 更小的数

问题描述 小蓝有一个长度均为 n 且仅由数字字符 0∼9 组成的字符串&#xff0c;下标从 0 到 n−1&#xff0c;你可以将其视作是一个具有 n 位的十进制数字 num&#xff0c;小蓝可以从 num 中选出一段连续的子串并将子串进行反转&#xff0c;最多反转一次。 小蓝想要将选出的子…

算法-全排列

1、全排列函数的使用 举例&#xff1a;{1,2,3}的全排列 #include<iostream> #include<bits/stdc.h> using namespace std; typedef long long ll; int main(){ll a[3] {1, 2, 3};do{for (ll i 0; i < 3;i){cout << a[i] << " ";}cout…

最好用的wordpress外贸主题

产品展示独立站wordpress主题 橙色的首页大banner外贸英文wordpress主题&#xff0c;适合用于产品展示型的外贸网站。 https://www.jianzhanpress.com/?p8556 Machine机器wordpress模板 宽屏简洁实用的wordpress外贸建站模板&#xff0c;适合工业机器生产、加工、制造的外贸…

2025 河北ICPC( D. 金泰园(二分)-- C.年少的誓约(公式转化))

文章目录 2025 河北ICPCD. 金泰园&#xff08;二分&#xff09;C.年少的誓约(公式转化)总结 2025 河北ICPC 题目链接&#xff1a; Attachments - The 9th Hebei Collegiate Programming Contest - Codeforces sdccpc20250522 - Virtual Judge 赛时&#xff1a;5道 D. 金泰…