Эта статья является частью серии статей о three.js. Первая статья - основы Three.js. Если вы еще не читали их, и вы новичок в three.js, возможно, вы захотите начать с них. Если вы еще не читали о камерах, вы можете начать с этой статьи.
Туман в 3D-движке - это, как правило, способ затухания до определенного цвета в зависимости от расстояния до камеры.
В three.js вы добавляете туман, создавая объект Fog
или FogExp2
и устанавливая его в свойстве сцены
fog
.
Fog
позволяет выбирать near
и far
настройки, которые находятся на расстоянии от камеры.
Все, что near
не подвержено влиянию тумана.
Все, что far
- это цвет тумана. Части между near
и far
переходят от их материального цвета к цвету тумана.
Есть также FogExp2
, который растет экспоненциально с расстоянием от камеры.
Чтобы использовать любой тип тумана, вы создаете его и назначаете его сцене, как в
const scene = new THREE.Scene(); { const color = 0xFFFFFF; // white const near = 10; const far = 100; scene.fog = new THREE.Fog(color, near, far); }
или для FogExp2
это будет
const scene = new THREE.Scene(); { const color = 0xFFFFFF; const density = 0.1; scene.fog = new THREE.FogExp2(color, density); }
FogExp2
ближе к реальности, но Fog
используется чаще, поскольку он позволяет вам выбрать место для нанесения тумана,
чтобы вы могли решить показать чистую сцену на определенном расстоянии, а затем исчезновение до некоторого цвета за этим расстоянием.
Важно отметить, что туман применяется к вещам, которые отображаются.
Это часть расчета каждого пикселя цвета объекта.
Это означает, что если вы хотите, чтобы ваша сцена стала блеклой, вам нужно установить туман и цвет фона на один и тот же цвет.
Цвет фона устанавливается с помощью свойства scene.background
. Чтобы выбрать цвет фона, вы прикрепляете к нему THREE.Color
. Например
scene.background = new THREE.Color('#F00'); // red
Вот один из наших предыдущих примеров с добавленным туманом. Единственное добавление - сразу после настройки сцены мы добавляем туман и устанавливаем цвет фона сцены
const scene = new THREE.Scene(); +{ + const near = 1; + const far = 2; + const color = 'lightblue'; + scene.fog = new THREE.Fog(color, near, far); + scene.background = new THREE.Color(color); +}
В приведенном ниже примере near
камеры равен 0,1, а far
- 5. Камера находится в точке z = 2
.
Кубики имеют размер 1 и имеют значение z = 0
.
Это означает, что при настройке тумана near = 1
и far = 2
кубики исчезнут прямо вокруг их центра.
Давайте добавим интерфейс, чтобы мы могли настроить туман. Мы снова будем использовать
lil-gui. lil-gui принимает объект и свойство и автоматически создает интерфейс для этого типа свойства.
Мы могли бы просто позволить ему манипулировать свойствами near
и far
тумана, но недопустимо иметь near
больше, чем far
, поэтому давайте создадим помощник,
чтобы lil-gui мог манипулировать свойством near
и far
,
но мы убедимся, что near
меньше или равно far
и far
больше или равно near
.
// We use this class to pass to lil-gui // so when it manipulates near or far // near is never > far and far is never < near class FogGUIHelper { constructor(fog) { this.fog = fog; } get near() { return this.fog.near; } set near(v) { this.fog.near = v; this.fog.far = Math.max(this.fog.far, v); } get far() { return this.fog.far; } set far(v) { this.fog.far = v; this.fog.near = Math.min(this.fog.near, v); } }
Затем мы можем добавить это так
{ const near = 1; const far = 2; const color = 'lightblue'; scene.fog = new THREE.Fog(color, near, far); scene.background = new THREE.Color(color); + + const fogGUIHelper = new FogGUIHelper(scene.fog); + gui.add(fogGUIHelper, 'near', near, far).listen(); + gui.add(fogGUIHelper, 'far', near, far).listen(); }
Параметры near
и far
задают минимальные и максимальные значения для регулировки тумана. Они устанавливаются при настройке камеры.
.Listen ()
в конце последних 2 строк указывает lil-gui прослушивать
изменения. Таким образом, когда мы меняем near
на far
или мы меняем far
на near
lil-gui обновит интерфейс другого свойства для нас.
Также было бы неплохо иметь возможность изменить цвет тумана, но, как было упомянуто выше, нам нужно синхронизировать цвет тумана и цвет фона. Итак, давайте добавим еще одно виртуальное свойство в наш помощник, который будет устанавливать оба цвета, когда lil-gui манипулирует им.
lil-gui может манипулировать цветами 4 способами, как шестнадцатеричная строка из 6 цифр CSS (например: # 112233
).
Как тон, насыщенность, яркость объекта (например: {h: 60, s: 1, v:}
).
Как массив RGB (например: [255, 128, 64]
). Или как массив RGBA (например: [127, 200, 75, 0.3]
).
Для нашей цели проще всего использовать шестнадцатеричную версию, поскольку таким образом lil-gui манипулирует только одним значением.
К счастью, THREE.Color
как метод getHexString
который мы используем, чтобы легко получить такую cтроку - нам просто нужно добавить «#»
вперед.
// We use this class to pass to lil-gui // so when it manipulates near or far // near is never > far and far is never < near +// Also when lil-gui manipulates color we'll +// update both the fog and background colors. class FogGUIHelper { * constructor(fog, backgroundColor) { this.fog = fog; + this.backgroundColor = backgroundColor; } get near() { return this.fog.near; } set near(v) { this.fog.near = v; this.fog.far = Math.max(this.fog.far, v); } get far() { return this.fog.far; } set far(v) { this.fog.far = v; this.fog.near = Math.min(this.fog.near, v); } + get color() { + return `#${this.fog.color.getHexString()}`; + } + set color(hexString) { + this.fog.color.set(hexString); + this.backgroundColor.set(hexString); + } }
Затем мы вызываем gui.addColor
, чтобы добавить интерфейс цвета для виртуального свойства нашего помощника.
{ const near = 1; const far = 2; const color = 'lightblue'; scene.fog = new THREE.Fog(color, near, far); scene.background = new THREE.Color(color); * const fogGUIHelper = new FogGUIHelper(scene.fog, scene.background); gui.add(fogGUIHelper, 'near', near, far).listen(); gui.add(fogGUIHelper, 'far', near, far).listen(); + gui.addColor(fogGUIHelper, 'color'); }
Вы можете видеть near
до 1,9, а far
до 2,0 дает очень резкий переход между незатуманенным и полностью затуманенным.
где near
= 1,1 и far
= 2,9 должны быть примерно самыми гладкими, учитывая, что наши кубики вращаются на 2 единицы от камеры.
И последнее: на материале существует логическое свойство fog
,
определяющее, влияет ли туман на объекты, созданные с этим материалом.
По умолчанию это true
для большинства материалов. В качестве примера того, почему вы можете захотеть отключить туман, представьте,
что вы делаете 3D-симулятор автомобиля с видом с места водителя или из кабины.
Вы, вероятно, хотите, чтобы тумана не было внутри, если смотреть изнутри автомобиля.
Лучшим примером может быть дом и густой туман вне дома. Допустим, туман установлен на расстоянии 2 метра ( near = 2) и полностью затуманен на 4 метра ( far = 4). Комнаты длиннее 2 метров, а дом, вероятно, длиннее 4 метров, поэтому вам необходимо установить материалы для внутренней части дома, чтобы не было тумана, в противном случае, если вы будете стоять внутри дома, глядя на стену в дальнем конце комнаты, она будет в тумане.
Обратите внимание, что на стены и потолок в дальнем конце комнаты распространяется туман. Отключив туман для материалов дома, мы можем решить эту проблему.