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.hqwc.cn/news/76045.html

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

相关文章

实例040 限制窗体大小

实例说明 Windows窗体是可以随意改变大小的,然而对于一些要求严格的窗体,开发人员不希望用户随意的改变其大小,例如,定位准确的地图和游戏软件等。遇到这种情况必须对窗口的大小进行一些限制。本例设计一个限制了大小的窗体&#…

vueuse常用方法

useDateFormat 时间格式化 <script setup lang"ts">import { useNow, useDateFormat } from vueuse/coreconst formatted useDateFormat(useNow(), YYYY-MM-DD HH:mm:ss)</script><template><div>{{ formatted }}</div> </templa…

Delphi 安卓App自动升级

Androidapi.JNI.Support引用这个单元 procedure _InstallApk(Apk: string); varLFile: JFile;LIntent: JIntent; beginLFile : TJFile.JavaClass.init(StringToJString(ExtractFilePath(Apk)), StringToJstring(ExtractFileName(Apk)));LIntent : TJIntent.Create;LIntent.set…

spring(15) SpringBoot启动过程

目录 一、过程简介二、过程流程图三、源码分析1、运行 SpringApplication.run() 方法2、确定应用程序类型3、加载所有的初始化器4、加载所有的监听器5、设置程序运行的主类6、开启计时器7、将 java.awt.headless 设置为 true8、获取并启用监听器9、设置应用程序参数10、准备环境…

实现简单的element-table的拖拽效果

第一步&#xff0c;先随便创建element表格 <el-table ref"dragTable" :data"tableData" style"width: 100%" border fit highlight-current-row><el-table-column label"日期" width"180"><template slot-sc…

python高级基础

文章目录 python高级基础闭包修饰器单例模式跟工厂模式工厂模式单例模式 多线程多进程创建websocket服务端手写客户端 python高级基础 闭包 简单解释一下闭包就是可以在内部访问外部函数的变量&#xff0c;因为如果声明全局变量&#xff0c;那在后面就有可能会修改 在闭包中的…

前端vue自定义柱形图 选中更改柱形图颜色及文字标注颜色

随着技术的发展&#xff0c;开发的复杂度也越来越高&#xff0c;传统开发方式将一个系统做成了整块应用&#xff0c;经常出现的情况就是一个小小的改动或者一个小功能的增加可能会引起整体逻辑的修改&#xff0c;造成牵一发而动全身。 通过组件化开发&#xff0c;可以有效实现…

RS232、RS422、RS485硬件及RS指令、RS2指令应用知识学习

RS232、RS422、RS485硬件及RS指令、RS2指令应用知识学习 一、串行&#xff08;异步/同步)通讯、并行通讯、以太网通讯 二、单工通讯/半双工通讯/双工通讯 三、常用硬件接口&#xff08;工业上基本是RS485两线制的接线&#xff09; 常用硬件接口RS232/RS422/RS485&#xff0c;…

LeetCode--HOT100题(37)

目录 题目描述&#xff1a;104. 二叉树的最大深度&#xff08;简单&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;104. 二叉树的最大深度&#xff08;简单&#xff09; 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远…

快速上手PyCharm指南

PyCharm简介 PyCharm是一种Python IDE&#xff08;Integrated Development Environment&#xff0c;集成开发环境&#xff09;&#xff0c;带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具&#xff0c;比如调试、语法高亮、项目管理、代码跳转、智能提示、自动…

怎么借助ChatGPT处理数据结构的问题

目录 使用ChatGPT进行数据格式化转换 代码示例 ChatGPT格式化数据提示语 代码示例 批量格式化数据提示语 代码示例 ChatGPT生成的格式化批处理代码 使用ChatGPT合并不同数据源的数据 合并数据提示语 自动合并数据提示语 ChatGPT生成的自动合并代码 结论 数据合并是…

二重积分小技巧---交换积分

又一个奇技淫巧。 ∫ 0 1 d y ∫ y 1 x 3 1 d x ? \int _0 ^1 dy \int _{\sqrt y} ^ 1 \sqrt{x^3 1} dx ? ∫01​dy∫y ​1​x31 ​dx? 解析&#xff1a; 不说话&#xff0c;看下图&#xff1a; ∫ 0 1 d y ∫ y 1 x 3 1 d x ∫ 0 1 d x ∫ 0 x 2 x 3 1 d y ∫ 0 …