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。如果有不懂的可留言,看到会回复。

相关推荐
答案—answer2 天前
开源项目:Three.js3D模型可视化编辑系统
javascript·3d·开源·开源项目·three.js·three.js编辑器
贝格前端工场2 天前
困在像素里:我的可视化大屏项目与前端价值觉醒
前端·three.js
全栈王校长3 天前
Three.js 材质进阶
webgl·three.js
全栈王校长3 天前
Three.js Geometry进阶
webgl·three.js
烛阴4 天前
3D字体TextGeometry
前端·webgl·three.js
全栈王校长4 天前
Three.js 开发快速入门
three.js
全栈王校长4 天前
Three.js 环境搭建与开发初识
three.js
DaMu4 天前
Dreamcore3D ARPG IDE “手搓”游戏引擎,轻量级实时3D创作工具,丝滑操作,即使小白也能轻松愉快的创作出属于你自己的游戏世界!
前端·架构·three.js
烛阴6 天前
从“无”到“有”:手动实现一个 3D 渲染循环全过程
前端·webgl·three.js
烛阴7 天前
拒绝配置地狱!5 分钟搭建 Three.js + Parcel 完美开发环境
前端·webgl·three.js