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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LVS+Keepalived

本章结构 1、Keepalived概述 2、Keepalived体系,主要的模块 3、Keepalived工作原理 4、LVSKeepalived的部署 一、Keepalived概述 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案,可以解决静态路由出现的单点故障问题。 vrrp通信原理&#…

学习笔记|课后练习解答|电磁炉LED实战|逻辑运算|STC32G单片机视频开发教程(冲哥)|第八集(下):课后练习分析与解答

课后练习解答 增加按键3,按下后表示启动,选择的对应的功能的LED持续闪烁,表示正在工作,且在工作的时候无法切换功能。 需求分解 1 增加按键3 #define KEY3 P34 //增加按键32 按下后表示启动 电平控制3 工作状态锁定 表示正在…

2023国赛数学建模A题B题C题D题资料思路汇总 高教社杯

本次比赛我们将会全程更新思路模型及代码,大家查看文末名片获取 之前国赛相关的资料和助攻可以查看 2022数学建模国赛C题思路分析_2022年数学建模c题思路_UST数模社_的博客-CSDN博客 2022国赛数学建模A题B题C题D题资料思路汇总 高教社杯_2022国赛a题题目_UST数模…

EasyExcel工具 Java导出Excel表数据

EasyExcel 优点坐标依赖读Excel最简单的读的对象写Excel最简单的写的对象最简单的读的监听器填充Excel简单填充(对象)复杂填充(对象和列表)官网:https://easyexcel.opensource.alibaba.com/ EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。…

电脑运行缓慢?4个方法,加速电脑运行!

“我电脑才用了没多久哎!怎么突然就变得运行很缓慢了呢?有什么方法可以加速电脑运行速度吗?真的很需要,看看我吧!” 电脑的运行速度快会让用户在使用电脑时感觉愉悦,而电脑运行缓慢可能会影响我们的工作效率…

C# 读取pcd点云文件数据

pcd文件有ascii 和二进制格式,ascii可以直接记事本打开,C#可以一行行读。但二进制格式的打开是乱码,如果尝试程序中读取,对比下看了数据也对不上。 这里可以使用pcl里的函数来读取pcd,无论二进制或ascii都可以正确读取…

lama-cleaner:基于SOTA AI 模型Stable Diffusion驱动的图像修复工具

介绍 由 SOTA AI 模型提供支持的图像修复工具。从照片中删除任何不需要的物体、缺陷、人物,或擦除并替换(由Stable Diffusion驱动)照片上的任何东西。 特征 1.多种SOTA AI模型 擦除模型:LaMa/LDM/ZITS/MAT/FcF/Manga 擦除和替…

Seaborn数据可视化(三)

1.绘制直方图 使用displot()绘制直方图。 import seaborn as sns import numpy as np import matplotlib.pyplot as plt# 生成随机数据 np.random.seed(0) data np.random.randn(1000)# 使用displot绘制直方图 sns.displot(data, bins10, kdeTrue)# 展示图形 plt.show() 结…

在数字化时代的挑战与解决:跨国大文件传输方法

随着当前数字化时代的迅猛发展,大文件跨国传输已经成为企业和个人工作中不可避免的挑战。尽管在这个过程中存在着许多技术障碍和困难,但是通过利用先进的技术和服务,我们仍然能够高效地完成跨国大文件传输的任务。本文将介绍几种常用的跨国快…

在C中使用Socket实现多线程异步TCP消息发送

目录 基础知识开始实现主要函数说明结束语 在本篇文章中,我们会探讨如何在C语言中使用socket来实现多线程,异步发送TCP消息的系统。虽然C标准库并没有原生支持异步和多线程编程,但是我们可以结合使用POSIX线程(pthread&#xff09…

Python爬虫——scrapy_日志信息以及日志级别

日志级别(由高到低) CRITICAL: 严重错误 ERROR: 一般错误 WARNING: 警告 INFO: 一般警告 DEBUG: 调试信息 默认的日志等级是DEBUG 只要出现了DEBUG或者DEBUG以上等级的日志,那么这些…

【Java从入门到精通|1】从特点到第一个Hello World程序

写在前面 在计算机编程领域,Java是一门广泛应用的高级编程语言。它以其强大的跨平台性能、丰富的库和生态系统以及易于学习的语法而备受开发者欢迎。本文将引导您逐步了解Java的特点、如何安装和配置开发环境,以及如何编写您的第一个Java程序。 一、Java…

Map和Set详解

一、二叉搜索树搜索树 1.二叉搜索树的概念 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都…

再JAVA中如何使用qsort对类进行排序?

目录 结论&#xff1a; 解析&#xff1a; 结论&#xff1a; import java.util.Arrays;class Person implements Comparable<Person>{public String name;public int age;public Person(String name, int age) {this.name name;this.age age;}Overridepublic Stri…

win10 下运行 npm run watch-poll问题

背景&#xff1a;在本地练习laravel项目&#xff0c;windows 宝塔环境&#xff08;之前装过ubuntu子系统&#xff0c;很慢&#xff0c;就放弃了。有知道的兄弟说下&#xff0c;抱拳&#xff09;。以下命令我是在本地项目中用git bash里运行的&#xff0c;最好用管理员权限打开你…

CSS自学框架之动画

这一节&#xff0c;自学CSS动画。主要学习了淡入淡出、淡入缩放、缩放、移动、旋转动画效果。先看一下成果。 优雅的过渡动画&#xff0c;为你的页面添加另一份趣味&#xff01; 在你的选择器里插入 animation 属性&#xff0c;并添加框架内置的 keyframes 即可实现&#xff0…

实例041 获取桌面大小

实例说明 获取桌面分辨率可以使用API函数GetDeviceCaps&#xff0c;但API函数参数较多&#xff0c;使用不方便&#xff0c;如何更方便的获取桌面分辨率呢&#xff1f;在本例中&#xff0c;通过读取Screen对象的属性&#xff0c;来获取桌面分辨率信息&#xff0c;以像素为单位。…

温故知新之:接口和抽象类有什么区别?

本文以下内容基于 JDK 8 版本。 1、接口介绍 接口是 Java 语言中的一个抽象类型&#xff0c;用于定义对象的公共行为。它的创建关键字是 interface&#xff0c;在接口的实现中可以定义方法和常量&#xff0c;其普通方法是不能有具体的代码实现的&#xff0c;而在 JDK 8 之后&…

前端单点登录SSO面试回答

JWT鉴权机制 1.JWT用于登录身份验证 2.用户登录成功后&#xff0c;后端通过JWT机制生成一个token&#xff0c;返回给客户端 3.客户端后续的每次请求都需要携带token&#xff0c;放在header的authorization中 4.后端从authorization中拿到token后&#xff0c;通过secretKey进…

【报错】yarn --version Unrecognized option: --version Error...

文章目录 问题分析解决问题 在使用 npm install -g yarn 全局安装 yarn 后,查看yarn 的版本号,报错如下 PS D:\global-data-display> yarn --version Unrecognized option: --version Error: Could