十三、Three场景物体增加发光特效

物体发光效果非常炫酷,本期来讲three场景内物体自带发光效果怎么来实现。本次使用的是threejs138版本,在vue3+vite+ant的项目中使用。

下面来看看实现的效果。绿色罐体有了明显的发光效果。

实现步骤

  • 增加composer.js

import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js'

import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';

import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';

import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';

import { GammaCorrectionShader } from 'three/examples/jsm/shaders/GammaCorrectionShader.js'

import scene from '../scene';

import camera from '../camera';

import renderer from '../renderer';

import * as THREE from 'three';







  const effectComposer = new EffectComposer(renderer.renderer)

  const renderPass = new RenderPass(scene, camera)

  effectComposer.addPass(renderPass)



  //创建UnrealBloomPass泛光通道

  const unrealBloomPass = new UnrealBloomPass(

      //参数一:泛光覆盖场景大小,二维向量类型

      new THREE.Vector2(window.innerWidth, window.innerHeight),

      //参数二:bloomStrength 泛光强度,值越大明亮的区域越亮,较暗区域变亮的范围越广

      2,

      //参数三:bloomRadius 泛光散发半径

      1,

      //参数四:bloomThreshold 泛光的光照强度阈值,如果照在物体上的光照强度大于该值就会产生泛光

      0.05

  )

  unrealBloomPass.renderToScreen = false



  const composer = new EffectComposer(renderer.renderer)

  composer.renderToScreen = false

  composer.addPass(new RenderPass(scene, camera))

  composer.addPass(unrealBloomPass)

  // var params = {

  //   exposure: 0,

  //   bloomStrength: 0.2,

  //   bloomThreshold: 0,

  //   bloomRadius: 0,

  //   };

  // unrealBloomPass.threshold = params.bloomThreshold;

  // unrealBloomPass.strength = params.bloomStrength;

  // unrealBloomPass.radius = params.bloomRadius;

  // 着色器

  let shaderPass = new ShaderPass(new THREE.ShaderMaterial({

    uniforms: {

      baseTexture: { value: null },

      bloomTexture: { value: composer.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 = false

  shaderPass.needsSwap = true

  //将创建的通道添加到EffectComposer(效果组合器)对象中

  effectComposer.addPass(shaderPass)



  const effectColorSpaceConversion = new ShaderPass(GammaCorrectionShader)

  effectComposer.addPass(effectColorSpaceConversion)





export default {composer,effectComposer};

  • 在animate里面重复调用,

  • 以下着重注意的点有三点。
  1. Composer.composer的引入位置必须是在renderer.render()之后。否则不能出来效果。
  2. Composer.effectComposer的位置必须是在最后,否则合成器不能展示成功。
  3.  glowMaterialList 里面的值是需要发光的物体名称,可以通过mitt或者vuex或者watch监听等方法来同步监听。
import camera from './camera';

import renderer from './renderer';

import controls from './controls';

import scene from './scene';

import { TWEEN } from 'three/examples/jsm/libs/tween.module.min';

import composer from './modify/composer';

import * as THREE from 'three';

var materials ={

  scene:null,

}

var glowMaterialList=['Cylinder022']



function animate() {

  controls.update();

  TWEEN.update();



  // 使用渲染器渲染相机看这个场景的内容渲染出来

  renderer.renderer.render(scene, camera);

 

  // 将不需要处理辉光的材质进行存储备份

  scene.traverse((v) => {

      // 备份一份场景背景然后清空

  if (v instanceof THREE.Scene) {

    materials.scene = v.background

    v.background = null

  }

  if (!glowMaterialList.includes(v.name) && v.isMesh) {

      // 备份当前材质内容

    materials[v.uuid] = v.material

    // 将不需要辉光的材质设置为黑色

    v.material = new THREE.MeshBasicMaterial({ color: 'black' })

  }

  })

  if (composer.composer) { composer.composer.render() }

  scene.traverse((v) => {

    if (materials[v.uuid]) {

      v.material = materials[v.uuid]

      delete materials[v.uuid]

    }

    if (v instanceof THREE.Scene) {

      v.background = materials.scene

      delete materials.scene

    }

  })

  if (composer.effectComposer) { composer.effectComposer.render() }



  requestAnimationFrame(animate);

}



export default animate;

  • resize的时候增加适应屏幕

import camera from "./camera";

import rendererModule from "./renderer";

import composer from './modify/composer';

// 更新摄像头

camera.aspect = window.innerWidth / window.innerHeight;

//   更新摄像机的投影矩阵

camera.updateProjectionMatrix();



// 监听屏幕大小改变的变化,设置渲染的尺寸

window.addEventListener("resize", () => {

  //   console.log("resize");

  // 更新摄像头

  camera.aspect = window.innerWidth / window.innerHeight;

  //   更新摄像机的投影矩阵

  camera.updateProjectionMatrix();



  //   更新渲染器

  rendererModule.renderer.setSize(window.innerWidth, window.innerHeight);

  //   设置渲染器的像素比例··

  rendererModule.renderer.setPixelRatio(window.devicePixelRatio);

  //   更新渲染器

  composer.composer.setSize(window.innerWidth, window.innerHeight);



});

以上就是实现物体发光的步骤,只需要调节composer.js里面unrealBloomPass 的参数就可以调节到你需要的发光的亮度,如果还有不懂的可以联系我哦。

  • 13
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要实现three.js中点击模型发光特效,可以使用以下步骤: 1. 创建一个着色器材质,并设置emissive属性为需要的颜色。 ``` var material = new THREE.MeshBasicMaterial({ color: 0xffffff, emissive: 0xff0000, emissiveIntensity: 0.5, side: THREE.DoubleSide //设置为双面可见 }); ``` 2. 将需要发光的模型的材质设置为该着色器材质。 ``` var mesh = new THREE.Mesh(geometry, material); ``` 3. 监听场景的鼠标点击事件,当点击到需要发光的模型上时,将该模型的材质的emissive属性设置为需要的颜色,并设置emissiveIntensity属性为大于0的值。 ``` function onDocumentMouseDown(event) { event.preventDefault(); var mouse = new THREE.Vector2(); mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = - (event.clientY / window.innerHeight) * 2 + 1; var raycaster = new THREE.Raycaster(); raycaster.setFromCamera(mouse, camera); var intersects = raycaster.intersectObjects(scene.children, true); if (intersects.length > 0) { var selectedObject = intersects[0].object; selectedObject.material.emissive.setHex(0xff0000); selectedObject.material.emissiveIntensity = 1; } } ``` 4. 在渲染循环中更新需要发光的模型的材质的emissiveIntensity属性,使其在点击后逐渐减小到0。 ``` function animate() { requestAnimationFrame(animate); //更新模型的emissiveIntensity mesh.material.emissiveIntensity = Math.max(0, mesh.material.emissiveIntensity - 0.05); renderer.render(scene, camera); } ``` 以上就是在three.js中实现点击模型发光特效的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

arguments_zd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值