В этом туториале мы рассмотрим работу программы Godot Antialiasing. В примере реализовано управление камерой: кнопки отвечают за перемещение, а мышь — за вращение
В сцене присутствуют вращающиеся, крутящиеся и масштабирующиеся блоки, статические объекты (например, корабль), а также анимированные частицы. Главная особенность — элементы управления, позволяющие изменять настройки видеоэффектов: Multisample, Screen-Space, V-Sync и другие. Можно даже снять ограничение FPS, что очень удобно. При сильном уменьшении Render Scale появляются дополнительные настройки, предназначенные, судя по всему, для слабых компьютеров
Мы визуально рассмотрели проект годот 3д туториал сглаживание
Давайте разберёмся в коде и структуре туториала Godot Anti-Aliasing
Здесь используется множество узлов Node3D и MeshInstance3D. Узлы Node3D отвечают за позиционирование объектов в пространстве, а MeshInstance3D — это уникальный узел, который отображает 3D-объекты: от стандартных сфер и кубов до загружаемых 3D-мешей. Также в сцене присутствуют элементы CpuParticles3D, GpuParticles3D и GpuParticlesCollisionBox3D
Сейчас рассмотрим код программы. В узел Testers вложены другие узлы Node3D. Для перемещения по ним используется переменная tester_index. Плавное перемещение камеры между узлами обеспечивается функцией lerp (линейная интерполяция между двумя значениями). Для ограничения масштабирования объектов колёсиком мыши применяется clamp, который фиксирует значение в заданных пределах
Камерой можно вращать и мышью. Но по оси X есть ограничение: от -1.57 до 0 (это от -π/2 до 0). Так сделано, чтобы камера не наворачивала «мёртвые петли» вокруг блоков. Получив данные с мыши, мы отправляем их двум узлам — CameraHolder и RotationX
В проекте есть код для настройки разных видеоэффектов. Во-первых, это MSAA — сглаживание 3D-объектов. Во-вторых, ограничение максимального FPS. Дальше — масштаб разрешения для 3D-сцены через scaling_3d_scale. Есть и FidelityFX Super Resolution (fsr_sharpness): сцена рендерится в пониженном разрешении, а потом увеличивается с компенсацией размытия. Плюс вертикальная синхронизация (window_set_vsync_mode), которая задаёт частоту обновления кадров. Также используется Temporal Anti-Aliasing (use_taa) для сглаживания движущихся объектов. И наконец, Screen-Space AA (screen_space_aa) — сглаживание уже готового изображения на экране
Что мы увидели в этой части? Мы узнали, что в Godot существуют различные методы сжатия и оптимизации изображения. В следующей части статьи я восстановлю этот туториал, и мы полностью разберём его работу
Перейдем к структуре и коду туториала Godot 3D Anti-Aliasing. Создадим проект под названием 3D Anti-Aliasing Experiment. Добавим корневой узел WorldEnvironment, внутрь поместим AnimationPlayer (он понадобится для создания анимаций), а также MeshInstance3D и DirectionalLight3D. Затем займёмся настройкой этих узлов
Сохраним сцену как world.tscn
В узле WorldEnvironment перейдём во вкладку Environment и выберем ресурс Environment. Затем во вкладке Background установим режим Sky, а во вкладке Sky в свойстве Sky выберем тип Sky. После этого назначим материал ProceduralSkyMaterial
В разделе Mesh узла MeshInstance3D в выберем PlaneMesh. Нажмём на PlaneMesh и изменим размеры на 128×128. В разделе Material выберем StandardMaterial3D. В разделе Shading во вкладке Diffuse Mode установим Lambert, в разделе Albedo выберем шахматную текстуру. В разделе UV1 изменим масштаб с 1×1 до 32×32 по осям XY
Теперь рассмотрим DirectionalLight3D. Во вкладке Directional Shadow для параметра Mode выберем Orthogonal. Значение Fade Start изменим с 0.8 на 1, а Max Distance установим на 25. Перейдём к вкладке Shadow Bias: изменим значение с 0.1 на 0.03, Normal Bias — с 2 на 1.5, Blur — с 1 на 1.5
Перейдем к камере. В этом демонстрационном примере камера перемещается при нажатии кнопок. Устройство камеры простое: вложенные друг в друга узлы Node3D, а внутри — Camera3D
Изучим первый объект. Он состоит из двух кубов — точнее, двух элементов MeshInstance3D, объединённых в одном узле Node3D
Рассмотрим первый куб. Во вкладке Mesh расположен BoxMesh. Во вкладке Surface Material Override находится StandardMaterial3D. Заходим внутрь: во вкладке Albedo цвет (Color) — жёлтый. Рядом есть Texture, в которую установлена NoiseTexture2D. Выберем NoiseTexture2D и нажмём по нему. В свойстве Noise выберем FastNoiseLite, а Color Ramp установим от чёрного к белому. После этого перейдём к свойству UV1 и настроим его как x=3.0, y=2.0, z=1.0. Ниже, в свойстве Sampling в поле Filter выберем фильтр Linear Mipmap Anisotropic
Теперь рассмотрим второй куб. Во вкладке Mesh расположен BoxMesh. Во вкладке Surface Material Override находится StandardMaterial3D. Заходим внутрь: во вкладке Shading отключён параметр Specular. Переходим на вкладку Albedo — цвет (Color) там зелёный, а в Texture выбрана GradientTexture2D. Нажимаем на GradientTexture2D: во вкладке Fill выбираем Square, в поле From указываем 0.5, 0.5 (чтобы градиент шёл из центра), и, само собой, настраиваем сам градиент
Получается, текстуры обоих кубов созданы программным способом
Создадим эти два куба.
Во-первых, создадим узел Node3D, в котором будут находиться 3D-объекты. Затем вложим в него ещё один Node3D — для кубов. И уже внутри него создадим два объекта MeshInstance3D
Перейдем к узлу CPUParticles3D. Во вкладке Drawing в свойство Mesh можно добавить любой меш, например QuadMesh. В материал добавим StandardMaterial3D, а в Albedo → Texture настроим градиент. Также можно поэкспериментировать с Color → Color Ramp для изменения цвета и Scale → Scale Amount для изменения размера частиц со временем
Создадим CPUParticles3D. Для этого выберем корневой Node3D, добавим внутрь него ещё один Node3D, а в него поместим CPUParticles3D
Теперь пришло время добавить камеру. К узлу WorldEnvironment добавим Node3D, внутрь которого вложим ещё один Node3D, а внутрь него — Camera3D
Сейчас добавим две кнопки (Button) и закрепим их: одну — внизу слева, другую — внизу справа
Добавим скрипт к узлу WorldEnvironment (разумеется, не забывая про 3D-настройки), а затем подключим сигналы от Button и Button2 к функциям _on_previous_pressed и _on_next_pressed
extends WorldEnvironment
const ROT_SPEED = 0.003
const ZOOM_SPEED = 0.125
const MAIN_BUTTONS = MOUSE_BUTTON_MASK_LEFT | MOUSE_BUTTON_MASK_RIGHT | MOUSE_BUTTON_MASK_MIDDLE
@onready var camera_holder: Node3D = $Node3D2
@onready var rotation_x: Node3D = $Node3D2/Node3D
@onready var camera: Camera3D = $Node3D2/Node3D/Camera3D
@onready var testers: Node3D = $Node3D
var tester_index := 0
var rot_x := -TAU / 16 # This must be kept in sync with RotationX.
var rot_y := TAU / 8 # This must be kept in sync with CameraHolder.
var camera_distance := 2.0
func _unhandled_input(input_event: InputEvent) -> void:
if input_event.is_action_pressed("ui_left"):
_on_previous_pressed()
if input_event.is_action_pressed("ui_right"):
_on_next_pressed()
if input_event is InputEventMouseButton:
if input_event.button_index == MOUSE_BUTTON_WHEEL_UP:
camera_distance -= ZOOM_SPEED
if input_event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
camera_distance += ZOOM_SPEED
camera_distance = clamp(camera_distance, 1.5, 6)
if input_event is InputEventMouseMotion and input_event.button_mask & MAIN_BUTTONS:
var relative_motion: Vector2 = input_event.screen_relative
rot_y -= relative_motion.x * ROT_SPEED
rot_x -= relative_motion.y * ROT_SPEED
rot_x = clamp(rot_x, -1.57, 0)
camera_holder.transform.basis = Basis.from_euler(Vector3(0, rot_y, 0))
rotation_x.transform.basis = Basis.from_euler(Vector3(rot_x, 0, 0))
func _process(delta: float) -> void:
var current_tester: Node3D = testers.get_child(tester_index)
var current_position := camera_holder.global_transform.origin.z
var target_position := current_tester.global_transform.origin.z
print(current_position," ",target_position)
camera_holder.global_transform.origin.z = lerpf(current_position, target_position, 3 * delta)
camera.position.z = lerpf(camera.position.z, camera_distance, 3 * delta)
func _on_previous_pressed() -> void:
tester_index = max(0, tester_index - 1)
update_gui()
func _on_next_pressed() -> void:
tester_index = min(tester_index + 1, testers.get_child_count() - 1)
update_gui()
func update_gui() -> void:
print(tester_index)
$Button.disabled = tester_index == 0
$Button2.disabled = tester_index == testers.get_child_count() - 1
И при нажатии на кнопки или клавиши «вправо»/«влево» камера перемещается от одного объекта к другому
годот 3д туториал сглаживание.Конец
Спасибо за внимание! Мы разобрали туториал по сглаживанию. Встретимся в следующих статьях




















































