先上圖對比方案1-2-3不同點,本文是方案1
方案1(旋轉場景情況下發光體不應該遮住另一個,但是遮住了)

方案2(層次正常,發光正常)

方案3(層次正常,發光正常,但是轉動場景時候部分輝光會被遮擋,但是還算OK)

three.js實現分模塊添加bloom方案--方案一,layers 分層渲染。
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>bloomPass</title>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#container {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="container"></div>
<button onclick="getC()" style="position: absolute; top: 50px;">getC</button>
<!-- <script src="js/three.min.js"></script> -->
<script src="js/tween.js"></script>
<!-- <script src="js/stats.min.js"></script> -->
<!-- <script src="js/OrbitControls.js"></script> -->
<!-- 后期處理js -->
<!-- -->
<!-- <script src="js/shaders/ConvolutionShader.js"></script> -->
<!-- <script> -->
<script type="module">
import * as THREE from '../build/three.module.js';
import Stats from './jsm/libs/stats.module.js';
import { GUI } from './jsm/libs/dat.gui.module.js';
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { EffectComposer } from './jsm/postprocessing/EffectComposer.js'; // EffectComposer(效果組合器)對象
import { RenderPass } from './jsm/postprocessing/RenderPass.js'; // RenderPass/該通道在指定的場景和相機的基礎上渲染出一個新場景
import { ShaderPass } from './jsm/postprocessing/ShaderPass.js'; // ShaderPass/使用該通道你可以傳入一個自定義的着色器,用來生成高級的、自定義的后期處理通道
import { CopyShader } from './jsm/shaders/CopyShader.js'; // 傳入了CopyShader着色器,用於拷貝渲染結果
import { BloomPass } from './jsm/postprocessing/BloomPass.js';
import { UnrealBloomPass } from './jsm/postprocessing/UnrealBloomPass.js'; // BloomPass/形成泛光的效果
// 需要用官方版本的tween.js
let container = document.getElementById('container');
let camera, scene, renderer;
let cubeGroup, labelGroup = [];
let stats, controls;
let renderOrder = 1
let bloomComposer = null
init();
update();
function init() {
// scene
scene = new THREE.Scene();
// camera
let frustumSize = 150;
let aspect = container.clientWidth / container.clientHeight;
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
50000
)
camera.position.set(306, 1126, 7976);
camera.lookAt(new THREE.Vector3(0, 0, 0));
var ambientLight = new THREE.AmbientLight('#ffffff', 0.7) // offline
scene.add(ambientLight)
// renderer
renderer = new THREE.WebGLRenderer();
renderer.autoClear = false
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
container.appendChild(renderer.domElement);
renderer.render(scene, camera);
addCubes()
addBloomPass()
stats = new Stats();
container.appendChild(stats.dom);
controls = new OrbitControls(camera, renderer.domElement);
window.addEventListener('resize', onWindowResize, false);
}
function update() {
requestAnimationFrame(update);
controls.update();
stats.update();
// 渲染器清除顏色、深度或模板緩存. 此方法將顏色緩存初始化為當前顏色
renderer.clear()
camera.layers.set(1)
if(bloomComposer) {bloomComposer.render()}
// 清除深度緩存
renderer.clearDepth()
camera.layers.set(0)
renderer.render(scene, camera)
}
function getC() {
console.log(camera)
}
function onWindowResize() {
let frustumSize = 200;
let aspect = container.clientWidth / container.clientHeight;
camera.left = frustumSize * aspect / -2;
camera.right = frustumSize * aspect / 2;
camera.top = frustumSize / 2;
camera.bottom = frustumSize / -2;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function addBloomPass() {
// RenderPass這個通道會渲染場景,但不會將渲染結果輸出到屏幕上
const renderScene = new RenderPass(scene, camera)
const effectCopy = new ShaderPass(CopyShader); //傳入了CopyShader着色器,用於拷貝渲染結果
effectCopy.renderToScreen = true;
// THREE.BloomPass(strength, kernelSize, sigma, Resolution)
// strength 定義泛光效果的強度,值越高,明亮的區域越明亮,而且滲入較暗區域的也就越多
// kernelSize 控制泛光的偏移量
// sigma 控制泛光的銳利程度,值越高,泛光越模糊
// Resolution 定義泛光的解析圖,如果該值太低,結果的方塊化就會越嚴重
const bloomPass = new BloomPass(2, 25, 4.0, 256); //BloomPass通道效果
//創建效果組合器對象,可以在該對象上添加后期處理通道,通過配置該對象,使它可以渲染我們的場景,並應用額外的后期處理步驟,在render循環中,使用EffectComposer渲染場景、應用通道,並輸出結果。
bloomComposer = new EffectComposer(renderer)
bloomComposer.setSize(window.innerWidth, window.innerHeight);
bloomComposer.addPass(renderScene);
bloomComposer.addPass(bloomPass);
bloomComposer.addPass(effectCopy);
bloomComposer.render()
}
function addCubes() {
// 創建兩個box, 將box進行layers進行分層是重要代碼,camera默認渲染0層
let texture = new THREE.TextureLoader().load("./backav9.jpg")
let texture1 = new THREE.TextureLoader().load("./py.png")
var geometry1 = new THREE.BoxGeometry(400, 400, 400);
var material1 = new THREE.MeshBasicMaterial({
map: texture
});
var cube1 = new THREE.Mesh(geometry1, material1);
// 重要代碼,將當前創建的box分配到0層
cube1.layers.set(1)
cube1.position.set(1200, 0, 0)
scene.add(cube1);
var geometry2 = new THREE.BoxGeometry(400, 400, 400);
var material2 = new THREE.MeshBasicMaterial({
map: texture1
});
var cube2 = new THREE.Mesh(geometry2, material2);
// 重要代碼,將當前創建的box分配到1層
cube2.layers.set(0)
cube2.position.set(600, 0, 0)
scene.add(cube2);
}
</script>
</body>
</html>