我一直坚持这个问题,并且已经开始研究并研究它几个小时了。
我正在尝试使用EffectComposer渲染我的场景,以便我的背景对象没有SSAO(在我的真实项目中,它是一个程序城市)和我的前景对象(在我的真实项目中是两个建筑物我想要呼唤,并且有不同的材料)请有SSAO。
正如您在下面的小提琴中看到的那样,蓝色立方体(它是bg场景的一部分)被红色立方体的SSAO渲染(在FG场景中)覆盖。显然,这种效果是不可取的。
如何使其正常工作?
谢谢!
- 亚当
http://jsfiddle.net/Lbddvnsp/1/
var renderTargetParameters, renderTarget, renderBackground, renderModel, clearMask, renderMask, depthMaterial, depthTarget, composer;
var container, camera, bgScene, fgScene, renderer;
init();
initSSAO();
addObjects();
animate();
function initSSAO() {
// Depth
var depthShader = THREE.ShaderLib[ "depthRGBA" ];
var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
depthMaterial.blending = THREE.NoBlending;
// Post-processing
// create a custom render target with a stencil buffer
// the stencil buffer allows for masking to take place
renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: true };
renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, renderTargetParameters );
composer = new THREE.EffectComposer( renderer, renderTarget );
// add both foreground and background rendering to the composer
renderBackground = new THREE.RenderPass( bgScene, camera );
renderModel = new THREE.RenderPass( fgScene, camera );
// set clear to false while rendering the model to preserve buffer data
// the information in the stencil buffer is used for the masking pass
renderModel.clear = false;
clearMask = new THREE.ClearMaskPass();
renderMask = new THREE.MaskPass( fgScene, camera );
depthTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat } );
var ssaoPass = new THREE.ShaderPass( THREE.SSAOShader );
ssaoPass.uniforms[ 'tDepth' ].value = depthTarget;
ssaoPass.uniforms[ 'size' ].value.set( window.innerWidth, window.innerHeight );
ssaoPass.uniforms[ 'cameraNear' ].value = camera.near;
ssaoPass.uniforms[ 'cameraFar' ].value = camera.far;
ssaoPass.uniforms[ 'aoClamp' ].value = 0.4;
//ssaoPass.renderToScreen = true;
// fast aproximate anti-alising
var fxaaPass = new THREE.ShaderPass( THREE.FXAAShader );
fxaaPass.uniforms[ 'resolution' ].value.set( 1 / window.innerWidth, 1 / window.innerHeight );
fxaaPass.renderToScreen = true;
composer.addPass( renderBackground );
composer.addPass( renderModel );
composer.addPass( renderMask );
composer.addPass( ssaoPass );
composer.addPass( clearMask );
composer.addPass( fxaaPass );
}
var cube;
function addObjects() {
// Floor (background scene)
var floorGeom = new THREE.PlaneGeometry(1000, 1000, 4, 4);
var floorMat = new THREE.MeshPhongMaterial({color: 0xff0000});
var floor = new THREE.Mesh(floorGeom, floorMat);
floor.position.y = -120;
floor.rotation.x = - 90 * Math.PI / 180;
bgScene.add(floor);
var cubeGeom = new THREE.CubeGeometry(100, 100, 100);
var cubeMat = new THREE.MeshPhongMaterial({color: 0x0000ff});
var cube2 = new THREE.Mesh(cubeGeom, cubeMat);
cube2.position.x = 300;
bgScene.add(cube2)
// SSAO Objects (foreground scene)
var cubeGeom = new THREE.CubeGeometry(200, 200, 200);
var cubeMat = new THREE.MeshLambertMaterial({color: 0x00ff00});
cube = new THREE.Mesh(cubeGeom, cubeMat);
cube.rotation.x = - 90 * Math.PI / 180;
fgScene.add(cube);
}
function init() {
// Container
container = document.createElement( 'div' );
document.body.appendChild( container );
// Scene
bgScene = new THREE.Scene();
fgScene = new THREE.Scene();
// Camera
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 40000 );
camera.position.x = 2000;
camera.position.y = 1000;
camera.position.z = -1000;
fgScene.add(camera);
camera.lookAt( fgScene.position );
// Lights
// Screwed around with settings of all lights to get a similar feel to the deferred example
var ambientLight = new THREE.AmbientLight( 0x404040 );
ambientLight.color.setHSL( 0.1, 0.1, 0.4 );
fgScene.add( ambientLight );
bgScene.add(ambientLight.clone());
var directionalLight = new THREE.DirectionalLight( 0xffffff );
directionalLight.color.setHSL( 0.1, 0.1, 0.5 );
directionalLight.position.x = 1000;
directionalLight.position.y = 1000;
directionalLight.position.z = 750;
directionalLight.position.normalize();
fgScene.add( directionalLight );
bgScene.add(directionalLight.clone());
var directionalLight2 = new THREE.DirectionalLight( 0x808080 );
directionalLight2.color.setHSL( 0.1, 0.1, 0.45 );
directionalLight2.position.x = - 1000;
directionalLight2.position.y = 1000;
directionalLight2.position.z = - 750;
directionalLight2.position.normalize();
fgScene.add( directionalLight2 );
bgScene.add(directionalLight2.clone());
var hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 0.65 );
hemiLight.color.setHSL( 0.6, 0.35, 0.7 );
hemiLight.groundColor.setHSL( 0.095, 0.5, 0.6 );
hemiLight.position.set( 0, 600, 0 );
fgScene.add( hemiLight );
bgScene.add(hemiLight.clone());
// Renderer
renderer = new THREE.WebGLRenderer({
antialias: false
});
renderer.autoClear = false;
renderer.setSize( window.innerWidth, window.innerHeight );
// Gamma settings make things look 'nicer' for some reason
renderer.gammaInput = true;
renderer.gammaOutput = true;
//renderer.physicallyBasedShading = true;
container.appendChild(renderer.domElement);
}
function render() {
renderer.clear();
//renderer.render( bgScene, camera );
//renderer.clear( false, true, false );
//camera.position.x += 1;
camera.lookAt( cube.position );
fgScene.overrideMaterial = depthMaterial;
// set force clear to true here so the depth buffer is not preserved
renderer.render( fgScene, camera, depthTarget, true );
fgScene.overrideMaterial = null;
composer.render();
}
function animate() {
window.requestAnimationFrame( animate );
render();
}
更新
我尝试使用黑色覆盖材料添加bgScene到深度目标渲染,只是为了看它是否会遮挡SSAO。 http://jsfiddle.net/5d7Lk7eu/1/ - 尽管在这个小提琴中很难看到(但我可以在我真实的项目场景中看到它)......实际上在bgScene对象中渲染的是fgScene的一个轮廓,它不再渲染SSAO完全通过bgScene。所以,我觉得我离我更近了,但我仍然被困住了。
更新2:*
下图(你可以看到火星面具通过地球显示)可能是一个更清晰的问题视觉例子(尽管这个没有使用SSAO,但我相信这两个问题是相关的):< / p>