(Три. js) цветение над вопросом не цветения - PullRequest
1 голос
/ 09 апреля 2020

Может кто-нибудь немного изменить приведенный пример для решения основной проблемы? Это поможет всем понять, как правильно использовать scene. traverse и obj.material. dispose в очень простом примере (потому что оригинальный пример немного сложен код для свободного погружения). Как должно выглядеть цветение, а не цветение: bloomYes.png Но в примере это неверно: bloomNot.png

Пример просмотра и изменения

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth/ window.innerHeight, 1, 1000);
camera.position.set(20, 0, -20);
camera.layers.enable(1);
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.autoClear = false;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor( 0x000000 );
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var light = new THREE.DirectionalLight(0xffffff, 0.75);
light.position.setScalar(100);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.25));

// not bloomy
var obj = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 4), new THREE.MeshLambertMaterial({color: 0xf0f0f0, wireframe: false}));
obj.layers.set(0);
obj.position.z = 0;
scene.add(obj);

var obj = new THREE.Mesh(new THREE.BoxGeometry(12, 12, 1), new THREE.MeshLambertMaterial({color: 0x0000ff, wireframe: false}));
obj.position.z = 2.5;
obj.layers.set(0);
scene.add(obj);

var obj = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 4), new THREE.MeshLambertMaterial({color: 0xf0f0f0, wireframe: false}));
obj.layers.set(0);
obj.position.z = 5;
scene.add(obj);

// bloomystuff
var objBloomRed = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
objBloomRed.position.z = -2.25;
objBloomRed.layers.set(1);
scene.add(objBloomRed);

var objBloomGreen = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0x00ff00, wireframe: false}));
objBloomGreen.position.z = 7.5;
objBloomGreen.layers.set(1);
scene.add(objBloomGreen);


// "fake" objects
var objRed = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
objRed.position.z = -2.5;
objRed.layers.set(0);
scene.add(objRed);

var objGreen = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0x00ff00, wireframe: false}));
objGreen.position.z = 7.5;
objGreen.layers.set(0);
scene.add(objGreen);

/** COMPOSER */
renderScene = new THREE.RenderPass( scene, camera )
	
effectFXAA = new THREE.ShaderPass( THREE.FXAAShader )
effectFXAA.uniforms.resolution.value.set( 1 / window.innerWidth, 1 / window.innerHeight )
	
bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 )
bloomPass.threshold = 0.21
bloomPass.strength = 1.2
bloomPass.radius = 0.55
bloomPass.renderToScreen = true
	
composer = new THREE.EffectComposer( renderer )
composer.setSize( window.innerWidth, window.innerHeight )
	
composer.addPass( renderScene )
composer.addPass( effectFXAA )
composer.addPass( bloomPass )
	
var delta = 0;
render();

function render(){
  requestAnimationFrame(render);
  delta += 0.05;
  objBloomRed.material.color.g = Math.sin(delta);
  objBloomRed.material.color.b = Math.cos(delta);
  objRed.material.color.g = Math.sin(delta);
  objRed.material.color.b = Math.cos(delta);

  renderer.clear();
  
  camera.layers.set(1);
  composer.render();
  
  renderer.clearDepth();
  camera.layers.set(0);
  renderer.render(scene, camera);

}
body {
    overflow: hidden;
    margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>

<script src='https://threejs.org/examples/js/postprocessing/EffectComposer.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/RenderPass.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/ShaderPass.js'></script>
<script src='https://threejs.org/examples/js/shaders/CopyShader.js'></script>
<script src="https://threejs.org/examples/js/shaders/FXAAShader.js"></script>
<script src="https://threejs.org/examples/js/shaders/LuminosityHighPassShader.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/UnrealBloomPass.js"></script>

<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

Спасибо.

1 Ответ

1 голос
/ 24 апреля 2020

Хорошо, я сделал это как можно скорее. Пусть все, кто хочет, знают, как это сделать! Просто посмотрите в код, как можно решить проблему «цветение над не цветением»:

var ENTIRE_SCENE = 0, BLOOM_SCENE = 1;
var bloomLayer = new THREE.Layers();
bloomLayer.set( BLOOM_SCENE );
var darkMaterial = new THREE.MeshBasicMaterial( { color: "yellow" } );
var materials = {};

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth/ window.innerHeight, 1, 1000);
camera.position.set(20, 0, -20);
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.setScalar(100);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.25));

// setup scene
scene.traverse(disposeMaterial);
scene.children.length = 0;

// not bloomy
var obj = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 4), new THREE.MeshBasicMaterial({color: 0x444444, wireframe: false}));
obj.position.z = 0;
obj.layers.enable(ENTIRE_SCENE)
scene.add(obj);

var obj = new THREE.Mesh(new THREE.BoxGeometry(12, 12, 1), new THREE.MeshBasicMaterial({color: 0x0000ff, wireframe: false}));
obj.position.z = 2.5;
obj.layers.enable(ENTIRE_SCENE)
scene.add(obj);

var obj = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 4), new THREE.MeshBasicMaterial({color: 0x444444, wireframe: false}));
obj.position.z = 5;
obj.layers.enable(ENTIRE_SCENE)
scene.add(obj);

// bloomystuff
var objBloomRed = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: false}));
objBloomRed.position.z = -2.5;
objBloomRed.layers.enable(BLOOM_SCENE)
scene.add(objBloomRed);

var objBloomGreen = new THREE.Mesh(new THREE.BoxGeometry(5, 5, 1), new THREE.MeshBasicMaterial({color: 0x00ff00, wireframe: false}));
objBloomGreen.position.z = 7.5;
objBloomGreen.layers.enable(BLOOM_SCENE)
scene.add(objBloomGreen);

window.onresize = function () {
    var width = window.innerWidth;
    var height = window.innerHeight;
    camera.aspect = width / height;
    camera.updateProjectionMatrix();
    renderer.setSize(width, height);
    bloomComposer.setSize(width, height);
    finalComposer.setSize(width, height);
    render();
};

/** COMPOSER */
renderScene = new THREE.RenderPass( scene, camera )

bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 )
bloomPass.threshold = 0.21
bloomPass.strength = 1.2
bloomPass.radius = 0.55

bloomComposer = new THREE.EffectComposer( renderer )
bloomComposer.setSize( window.innerWidth, window.innerHeight )

bloomComposer.renderToScreen = false;
bloomComposer.addPass( renderScene );
bloomComposer.addPass( bloomPass );

      var finalPass = new THREE.ShaderPass(
  new THREE.ShaderMaterial({
    uniforms: {
      baseTexture: {value: null},
      bloomTexture: {value: bloomComposer.renderTarget2.texture}
    },
    vertexShader: vertexshader.textContent,
    fragmentShader: fragmentshader.textContent,
    defines: {}
  }), "baseTexture"
);
finalPass.needsSwap = true;

var finalComposer = new THREE.EffectComposer(renderer);
finalComposer.addPass(renderScene);
finalComposer.addPass(finalPass);

function disposeMaterial(obj) {
    if (obj.material) {
        obj.material.dispose();
    }
}
function renderBloom(mask) {
    if (mask === true) {
        bloomComposer.render();
    } else {
        camera.layers.set(BLOOM_SCENE);
        bloomComposer.render();
        camera.layers.set(ENTIRE_SCENE);
    }
}

var delta = 0;
render();

function render(){
    requestAnimationFrame(render);
    delta += 0.05;
    objBloomRed.material.color.g = Math.sin(delta);
    objBloomRed.material.color.b = Math.cos(delta);

    renderBloom(true);
    finalComposer.render();
}            
body {
    overflow: hidden;
    margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src='https://threejs.org/examples/js/postprocessing/EffectComposer.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/RenderPass.js'></script>
<script src='https://threejs.org/examples/js/postprocessing/ShaderPass.js'></script>
<script src='https://threejs.org/examples/js/shaders/CopyShader.js'></script>
<script src="https://threejs.org/examples/js/shaders/FXAAShader.js"></script>
<script src="https://threejs.org/examples/js/shaders/LuminosityHighPassShader.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/UnrealBloomPass.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<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;
  vec4 getTexture( sampler2D texelToLinearTexture ) {
    return mapTexelToLinear( texture2D( texelToLinearTexture , vUv ) );
  }
  void main() {
    gl_FragColor = ( getTexture( baseTexture ) + vec4( 1.0 ) * getTexture( bloomTexture ) );
  }
</script>
...