ThreeJS选择性绽放禁用场景背景绽放



我使用ThreeJS来生成一个选择性绽放效果,以便在使用发射贴图作为过滤器的对象上显示发光部分。最近我尝试启用我的环境地图,并意识到开花影响scene.background的外观。

我是这样生成环境地图的:

function createEnvironment( hdr ) {
new RGBELoader().setDataType( THREE.UnsignedByteType ).load( hdr, function ( texture ) {        

const pmremGenerator = new THREE.PMREMGenerator( renderer )
pmremGenerator.compileEquirectangularShader()

const envMap = pmremGenerator.fromEquirectangular( texture ).texture
scene.background = texture;
scene.environment = envMap

texture.dispose()
pmremGenerator.dispose()
} );
}

此刻,环境地图像疯了一样发光。我看了一下,但我找不到一个解决方案,因为场景。背景没有使用材料,我找不到其他方法。

我现在卡住了。如何使选择性开花不影响scene.background?

这是我使用的选择性开花代码https://stackoverflow.com/a/67113323/9067589

body{
overflow: hidden;
margin: 0;
}
<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="module">
console.clear();
import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.127.0/build/three.module.js';
import {GLTFLoader} from 'https://cdn.jsdelivr.net/npm/three@0.127.0/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three@0.127.0/examples/jsm/controls/OrbitControls.js';
import { EffectComposer } from 'https://cdn.jsdelivr.net/npm/three@0.127.0/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'https://cdn.jsdelivr.net/npm/three@0.127.0/examples/jsm/postprocessing/RenderPass.js';
import { ShaderPass } from 'https://cdn.jsdelivr.net/npm/three@0.127.0/examples/jsm/postprocessing/ShaderPass.js';
import { UnrealBloomPass } from 'https://cdn.jsdelivr.net/npm/three@0.127.0/examples/jsm/postprocessing/UnrealBloomPass.js';
let model;
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.1, 100);
camera.position.set(7.7, 2.5, 7.2);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
//renderer.setClearColor(0x404040);
document.body.appendChild(renderer.domElement);
let controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", e => {console.log(camera.position)})
let light = new THREE.DirectionalLight(0xffffff, 1.5);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));
let uniforms = {
globalBloom: {value: 1}
}
let loader = new GLTFLoader();
loader.load( "https://cdn.jsdelivr.net/gh/MJegerlehnerBio/bloom-solution/turntable_121.glb", function ( gltf ) {
model = gltf.scene;
let emssvTex = new THREE.TextureLoader().load("https://cdn.jsdelivr.net/gh/MJegerlehnerBio/bloom-solution/RecordPlayer_Emission.jpeg", function( texture ) {
texture.flipY = false
texture.encoding = THREE.sRGBEncoding
})    
model.traverse( function ( child ) {
if ( child.isMesh ) {
child.material.emissiveMap = emssvTex;
child.material.onBeforeCompile = shader => {
shader.uniforms.globalBloom = uniforms.globalBloom;
shader.fragmentShader = `
uniform float globalBloom;
${shader.fragmentShader}
`.replace(
`#include <dithering_fragment>`,
`#include <dithering_fragment>
if (globalBloom > 0.5){
gl_FragColor = texture2D( emissiveMap, vUv );
}
`
);
console.log(shader.fragmentShader);
}
}
});
model.scale.setScalar(40);
scene.add(model);
});
// bloom
const renderScene = new RenderPass( scene, camera );
const bloomPass = new UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 2, 0, 0 );
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 );
window.onresize = function () {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( innerWidth, innerHeight );
bloomComposer.setSize( innerWidth, innerHeight );
finalComposer.setSize( innerWidth, innerHeight );
};
renderer.setAnimationLoop( _ => {

renderer.setClearColor(0x000000);
uniforms.globalBloom.value = 1;

bloomComposer.render();

renderer.setClearColor(0x404040);
uniforms.globalBloom.value = 0;

finalComposer.render();
//renderer.render(scene, camera);
})
</script>

在渲染循环中,使用scene.background代替renderer.setClearColor

定义场景背景

let scback = {
bloomOn: new THREE.Color(0x000000),
bloomOff: new THREE.Color(0x404040) // or define something else, a cubetexture, for example.
}

然后在渲染循环中:

renderer.setAnimationLoop( _ => {

scene.background = scback.bloomOn; // must be pure black
uniforms.globalBloom.value = 1;

bloomComposer.render();

scene.background = scback.bloomOff; // anything else you want to show
uniforms.globalBloom.value = 0;

finalComposer.render();
})

PS这只是从头开始,还没有测试过。:)

最新更新