Three.js 实现模型材质局部辉光效果和解决辉光影响场景背景图显示的问题

news2025/1/18 20:05:31

1.Three.js 实现模型材质局部辉光效果

2.解决辉光效果影响场景背景图显示的问题

相关API的使用:

1. EffectComposer(渲染后处理的通用框架,用于将多个渲染通道(pass)组合在一起创建特定的视觉效果)

2. RenderPass(是用于渲染场景的通道。它将场景和相机作为输入,使用Three.js默认的渲染器(renderer)来进行场景渲染,并将结果输出给下一个渲染通道)

3. UnrealBloomPass(是 three.js 中用于实现泛光效果的后期处理效果,通过高斯模糊和屏幕混合技术,将亮度较高的区域扩散开来,从而实现逼真的泛光效果。)

4. ShaderPass(是一个自定义着色器的通道。它允许你指定自定义的着色器代码,并将其应用于场景的渲染结果。这样你可以创建各种各样的图形效果,如高斯模糊、后处理效果等)

在上一篇 Three.js加载外部glb,fbx,gltf,obj 模型文件 的文章基础上新增一个 createEffectComposer(效果合成器方法)和sceneAnimation( 效果器渲染方法)以及getFlowMeaterList(获取需要辉光效果材质的方法)

首先引入相关的api

import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
import { UnrealBloomPass} from 'three/examples/jsm/postprocessing/OutlinePass.js'
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'

创建效果合成器方法(createEffectComposer):需要创建两个合成器 effectComposer 用于正常渲染场景,glowComposer用于渲染辉光效果

createEffectComposer() {
		const { clientHeight, clientWidth } = this.container
		// 场景渲染器
		this.effectComposer = new EffectComposer(this.renderer)
		const renderPass = new RenderPass(this.scene, this.camera)
		this.effectComposer.addPass(renderPass)
		//创建辉光效果
		this.unrealBloomPass = new UnrealBloomPass(new THREE.Vector2(clientWidth, clientHeight), 0, 0, 0)
		this.unrealBloomPass.threshold = 1 // 辉光强度
		this.unrealBloomPass.strength = 0 // 辉光阈值
		this.unrealBloomPass.radius = 1 //辉光半径
		this.unrealBloomPass.renderToScreen = false // 
		// 辉光合成器
		this.glowComposer = new EffectComposer(this.renderer)
		this.glowComposer.renderToScreen = false
		this.glowComposer.addPass(new RenderPass(this.scene, this.camera))
		this.glowComposer.addPass(this.unrealBloomPass)
		// 着色器
		let shaderPass = new ShaderPass(new THREE.ShaderMaterial({
			uniforms: {
				baseTexture: { value: null },
				bloomTexture: { value: this.glowComposer.renderTarget2.texture },
				tDiffuse: {
					value: null
				}
			},
			vertexShader:'\t\t\tvarying vec2 vUv;\n' +
                         '\n' +
                         '\t\t\tvoid main() {\n' +
                         '\n' +
                         '\t\t\t\tvUv = uv;\n' +
                          '\n' +
                          '\t\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n' +
                         '\n' +
                         '\t\t\t}',
			fragmentShader:'\t\t\tuniform sampler2D baseTexture;\n' +
                            '\t\t\tuniform sampler2D bloomTexture;\n' +
                            '\n' +
                            '\t\t\tvarying vec2 vUv;\n' +
                             '\n' +
                            '\t\t\tvoid main() {\n' +
                            '\n' +
                            '\t\t\t\tgl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );\n' +
                            '\n' +
                           '\t\t\t}',
			defines: {}
		}), 'baseTexture')

		shaderPass.renderToScreen = true
		shaderPass.needsSwap = true
		this.effectComposer.addPass(shaderPass)
	}

获取需要辉光渲染的材质:

   getFlowMeaterList(){
        const modelMaterialList= []
  		this.model.traverse((v) => {
			if (v.isMesh && v.material) {
	            	const { name, color,map } = v.material
					// 统一将模型材质 设置为 MeshLambertMaterial 类型
					v.material = new THREE.MeshLambertMaterial({
						map,
						transparent: true,
						color,
						name,
					})
					modelMaterialList.push(v)	
			}
		})
		this.glowMaterialList = modelMaterialList.map(v=>v.name)
   }

渲染场景方法(sceneAnimation):处理不需要辉光的材质。注意:辉光效果会影响场景背景图的正常显示需要单独处理这里通过 instanceof THREE.Scene 判断是否是场景材质然后进行单独处理

   sceneAnimation() {
		this.renderAnimation = requestAnimationFrame(() => this.sceneAnimation())
		this.controls.update()
		// 将不需要处理辉光的材质进行存储备份
		this.scene.traverse((v) => {
		     // 备份一份场景背景然后清空
			if (v instanceof THREE.Scene) {
				this.materials.scene = v.background
				v.background = null
			}
			if (!this.glowMaterialList.includes(v.name) && v.isMesh) {
			   // 备份当前材质内容
				this.materials[v.uuid] = v.material
				// 将不需要辉光的材质设置为黑色
				v.material = new THREE.MeshBasicMaterial({ color: 'black' })
			}
		})
		// 执行辉光效果器渲染
		this.glowComposer.render()
		// 在辉光渲染器执行完之后在恢复材质原效果
		this.scene.traverse((v) => {
			if (this.materials[v.uuid]) {
				v.material = this.materials[v.uuid]
				delete this.materials[v.uuid]
			}
			if (v instanceof THREE.Scene) {
				v.background = this.materials.scene
				delete this.materials.scene
			}
		})
		// 执行场景效果器渲染
		this.effectComposer.render()
	}

完整的代码可参考:https://gitee.com/ZHANG_6666/Three.js3D/blob/master/src/views/renderModel.js

界面效果对比
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

【100天精通python】Day36:GUI界面编程_Tkinter高级功能操作和示例

目录 专栏导读 一、GUI 高级功能 1 自定义主题和样式 2 实现拖放功能 3 多线程和异步编程 二、实战项目 1. 待办事项应用 2. 图像查看器 3. 文本编辑器 4 添加动画和过渡效果 5 多界面和多线程示例 专栏导读 专栏订阅地址:https://blog.csdn.net/qq_358…

前端-初始化Vue3+TypeScript

如果使用如下命令初始化项目,项目很干净,很适合了解项目的各个结构。 npm init vitelatest如果使用如下命令初始化项目,是可以选择你需要的组件 npm init vuelatest

Docker 容器数据卷

Docker挂载主机目录访问如果出现cannot open directory .: Permission denied 解决办法:在挂载目录后多加一个--privilegedtrue参数即可 如果是CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行…

你家的wifi安全么?

在移动互联网已经相当普及的今天,家用Wifi已经成为居家必备设备了,但你有没有考虑过这样一个问题,“我家的Wifi安全么,有没有可能被别人蹭网,或者被黑客登录进来,窃取数据?”下面就结合目前主流…

Bryntum Scheduler Pro 5.5.1 Crack

BRYNTUM 调度程序专业版,专业的日程安排小部件 Bryntum Scheduler Pro 5.5.1 一个专业有大脑的调度UI组件。Scheduler Pro 可帮助您安排任务,同时考虑资源和任务的可用性。 连接您的任务 让 Scheduler Pro 处理剩下的事情。它将根据您定义的链接安排您的任务并遵守任…

3D echarts在vue中的使用

注意:高度问题要如此设置即可解决 参考1 参考2

由于找不到d3dx9_43.dll无法继续执行代码怎么解决

我们在安装PS,吃鸡等软件跟游戏的时候,有可能安装完之后出现以下问题(特别是win7或者win8系统) 错误: 打开PS或者吃鸡等游戏的时候出现这个错误:无法启动此程序,因为计算机中丢失d3dx9_43.dll。…

如何让多线程步调一致?

前几天老板突然匆匆忙忙的过来说对账系统最近越来越慢了,能不能快速优化一下?我了解了对账系统的业务后,发现还是挺简单的,用户通过在线商城下单,会生成电子订单,保存在订单库。之后物流会生成派送单给用户…

免费写真软件让你畅享写真之旅

佳媛: 嗨,妙纯,听说你喜欢拍摄写真照,那你有什么简单的写真照制作方式推荐吗? 妙纯:当然,现在有很多古装写真软件,你可以利用这些软件来制作写真照片哦。 佳媛: 哦?那拍古装写真软…

Apache JMeter

下载 Apache JMeter 并安装 java链接 打开 apache-jmeter-5.4.1\bin 找到jmeter.bat 双击打开 或者 ApacheJMeter.jar 双击打开 设置中文 找到 options 》choose Language 》chinese 新建 计划 创建线程组 添加Http请求 配置元件添加请求头参数(content-type&…

LVS - DR

LVS-DR 数据流向 客户端发送请求到 Director Server(负载均衡器),请求的数据报文(源 IP 是 CIP,目标 IP 是 VIP)到达内核空间。Director Server 和 Real Server 在同一个网络中,数据通过二层数据链路层来传…

miniconda克隆arcpy

arcpy环境克隆 前言尝试思考到此结束 前言 最近遇到了一些问题,需要用到arcpy来处理一些东西,但众所周知,arcgis的arcpy是python 2.0的,我不是很喜欢;所以我安装了arcgis pro 2.8,我发现这也是个坑&#x…

Redis高可用:主从复制详解

目录 1.什么是主从复制? 2.优势 3.主从复制的原理 4.全量复制和增量复制 4.1 全量复制 4.2 增量复制 5.相关问题总结 5.1 当主服务器不进行持久化时复制的安全性 5.2 为什么主从全量复制使用RDB而不使用AOF? 5.3 为什么还有无磁盘复制模式&#xff…

【学习FreeRTOS】第10章——FreeRTOS时间片调度

1.时间片调度简介(同第2章1.3) 同等优先级任务轮流地享有相同的 CPU 时间(可设置), 叫时间片,在FreeRTOS中,一个时间片就等于SysTick 中断周期 首先Task1运行完一个时间片后,切换至Task2运行Task2运行完…

从SaaS到RPA,没有真正“完美”的解决方案!

众所周知,SaaS行业越来越卷,利润也越来越“薄”,这是传统软件厂商的悲哀,也是未来数字化行业不得不面对的冷峻现状之一。 随着基于aPaaS、低代码的解决方案之流行,SaaS行业变得越来越没有技术门槛,IT人员的…

Vue3.X 创建简单项目

一、环境安装与检查 首先,我们要确保我们安装了构建vue框架的环境,不会安装的请自行百度,有很多安装教程。检查环境 node -v # 如果没有安装nodejs请安装,安装教程自行百度 vue -V# 没有安装,请执行npm install -g v…

数据挖掘 | 零代码采集房源数据,支持自动翻页、数据排重等

1 前言 城市规划、商业选址等应用场景中经常会对地区房价、地域价值进行数据分析,其中地区楼盘房价是分析数据中重要的信息参考点,一些互联网网站上汇聚了大量房源信息,通过收集此类数据,能够对地区房价的分析提供参考依据。 如何…

ld链接文件和startup文件分析和优化--基于RT1176

ld链接文件关系到程序的代码段数据段bss段及其用户自定义段的运行位置,ld文件中的各个段都会在main函数之前,从加载域拷贝到运行域中。本章将具体介绍如何修改ld和startup文件。 软件平台:VSCODEGCC工具链 硬件平台:rt1176开发板…

如何在HTML中使用React

突发奇想 查了查真的可以,官方文档: 在网站中添加 React – React 开始 引入js <!-- 开发环境使用 --><script src"https://unpkg.com/react18/umd/react.development.js"></script><script src"https://unpkg.com/react-dom18/umd/reac…

ROS局部路径规划器插件teb_local_planner流程梳理(下)

在我之前的文章《ROS导航包Navigation中的 Movebase节点路径规划相关流程梳理》中已经介绍过Move_base节点调用局部路径规划器插件的接口函数是computeVelocityCommands&#xff0c;本部分来&#xff0c;我们从这个函数入手梳理teb_local_planner功能包的工作流程。 ☆注&#…