Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Создание деревьев

Это краткое руководство о том, как создавать деревья и другие виды растительности с нуля.

The aim is to not focus on the modeling techniques (there are plenty of tutorials about that), but how to make them look good in Godot.

../../_images/tree_sway.gif

Начните с дерева

Я взял это дерево из SketchFab:

../../_images/tree_base.png

https://sketchfab.com/models/ea5e6ed7f9d6445ba69589d503e8cebf

и открыл его в Blender.

Рисование цветами вершин

The first thing you may want to do is to use the vertex colors to paint how much the tree will sway when there is wind. Just use the vertex color painting tool of your favorite 3D modeling program and paint something like this:

../../_images/tree_vertex_paint.png

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

../../_images/tree_gradient.png

Напишите пользовательский шейдер для листьев

This is an example of a shader for leaves:

shader_type spatial;
render_mode depth_prepass_alpha, cull_disabled, world_vertex_coords;

Это пространственный шейдер. В нем нет обрезки спереди/сзади (поэтому листья видны с обеих сторон), и используется альфа-препасс, поэтому меньше артефактов глубины, возникающих при использовании прозрачности (и листья отбрасывают тень). Наконец, для эффекта качания рекомендуется использовать мировые координаты, чтобы дерево можно было дублировать, перемещать и т.д., и оно все равно будет работать вместе с другими деревьями.

uniform sampler2D texture_albedo : source_color;
uniform vec4 transmission : source_color;

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

uniform float sway_speed = 1.0;
uniform float sway_strength = 0.05;
uniform float sway_phase_len = 8.0;

void vertex() {
    float strength = COLOR.r * sway_strength;
    VERTEX.x += sin(VERTEX.x * sway_phase_len * 1.123 + TIME * sway_speed) * strength;
    VERTEX.y += sin(VERTEX.y * sway_phase_len + TIME * sway_speed * 1.12412) * strength;
    VERTEX.z += sin(VERTEX.z * sway_phase_len * 0.9123 + TIME * sway_speed * 1.3123) * strength;
}

Это код для создания колыхания листьев. Он прост (просто использует синусоиду, умноженную на время и положение оси, но работает хорошо). Обратите внимание, что сила умножается на цвет. Каждая ось использует свой маленький коэффициент умножения, близкий к 1.0, поэтому оси не синхронизируются.

Наконец, все, что осталось, - это шейдер фрагментов:

void fragment() {
    vec4 albedo_tex = texture(texture_albedo, UV);
    ALBEDO = albedo_tex.rgb;
    ALPHA = albedo_tex.a;
    METALLIC = 0.0;
    ROUGHNESS = 1.0;
    TRANSMISSION = transmission.rgb;
}

И это практически все.

Шейдер trunk похож, за исключением того, что он не записывается в альфа-канал (поэтому не требуется предварительный альфа-пасс) и не требует передачи для работы. Оба шейдера можно улучшить, добавив нормальное отображение, AO и другие карты.

Улучшение шейдера

Есть много других ресурсов о том, как это сделать, которые вы можете прочитать. Теперь, когда вы знаете основы, рекомендуем прочитать главу из GPU Gems3 о том, как Crysis делает это (сосредоточьтесь в основном на коде sway, так как многие другие методы, показанные там, устарели):

https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch16.html