3

我已经调整了这个后处理示例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 编程很陌生,想学习,并且想知道是否可以在着色器/材质设置阶段做到这一点。

4

0 回答 0