如何通过创建后处理BLOOM来改变我的场景背景?



我是THREE.js的新手,我想让对象在鼠标滚动时亮起来。

但是当我改变场景。布卢姆将背景色改为白色,我发现Bloom会影响背景颜色的外观。如何解决这个问题?

这是之前

输入图片描述

之后输入图片描述

这里是完整的代码

<script type="x-shader/x-vertex" id="vertexshader">
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
uniform sampler2D baseTexture;
uniform sampler2D bloomTexture;
varying vec2 vUv;
void main() {
gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );
}
</script>
<script type="importmap">
{
"imports": {
"three": "./build/three.module.js"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import Stats from './jsm/libs/stats.module.js';
import { GUI } from './jsm/libs/lil-gui.module.min.js';
import { EffectComposer } from './jsm/postprocessing/EffectComposer.js';
import { RenderPass } from './jsm/postprocessing/RenderPass.js';
import { UnrealBloomPass } from './jsm/postprocessing/UnrealBloomPass.js';
import { FBXLoader } from './Loader/FBXLoader/FBXLoader.js';
import { OBJLoader } from './Loader/OBJLoader.js';
import { MTLLoader } from './Loader/MTLLoader.js'
import { GLTFLoader } from "./Loader/GLTFLoader.js";
import { ShaderPass } from './jsm/postprocessing/ShaderPass.js';
const ENTIRE_SCENE = 0, BLOOM_SCENE = 1;
const bloomLayer = new THREE.Layers();
bloomLayer.set(BLOOM_SCENE);
let params = {
exposure: 1,
bloomThreshold: 0.41,
bloomStrength: 0.66,
bloomRadius: 0.05,
scene: 'Scene with Glow'
};
//set MeshBasicMaterial
const darkMaterial = new THREE.MeshBasicMaterial({ color: 'black' });
const materials = {};
/*--------renderer--------*/
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
//add scene
const scene = new THREE.Scene();
/*--------camera--------*/
const camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 0.1, 100000000);
camera.position.set(0, 10, 0);
camera.lookAt(0, 0, 0);


/*--------OrbitControls--------*/
let controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0, 0);
controls.enablePan = false;
controls.maxPolarAngle = Math.PI / 2;
controls.enableDamping = true;
//Render
const renderScene = new RenderPass(scene, camera);
const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85);
bloomPass.threshold = params.bloomThreshold;
bloomPass.strength = params.bloomStrength;
bloomPass.radius = params.bloomRadius;
const bloomComposer = new EffectComposer(renderer);
bloomComposer.renderToScreen = false;
bloomComposer.addPass(renderScene);
bloomComposer.addPass(bloomPass);
const finalPass = new ShaderPass(
new THREE.ShaderMaterial({
uniforms: {
baseTexture: { value: null },
bloomTexture: { value: bloomComposer.renderTarget2.texture }
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
defines: {}
}), 'baseTexture'
);
finalPass.needsSwap = true;
const finalComposer = new EffectComposer(renderer);
finalComposer.addPass(renderScene);
finalComposer.addPass(finalPass);
/*--------Stats--------*/
const stats = Stats();
stats.showPanel(0);
document.body.appendChild(stats.dom);
/*--------AmbientLight-1--------*/
scene.add(new THREE.AmbientLight(0xffffff, 1));
//light1
const light1 = new THREE.PointLight(0xddffdd, 1);
light1.position.z = 0;
light1.position.y = 300;
light1.position.x = 200;
scene.add(light1);
//GUI
const gui = new GUI();
gui.add(params, 'scene', ['Scene with Glow', 'Scene only']).onChange(function (value) {
switch (value) {
case 'Scene with Glow':
bloomComposer.renderToScreen = false;
break;
case 'Scene only':
// nothing to do
break;
}
});
const folder = gui.addFolder('Bloom Parameters');
folder.add(params, 'exposure', 0.1, 2).onChange(function (value) {
renderer.toneMappingExposure = Math.pow(value, 4.0);
});
folder.add(params, 'bloomThreshold', 0.0, 1.0).onChange(function (value) {
bloomPass.threshold = Number(value);
});
folder.add(params, 'bloomStrength', 0.0, 10.0).onChange(function (value) {
bloomPass.strength = Number(value);
});
folder.add(params, 'bloomRadius', 0.0, 1.0).step(0.01).onChange(function (value) {
bloomPass.radius = Number(value);
});
/*--------scene.background--------*/
scene.background = new THREE.Color(0xffffff);
/*--------cube--------*/
const geometry = new THREE.BoxGeometry(4, 4, 4);
const material = new THREE.MeshBasicMaterial({ color: 0x000050 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
/*--------raycaster--------*/
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
window.addEventListener('mousemove', onMouseMove);
console.log(scene);
function onMouseMove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(scene.children);
scene.children[2].layers.set(ENTIRE_SCENE);
if (intersects[0]) {
const intersects_object_name = intersects[0].object.name;
intersects[0].object.layers.enableAll(BLOOM_SCENE);
}
}
//window.onresize
window.onresize = function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
};
function disposeMaterial(obj) {
if (obj.material) {
obj.material.dispose();
}
}
//render
function render() {
switch (params.scene) {
case 'Scene only':
renderer.render(scene, camera);
break;
case 'Scene with Glow':
default:
// render scene with bloom
renderBloom(true);
// render the entire scene, then render bloom scene on top
finalComposer.render();
break;
}
}
function renderBloom(mask) {
if (mask === true) {
scene.traverse(darkenNonBloomed);
bloomComposer.render();
scene.traverse(restoreMaterial);
} else {
camera.layers.set(BLOOM_SCENE);
bloomComposer.render();
camera.layers.set(ENTIRE_SCENE);
}
}
function darkenNonBloomed(obj) {
if (obj.isMesh && bloomLayer.test(obj.layers) === false) {
materials[obj.uuid] = obj.material;
obj.material = darkMaterial;
}
}
function restoreMaterial(obj) {
if (materials[obj.uuid]) {
obj.material = materials[obj.uuid];
delete materials[obj.uuid];
}
}
function animate() {
stats.update();
render();
requestAnimationFrame(animate);
};
animate();
</script>
如果需要,这里有一些例子https://smile881225.github.io/AskQuestions/

尝试更改这部分:

if (mask === true) {
scene.traverse(darkenNonBloomed);
bloomComposer.render();
scene.traverse(restoreMaterial);
} else {

:

if (mask === true) {
renderer.setClearColor(0x000000); // all must be black, including background
scene.traverse(darkenNonBloomed);
bloomComposer.render();
renderer.setClearColor(0x006432); // set the color you want
scene.traverse(restoreMaterial);
} else {

最新更新