我已经调整了此后处理示例http://mrdoob.github.com/three.js/examples/webgl_postprocessing_dof.html以应用景深/散景效果。如何指定焦点范围(或任何可以调用的范围)?
如果相机远端平面为10000,并且模型尺寸为10,则无法将焦点聚焦到模型的不可见部分 - 因为它试图从1-10000(相机附近到相机远)聚焦而不是1-10(相机和我的模型背面之间),实际感兴趣的区域。
在我意识到将相机远端平面设置得尽可能低(与场景大小大致相同)后,它确实正常工作,因此焦点可以调整到实际模型的位置。
现在我不能再进行相机远程飞机技巧,因为我添加了一个天空盒,因此相机需要让它的远处飞机与模型尺寸相关。这会弄乱景深;我可以非常靠近或非常远地聚焦,但整个模型要么完全模糊,要么根本不模糊,因为可调距离太大(一直到天空盒)。
如果我知道我想要关注的区域,我该如何在我的代码中指定它?
这是我的设置代码:
dof_material_depth = new THREE.MeshDepthMaterial();
dof_scene = new THREE.Scene();
dof_camera = new THREE.OrthographicCamera(SCREEN_WIDTH / - 2, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, SCREEN_HEIGHT / - 2, -10000, 10000 );
dof_camera.position.z = 100;
dof_scene.add( dof_camera );
var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
dof_rtTextureDepth = new THREE.WebGLRenderTarget(SCREEN_WIDTH, SCREEN_HEIGHT, pars );
dof_rtTextureColor = new THREE.WebGLRenderTarget(SCREEN_WIDTH, SCREEN_HEIGHT, pars );
dof_bokeh_shader = THREE.BokehShader;
dof_bokeh_uniforms = THREE.UniformsUtils.clone(dof_bokeh_shader.uniforms );
dof_bokeh_uniforms[ "tColor" ].value = dof_rtTextureColor;
dof_bokeh_uniforms[ "tDepth" ].value = dof_rtTextureDepth;
dof_bokeh_uniforms[ "focus" ].value = 1.1;
dof_bokeh_uniforms[ "aspect" ].value = SCREEN_WIDTH / SCREEN_HEIGHT;
dof_materialBokeh = new THREE.ShaderMaterial( {
uniforms: dof_bokeh_uniforms,
vertexShader: dof_bokeh_shader.vertexShader,
fragmentShader: dof_bokeh_shader.fragmentShader
});
dof_quad = new THREE.Mesh( new THREE.PlaneGeometry(SCREEN_WIDTH, SCREEN_HEIGHT), dof_materialBokeh );
dof_quad.position.z = -500;
dof_scene.add(dof_quad );
这里是渲染部分:
renderer.render(scene, camera, dof_rtTextureColor, true );
scene.overrideMaterial = dof_material_depth;
renderer.render(scene, camera, dof_rtTextureDepth, true );
dof_scene.overrideMaterial = null;
render(dof_scene, dof_camera );
var delta = 0.01;
composerScene.render( delta);
编辑:
我确实设法通过在渲染深度材质之前为相机设置低远平面,然后在渲染复合材料之前恢复正常来获得所需的结果:
renderer.render(scene, camera, dof_rtTextureColor, true );
var oldfar = camera.far; // this goes to skybox
camera.far = scenesize; // this goes to just behind the model
scene.overrideMaterial = dof_material_depth;
renderer.render(scene, camera, dof_rtTextureDepth, true );
camera.far = oldfar;
dof_scene.overrideMaterial = null;
render(dof_scene, dof_camera );
var delta = 0.01;
composerScene.render( delta);
这很完美。我会打开这个问题,因为我对WebGLL / 3D编程很陌生,想要学习,并想知道是否可以在着色器/材料设置阶段这样做。