Three.js percebe o efeito de brilho local do material do modelo e resolve o problema de que o brilho afeta a exibição da imagem de fundo da cena

1.Three.js realiza o efeito de brilho local do material do modelo

2. Resolva o problema de que o efeito de brilho afeta a exibição da imagem de fundo da cena

Uso de APIs relacionadas:

1. EffectComposer (uma estrutura geral para processamento pós-renderização, usada para combinar várias passagens de renderização (passagem) para criar efeitos visuais específicos)

2. RenderPass (é o canal usado para renderizar a cena. Ele pega a cena e a câmera como entrada, usa o renderizador padrão Three.js (renderizador) para renderizar a cena e envia o resultado para a próxima etapa de renderização)

3. UnrealBloomPass (É um efeito de pós-processamento usado em three.js para obter o efeito bloom. Através do desfoque gaussiano e da tecnologia de mesclagem de tela, a área com maior brilho é difusa para obter um efeito bloom realista.)

4. ShaderPass (é um canal de um shader personalizado. Ele permite especificar um código de shader personalizado e aplicá-lo ao resultado da renderização da cena. Dessa forma, você pode criar uma variedade de efeitos gráficos, como desfoque gaussiano, pós- efeitos de processamento, etc.)

Com base no artigo anterior sobre Three.js carregando arquivos de modelo externos glb, fbx, gltf, obj, um novo createEffectComposer (método de sintetizador de efeito) e sceneAnimation (método de renderização de efeito) e getFlowMeaterList (para obter materiais de efeito de brilho ) foram adicionados. método)

Primeiro introduza a API relevante

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'

Criar método Effect Composer (createEffectComposer): precisa criar dois compositores effectComposer para cena de renderização normal, glowComposer para renderizar efeito de brilho

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)
	}

Obtenha o material que precisa de renderização de brilho:

   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)
   }

Método de renderização de cena (sceneAnimation): manuseie materiais que não requerem brilho. Nota: O efeito de brilho afetará a exibição normal da imagem de fundo da cena e precisa ser processado separadamente ( aqui, julgue se é um material de cena por instância de TRÊS.Cena e, em seguida, processe-o separadamente )

   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()
	}

O código completo pode se referir a: https://gitee.com/ZHANG_6666/Three.js3D/blob/master/src/views/renderModel.js

Comparação de efeito de interface
insira a descrição da imagem aqui
insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/weixin_43835425/article/details/132370548
Recomendado
Clasificación