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

news2025/1/11 21:41:30

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/915751.html

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

相关文章

iPhone 14 Pro 动态岛的功能和使用方法详解

当iPhone 14 Pro机型发布时,苹果公司将软件功能与屏幕顶部的药丸状切口创新集成,称之为“灵动岛”,这让许多人感到惊讶。这篇文章解释了它的功能、工作原理,以及你如何与它互动以执行动作。 一、什么是灵动岛?它是如何工作的 在谣言周期的早期‌iPhone 14 Pro‌ 在宣布时…

只考一门数据结构,计算机学硕复录比1:1的山东双非学校考情分析

青岛理工大学 考研难度(☆) 内容:23考情概况(拟录取和复试分析)、院校概况、23专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1420字,预计阅读:3分钟 2023考情概况 青岛理工…

Linux下的系统编程——基础操作(一)

前言: linux系统编程是基于Linux系统进行程序开发的一个过程,主要涉及到的是linux系统中的函数使用如下图所示: 最外层的是咱们的应用程序,这部分程序大多调用的是咱们标准库,或者说是C库,这部分库函数能…

PDF中的表格怎么转换为Excel?这两个工具一定得收藏!

PDF是一种常见的文件格式,它可以保持文件的原始样式和内容,但是也有一些缺点,比如不易编辑和处理数据。如果你想要将PDF中的表格或数据导出到Excel中,以便进行分析、计算或制作图表,那么你可能需要一个专业的PDF转Exce…

Window异常提示:“为了对电脑进行保护,已经阻止此应用”

目录 1.Window异常提示图片: 2.家庭版额外需要执行的解决方式: 3.本地组策略编辑器(后续家庭版和专业版一致) 4.禁用后重新启动电脑就可以正常运行程序了 1.Window异常提示图片: 2.家庭版额外需要执行的解决方式: 代码&#xff…

超纯水中硼离子去除,特种除硼树脂CH-99

超纯水是指水中杂质含量极低的一种水质,其中矢量硼是一种常见的杂质。矢量硼的存在会影响超纯水的质量,因此需要采取一定的方法去除。 常用的去除矢量硼的方法有离子交换法、反渗透法和电化学法等。 电化学法: 是一种利用电化学反应对水中…

Java JDBC学习教程

Java JDBC JDBC 独立于数据库JDBC 不独立于SQLJDBC 不适用于非关系数据库流行的关系数据库JDBC 教程范围JDBC 核心概念JDBC 示例加载JDBC驱动程序打开数据库连接创建语句更新数据库查询数据库关闭数据库连接 Java JDBC API(Java Database Connectivity&#xff09…

无涯教程-PHP - preg_grep()函数

preg_grep() - 语法 array preg_grep ( string $pattern, array $input [, int $flags] ); 返回由与给定模式匹配的输入数组元素组成的数组。 如果将flag设置为PREG_GREP_INVERT,则此函数返回输入数组中与给定模式不匹配的元素。 preg_grep() - 返回值 返回使用…

8路光栅尺磁栅尺编码器或16路高速DI脉冲信号转Modbus TCP网络模块 YL99-RJ45

特点: ● 光栅尺磁栅尺解码转换成标准Modbus TCP协议 ● 高速光栅尺磁栅尺4倍频计数,频率可达5MHz ● 模块可以输出5V的电源给光栅尺或传感器供电 ● 支持8个光栅尺同时计数,可识别正反转 ● 可以设置作为16路独立DI高速计数器 ● 可网…

vue 简单实验 v-bind 变量与html属性绑定

1.代码 <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"bind-attribute"><span v-bind:title"message">鼠标悬停几秒钟查看此处动态绑定的提示信息&#xff01;</sp…

“产业应用创新奖2023”启动征集

当前&#xff0c;人工智能已经成为新一轮科技革命和产业变革的重要驱动力量&#xff0c;基于强算法、大算力和大数据的大模型成为主流方向。文心大模型和飞桨一直致力于发挥算法模型技术优势&#xff0c;助力AI 大生产加速升级。 文心飞桨赋能千行百业 产业创新不断涌现 数字医…

你做的可视化大屏老被老板嫌弃丑?那是你没掌握这7个动态效果!

数据可视化大屏成为了最近的爆火需求&#xff0c;自从老李我在朋友圈发了一条关于可视化大屏的朋友圈&#xff0c;客户、亲戚、朋友、同学都过来问我这种可视化大屏是怎么做出来的&#xff0c;要花多少钱&#xff1f; 老李也很实诚&#xff0c;直接跟他们说&#xff0c;免费&a…

概率论与数理统计:第七章:参数估计 第八章:假设检验

文章目录 Ch7. 参数估计7.1 点估计1.矩估计2.最大似然估计(1)离散型(2)连续型 7.2 评价估计量优良性的标准(1)无偏性 (无偏估计)(2)有效性(3)一致性 7.3 区间估计1.置信区间、置信度2.求μ的置信区间 Ch8. 假设检验1.拒绝域α、接受域1-α、H₀原假设、H₁备择假设2.双边检验、…

初识 JVM 01

JVM JRE JDK的关系 JVM 的内存机构 程序计数器 java指令的执行流程&#xff1a; 1 右侧的java源代码编译为左侧的java字节码&#xff08;右侧第一个方块对应左侧第一个方块&#xff09; 2 字节码 经过解释器 变为机器码 3 机器码就可以被cpu来执行 程序计数器的作用就…

Linux学习之samba服务

yum install -y samba安装samba。 安装完成如下&#xff1a; /etc/samba/smb.conf是samba配置文件&#xff0c;内容如下&#xff1a; # See smb.conf.example for a more detailed config file or # read the smb.conf manpage. # Run testparm to verify the config is cor…

亿发智能定制系统规范食品饮料行业质量管理,ERP解决方案助力业务增长

随着食品生产业态的不断复杂化和食品风险的逐渐凸显&#xff0c;食品饮料生产商面临着更大的挑战和机遇,需要与时俱进&#xff0c;借助数字化手段建立完整的质量管理体系&#xff0c;有效降低食品事故的风险。同时&#xff0c;面对数字化时代&#xff0c;食品饮料生产商需要一套…

正则表达式一小时学完

闯关式学习Regex 正则表达式&#xff0c;我感觉挺不错的&#xff0c;记录一下。 遇到不会的题&#xff0c;可以评论交流。 真的很不错 链接 Regex Learn - Step by step, from zero to advanced.

ui设计师年终总结(合集)

ui设计师年终总结篇一 xx年很快就会过去了&#xff0c;掐指一算&#xff0c;来到同程已经整整一年了&#xff0c;在这里我对我一年以来的工作情况进行简要的总结&#xff0c;算是对公司也是对个人这段时间的工作的一个交代&#xff0c;详细内容请看下文ui设计师年终个人总结。…

快速上手Linux核心命令:文件内容相关命令

前言 上一篇中已经预告&#xff0c;我们这篇主要说一说Linux中文件内容查看处理相关的命令。一共16个命令&#xff0c;其中 标注的为重点命令&#xff0c;工作中用的也比较多&#xff0c;需要熟练掌握 cat 合并文件或查看文件内容 1、简介 cat 是concatenate 单词的缩写&a…