OutlinePass: контур вокруг объектов

OutlinePass — это часть пакета postprocessing в Three.js, предназначенная для выделения объектов контурами. Она создаёт эффект обводки вокруг выбранных объектов сцены, что часто используется для визуального выделения интерактивных элементов или создания стилизованной графики.

Для работы требуется EffectComposer, который управляет цепочкой постобработки. Базовая настройка выглядит следующим образом:

import * as THREE from 'three';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

// Сцена, камера и рендерер
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Управление камерой
const controls = new OrbitControls(camera, renderer.domElement);

// Эффекты
const composer = new EffectComposer(renderer);
const renderPass = new RenderPass(scene, camera);
composer.addPass(renderPass);

const outlinePass = new OutlinePass(
    new THREE.Vector2(window.innerWidth, window.innerHeight),
    scene,
    camera
);
composer.addPass(outlinePass);

Ключевой момент — передача сцены и камеры в OutlinePass, а также установка размеров через Vector2.


Настройка объектов для обводки

Обводка применяется только к выбранным объектам, которые передаются через массив selectedObjects:

const cube = new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1),
    new THREE.MeshStandardMaterial({ color: 0x00ff00 })
);
scene.add(cube);

outlinePass.selectedObjects = [cube];

Можно добавлять и удалять объекты динамически, что позволяет реализовать интерактивное выделение.


Основные параметры OutlinePass

OutlinePass имеет несколько важных свойств для контроля визуального эффекта:

  • edgeStrength — интенсивность обводки. Значение от 0 (невидимо) до ~10.
  • edgeGlow — величина свечения контура.
  • edgeThickness — толщина линии.
  • visibleEdgeColor — цвет видимой стороны контура.
  • hiddenEdgeColor — цвет невидимой части объекта (когда объект частично перекрыт).
  • pulsePeriod — задаёт анимацию пульсации обводки.
  • usePatternTexture — включает текстурное узорное наложение на контур.

Пример настройки:

outlinePass.edgeStrength = 5;
outlinePass.edgeGlow = 0.5;
outlinePass.edgeThickness = 2;
outlinePass.visibleEdgeColor.set('#ffffff');
outlinePass.hiddenEdgeColor.set('#ff0000');
outlinePass.pulsePeriod = 2;
outlinePass.usePatternTexture = true;

Эти параметры позволяют гибко управлять стилем обводки и создавать как реалистичные, так и художественные эффекты.


Анимация и динамическое обновление

OutlinePass работает вместе с анимационным циклом EffectComposer. В рендере нужно использовать composer.render() вместо обычного renderer.render():

function animate() {
    requestAnimationFrame(animate);
    controls.update();
    composer.render();
}
animate();

Динамическое выделение объектов реализуется изменением массива selectedObjects в любой момент:

window.addEventListener('click', () => {
    outlinePass.selectedObjects = [cube]; // можно менять на другие объекты
});

Также возможна анимация параметров контура, например, плавное изменение edgeStrength для эффекта пульсации:

const clock = new THREE.Clock();
function animate() {
    requestAnimationFrame(animate);
    const t = clock.getElapsedTime();
    outlinePass.edgeStrength = 5 + Math.sin(t * 2) * 2;
    composer.render();
}
animate();

Поддержка нескольких объектов и слоёв

OutlinePass корректно обрабатывает несколько объектов одновременно. Можно выделять группы объектов и применять разные стили через слои или дополнительные OutlinePass. Например:

const sphere = new THREE.Mesh(
    new THREE.SphereGeometry(0.5, 32, 32),
    new THREE.MeshStandardMaterial({ color: 0xff0000 })
);
scene.add(sphere);

outlinePass.selectedObjects.push(sphere);

При необходимости можно использовать маскировку слоёв THREE.Layers, чтобы контур применялся только к определённым объектам сцены.


Использование с освещением и материалами

OutlinePass учитывает материалы и освещение объектов. Важно, чтобы объекты имели материал с цветом или текстурой, иначе контур может выглядеть нечётким. Для прозрачных объектов можно использовать MeshBasicMaterial с прозрачностью:

const transparentCube = new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1),
    new THREE.MeshBasicMaterial({ color: 0x00ff00, transparent: true, opacity: 0.5 })
);
scene.add(transparentCube);
outlinePass.selectedObjects.push(transparentCube);

Оптимизация производительности

OutlinePass может быть затратным для большого числа объектов. Рекомендации:

  • Использовать массив selectedObjects только для реально выделяемых объектов.
  • Настроить edgeThickness и edgeGlow умеренно.
  • Избегать частого изменения размеров канваса без необходимости.
  • Использовать composer.setSize() при изменении размеров окна.

Эти меры помогают сохранить высокую частоту кадров даже при сложных сценах.


Дополнительные возможности

  • Pulse и анимация цвета — позволяет визуально выделять интерактивные объекты.
  • Pattern Texture — создаёт стилизованный контур с текстурой, например для мультяшного или «неонового» эффекта.
  • Скрытые контуры — цвет скрытой части объекта помогает видеть форму даже при частичном перекрытии.

Совместно с EffectComposer и RenderPass, OutlinePass обеспечивает мощный инструмент постобработки для визуального выделения объектов в сцене.