1.THREEJS高级-全局辉光和部分辉光

辉光

辉光就是让一个模型进行发光,可以实现灯泡,车灯的效果。

全局辉光

threejs官网案例:threejs.org/examples/?q...

  1. 引入实现辉光所需要的扩展库
js 复制代码
//引入后处理扩展库 
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; 
//引入渲染器通道RenderPass 
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; 
// 引入UnrealBloomPass辉光通道 
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
  1. EffectComposer

想要在用threejs输出一张图像,除了必不可少的场景、相机外还需要WebGLRenderer把图像渲染到页面上,如果你需要对一个webgl渲染器的渲染结果进行后期处理,就把它作为EffectComposer的参数。

kotlin 复制代码
this.composer = new EffectComposer(this.renderer)
  1. RenderPass

通过EffectComposer指定需要后期处理的渲染器后。再通过渲染器通道RenderPass指定后处理对应的相机camera和场景scene

// 复制代码
const renderPass = new RenderPass(this.scene, this.camera);
  1. 发光通道UnrealBloomPass

参数1是一个二维向量Vector2,二维向量尺x、y分量要和Canvas画布的宽、高度尺寸保持一致。参数2是发光强度,参数3是发光阈值,参数4是发光半径。

javascript 复制代码
this.bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight),1,0.5,0.5)
  1. EffectComposer添加渲染器通道RenderPass和发光通道。
kotlin 复制代码
// 设置renderPass通道 
this.composer.addPass(renderPass); this.composer.addPass(this.bloomPass)
  1. 循环执行
kotlin 复制代码
this.composer.render()

效果图:前后对比

部分辉光

threejs官网案例threejs.org/examples/q=...

  • 有时候我们只希望部分物体发光,但是辉光会对场景中所有模型产生效果,那么就会导致其他不希望有辉光效果的物体出现了辉光。

  • 想要实现部分模型有辉光的效果就不得不提到图层。

    • 图层简介:图层对象为Object3D对象分配了1-32个图层,编号为0-31。 默认所有 Object3D 对象都存储在第 0 个图层上。图层对象可以用于控制对象的显示,和相机处于同一个图层的物体才可以被显示出来。每个继承自 Object3D 的对象都有一个 Object3D.layers 对象。Mesh、Camera、Group等都继承自基类 Object3D,所以它们都有一个 layers 属性。
  • 具体实现方式如下;

    • 思路:准备两个后处理器 EffectComposer,一个用于产生辉光效果(bloomComposer ),另一个用来正常渲染整个场景(finalComposer)。在创建一个集合对象,用来存储要辉光的模型,主要是用于区分辉光和不辉光的模型
  • 准备基础数据和方法后面要用

javascript 复制代码
BLOOM_SCENE: 1,
bloomLayer: new THREE.Layers(),
materials: {},
darkMaterial: new THREE.MeshBasicMaterial({ color: 'black' })
init() {
  this.bloomLayer.set(this.BLOOM_SCENE);
},
//要启用图层1,才会展示辉光效果
initCamera() {
       ......
  this.camera.layers.enable(1)
},
 //非辉光图层的模型颜色全部变为黑色
darkenNonBloomed(obj) {
  if (obj.isMesh && this.bloomLayer.test(obj.layers) === false) {
    this.materials[obj.uuid] = obj.material;
    obj.material = this.darkMaterial;
  }
},
//恢复非辉光图层的模型颜色
restoreMaterial(obj) {
  if (this.materials[obj.uuid]) {
    obj.material = this.materials[obj.uuid];
    delete this.materials[obj.uuid];
  }
},

initModelGlow(url) {
  const loader = new GLTFLoader()
  loader.load(url, (gltf) => {
    const model = gltf.scene;
    gltf.scene.traverse((obj) => {
      if (obj.isMesh) {
          //注意:设置导入的模型图层与辉光涂层一样才会显示辉光
        obj.layers.set(this.BLOOM_SCENE)
      }
    })
    model.translateX(5)
    this.scene.add(model);
  });
},
  • 创建辉光图层,将辉光物体添加在该图层上,用于区分辉光物体和非辉光物体
kotlin 复制代码
this.bloomLayer.set(this.BLOOM_LAYER);
  • 利用 UnrealBloomPass实现辉光
kotlin 复制代码
let renderScene = new RenderPass(this.scene, this.camera)

this.bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight))
this.bloomPass.strength = this.params.bloomStrength
this.bloomPass.threshold = this.params.bloomThreshold
this.bloomPass.radius = this.params.bloomRadius
  • 准备第一个后处理器 EffectComposer,产生辉光效果
kotlin 复制代码
this.bloomComposer = new EffectComposer(this.renderer)
this.bloomComposer.renderToScreen = false; //不渲染到屏幕
this.bloomComposer.addPass(renderScene)
this.bloomComposer.addPass(this.bloomPass)
  • 这块不是很懂,貌似是利用ShaderPass着色器合成最终通道(不包含辉光特效)
php 复制代码
const mixPass = new ShaderPass(
new THREE.ShaderMaterial({
  uniforms: {
    baseTexture: { value: null },
    bloomTexture: { value: this.bloomComposer.renderTarget2.texture }
  },
  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'
);
mixPass.needsSwap = true;
  • 利用 finalComposer 渲染,finalComposer 将加入两个通道,一个是 bloomComposer 的渲染结果,另一个则是正常的渲染结果。
kotlin 复制代码
this.finalComposer = new EffectComposer(this.renderer);
this.finalComposer.addPass(renderScene);
this.finalComposer.addPass(mixPass);
  • 循环渲染

    先将不辉光的模型材质设置为黑色,模型设置为黑色后,辉光也没有效果。然后执行辉光合成器的render进行渲染,此时场景渲染辉光,而不需要辉光的模型因为设置了黑色,所以也看不出来。到此,场景中需要辉光的模型就实现了辉光,而不需要辉光的模型目前是看不见的,所以接下来,我们要将材质设置为黑色的模型还原成原本的材质颜色,再执行最终合成器的render进行渲染,因为finalComposer合成器中不包含辉光特效,所以第二次redner后,只渲染了正常不辉光的模型,而第一次渲染辉光的模型也被混合在一起了,所以场景最终就实现了一部分模型辉光,一部分不辉光。

kotlin 复制代码
render() {
  this.scene.traverse(this.darkenNonBloomed)
  // 渲染辉光合成器\
  this.bloomComposer.render()
  // 还原不会光的材质
  this.scene.traverse(this.restoreMaterial)
  // 渲染最终合成器
  this.finalComposer.render()
  // this.renderer.render(this.scene, this.camera)
},

效果图

以下案例源码在此处: gitee.com/ldglys/thre... 如果对您有所帮助请给个star。如果有不懂的可留言,看到会回复。

相关推荐
程序员_三木1 小时前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
MossGrower2 天前
36. Three.js案例-创建带光照和阴影的球体与平面
3d图形·webgl·three.js·光照与阴影
MossGrower2 天前
34. Three.js案例-创建球体与模糊阴影
webgl·three.js·3d渲染·阴影效果
广东数字化转型2 天前
Three.js相机Camera控件知识梳理
3d·three.js
关山月3 天前
9个学习着色器的GLSL示例
前端·three.js
程序员_三木3 天前
Three.js资源-贴图材质网站推荐
javascript·webgl·three.js·材质·贴图
MossGrower4 天前
37. Three.js案例-绘制部分球体
3d图形·webgl·three.js·球体几何体
关山月4 天前
如何使用Three.js创建3D音频可视化工具
前端·three.js
MossGrower5 天前
35. Three.js案例-创建带阴影的球体与平面
webgl·three.js·阴影·球体
MossGrower6 天前
28. Three.js案例-创建圆角矩形并进行拉伸
3d图形·webgl·three.js·圆角矩形