Глубина резкости (Depth of Field, DoF) — это визуальный эффект, позволяющий симулировать оптическое поведение камеры, когда объекты вне зоны фокуса становятся размытыми. В Three.js этот эффект реализуется через постобработку, чаще всего с использованием BokehPass из модуля postprocessing. Этот подход позволяет создавать реалистичное размытие заднего и переднего плана, акцентируя внимание на ключевых объектах сцены.
Эффект DoF основан на двух основных компонентах:
Для работы с BokehPass необходимо:
depthTexture через WebGLRenderTarget.Пример настройки:
import * as THREE from 'three';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { BokehPass } from 'three/examples/jsm/postprocessing/BokehPass.js';
// Сцена и камера
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// Рендерер
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Composer и RenderPass
const composer = new EffectComposer(renderer);
const renderPass = new RenderPass(scene, camera);
composer.addPass(renderPass);
// Настройка BokehPass
const bokehPass = new BokehPass(scene, camera, {
focus: 2.0, // расстояние до фокуса
aperture: 0.025, // размер апертуры, влияет на степень размытия
maxblur: 0.01, // максимальная величина размытия
width: window.innerWidth,
height: window.innerHeight
});
composer.addPass(bokehPass);
Использование этих параметров позволяет точно настроить эффект в зависимости от композиции сцены.
Карта глубины Для корректного размытия
необходимо, чтобы камера и сцена поддерживали рендеринг глубины.
Включение renderer.capabilities.isWebGL2 позволяет
использовать depthTexture с THREE.FloatType,
что повышает точность размытия.
Производительность Эффект DoF затратен, особенно
при высокой maxblur и большом разрешении. Рекомендуется
уменьшать разрешение BokehPass через renderTarget с меньшим
размером и масштабировать результат.
Комбинация с другими эффектами BokehPass можно использовать вместе с другими postprocessing-пассами, например, BloomPass или FilmPass. Важно соблюдать порядок, так как размытие вне фокуса должно применяться после основного рендера сцены.
Глубина резкости особенно полезна в следующих случаях:
Адаптивное размытие Можно динамически изменять
aperture или focus в зависимости от позиции
камеры или объекта для интерактивных сцен.
Двойное размытие Для сложных сцен иногда используется комбинация BokehPass с другим фильтром размытия, чтобы имитировать рассеивание света на ближних объектах.
Использование LOD Для больших сцен объекты с дальнего плана можно заменять на упрощённые модели, что снижает нагрузку при вычислении размытия.
Параметры focus, aperture и
maxblur удобно связывать с dat.GUI или
любым другим инструментом управления, чтобы менять степень размытия в
реальном времени. Это полезно для настройки композиции и тестирования
визуальных решений.
import { GUI } from 'dat.gui';
const gui = new GUI();
gui.add(bokehPass.materialBokeh.uniforms.focus, 'value', 0.1, 10).name('Focus');
gui.add(bokehPass.materialBokeh.uniforms.aperture, 'value', 0, 0.1).name('Aperture');
gui.add(bokehPass.materialBokeh.uniforms.maxblur, 'value', 0, 0.05).name('Max Blur');
В цикле анимации сцены renderer.render заменяется на composer.render, чтобы эффект постобработки применялся ко всей сцене:
function animate() {
requestAnimationFrame(animate);
composer.render();
}
animate();
Такой подход гарантирует, что размытие вне фокуса корректно рассчитывается на каждом кадре, сохраняя плавность анимации и реалистичность эффекта.