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 = falsethis.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 = trueshaderPass.needsSwap = truethis.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.backgroundv.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.scenedelete this.materials.scene}})// 执行场景效果器渲染this.effectComposer.render()}

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

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

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

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

相关文章

Training Technology One : Distribution

文章目录 训练命令初始化获得分布式参数设定GPU初始化同步输出控制(非常规流程,技巧)*分布式判断(非常规流程,技巧)* 数据集模型训练 本节内容以BLIP的分布式训练代码为蓝本介绍分布式训练的过程. 本文采用DDP作为分布式框架, 库为torch.distributed. 训练命令 python -m tor…

Docker搭建LNMP----(超详细)

目录 ​编辑 一、项目环境 1.1 所有安装包下载: 1.3 服务器环境 1.4任务需求 二、Ngin 2.1、建立工作目录 2.2 编写 Dockerfile 脚本 2.3准备 nginx.conf 配置文件 2.4生成镜像 2.5创建自定义网络 2.6启动镜像容器 2.7验证 nginx、 三、Mysql 3.1建立…

http请求中token和cookie有什么区别? 连环问:session和JWT那个更好? 连环问:如何实现SSO单点登录?

参考地址:SameSite cookies explained cookie: 1. HTTP无状态,每次请求都要带cookie,以帮助识别身份 2. 服务端也可以向客户端set-cookie, cookie大小限制4kb 3. 默认有跨域限制:不可跨域共享、传递cookie cookie本地存储: 1. HTML5之前 cookie 常被用于本地存储 …

APEX内置验证与授权管理

参考博客:(真的很好的教程,感谢!) 09技术太卷我学APEX-定制页面及导航菜单权限_白龙马5217的博客-CSDN博客https://blog.csdn.net/html5builder/article/details/128816236?spm1001.2014.3001.5501 1 应用程序安全性…

海外网红营销中的创新技术与趋势:AI、AR和VR的应用探索

随着全球数字化时代的不断发展,互联网已经成为连接人们的桥梁,而社交媒体则在其中扮演着举足轻重的角色。在这个全球性的社交媒体网络中,海外网红以其独特的个人魅力和内容创作能力迅速崭露头角。而为了在竞争激烈的市场中脱颖而出&#xff0…

并发和并行的区别 以及什么是串行,还有同步和异步;阻塞非阻塞;还有进程、线程、协程一次说清。

。 并发和并行的区别 以及什么是串行,还有同步和异步:阻塞非阻塞: 并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。并行:单位时间内&#xf…

BBS项目 day05 后台系统功能(首页、文章列表展示、添加文章、上传文件(uuid生成新的文件名))

一、后台功能的初始配置 1. urls.py路由分发 re_path(app02/, include(app02.urls)),2.app02/urls.py from django.urls import path, re_path, include from app02 import viewsurlpatterns [path(home/, views.home),path(article_list/, views.article_list),path(add_ar…

单片机(二)使用位移 让灯亮

一:硬件电路 P2 口: P2.0~ P2.7 是这些 I0 口 LED 阳极接 电源 , P20 口 为低电平 可以让 LED灯 亮 二:软件实现部分 两种 ① 通过循环 来展示从左 到右 #include "reg52.h"#define LED_PORT P2 // 定义单片机的P2端…

软考A计划-系统集成项目管理工程师-项目变更管理

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 👉关于作者 专注于Android/Unity和各种游…

Jackson 实现 JSON 字段类型处理器

1.处理过程 1.1 实体类设为autoResultMap true TableName(value "table1", autoResultMap true)1.2 字段 typeHandler JacksonTypeHandler.class ApiModelProperty(value "明细")TableField(value "detail", typeHandler JacksonTypeHa…

【Spring Boot】Spring Boot整合多数据源

文章目录 前言一、基本概念1.1 什么是多数据源?1.2 为什么要使用多数据源? 二、如何在 Spring Boot 中整合多数据源?2.1 基本配置2.2 项目代码2.3 注意事项 前言 在实际的开发工作中,我们经常会遇到需要整合多个数据源的情况&…

Nginx使用keepalived配置VIP

VIP常用于负载均衡的高可用,使用VIP可以给多个主机绑定一个IP,这样,当某个负载应用挂了之后,可以自动切到另一个负载。 我这里是在k8s环境中做的测试,集群中有6个节点,我给140和141两个节点配置VIP。 1. 安…

Python土力学与基础工程计算.PDF-压水试验

Python 求解代码如下: 1. import math 2. 3. # 输入参数 4. L 2.0 # 试验段长度,m 5. Q 120.0 # 第三阶段计算流量,L/min 6. p 1.5 # 第三阶段试验段压力,MPa 7. r0 0.05 # 钻孔半径,m 8. 9. # 计算透…

Docker 微服务实战

1. 通过IDEA新建一个普通微服务模块 1.1 建Module docker_boot 1.2 改写pom <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance&…

CDN、DNS、ADN、SCDN、DCDN、ECDN、PCDN、融合CDN傻傻分不清楚,一文全部搞懂

一、CDN是什么&#xff1f; CDN的全称是Content Delivery Network&#xff0c;即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节&#xff0c;使内容传输得更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之…

1267. 统计参与通信的服务器

这里有一幅服务器分布图&#xff0c;服务器的位置标识在 m * n 的整数矩阵网格 grid 中&#xff0c;1 表示单元格上有服务器&#xff0c;0 表示没有。 如果两台服务器位于同一行或者同一列&#xff0c;我们就认为它们之间可以进行通信。 请你统计并返回能够与至少一台其他服务…

算法练习(9):牛客在线编程09 双指针

package jz.bm;import jz.Interval;import java.util.ArrayList; import java.util.HashMap;public class bm9 {/*** BM87 合并两个有序的数组*/public void merge(int A[], int m, int B[], int n) {int i m - 1, j n - 1, k m n - 1;while (i > 0 || j > 0) {int a…

我是如何使用Spring Retry减少1000 行代码

使用 Spring Retry 重构代码的综合指南。 问题介绍 在我的日常工作中&#xff0c;我主要负责开发一个庞大的金融应用程序。当客户发送请求时&#xff0c;我们使用他们的用户 ID 从第三方服务获取他们的帐户信息&#xff0c;保存交易并更新缓存中的详细信息。尽管整个流程看起来…

Elasticsearch简介及安装

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

H36M VS 3DPW datasets

1采集设备方面 H36M使用了高精度的多视角摄像机动态捕捉系统获得了非常准确和连贯的3D关节坐标标注。 3DPW使用了单目摄像机与IMU的复合传感系统进行采集,存在一定程度的标注噪声。 2场景环境方面 H36M主要针对室内定向动作,背景单一简洁。 3DPW重点是室外复杂环境中人的自…