Three.js はモデルマテリアルの局所的なグロー効果を実現し、グローがシーンの背景画像の表示に影響を与える問題を解決します

1.Three.jsはモデルマテリアルの局所的なグロー効果を実現します

2. グローエフェクトがシーンの背景画像の表示に影響を与える問題を解決

関連する API の使用:

1. EffectComposer (レンダリング後の処理のための一般的なフレームワーク。複数のレンダリング パス (パス) を組み合わせて特定の視覚効果を作成するために使用されます)

2. RenderPass (シーンのレンダリングに使用されるチャネルです。シーンとカメラを入力として受け取り、Three.js のデフォルトのレンダラ (レンダラー) を使用してシーンをレンダリングし、結果を次のレンダリング パスに出力します)

3. UnrealBloomPass (three.js でブルーム効果を実現するための後処理エフェクトです。ガウスぼかしとスクリーン ブレンディング技術により、輝度の高い領域を拡散してリアルなブルーム効果を実現します。)

4. ShaderPass (カスタム シェーダのチャネルです。これにより、カスタム シェーダ コードを指定し、それをシーンのレンダリング結果に適用できます。これにより、ガウス ブラー、ポスト シェーダなどのさまざまなグラフィックス効果を作成できます。加工エフェクトなど)

外部 glb、fbx、gltf、obj モデル ファイルを読み込む Three.js に関する以前の記事に基づいて、新しい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): 通常のレンダリング シーン用の 2 つのコンポジターを作成する必要があります。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を参照してください。

インターフェース効果の比較
ここに画像の説明を挿入
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_43835425/article/details/132370548