Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Fazendo árvores

Este é um pequeno tutorial sobre como criar árvores e outros tipos de vegetação do zero.

O objetivo não é focar nas técnicas de modelagem (existem muitos tutoriais sobre isso), mas em como fazê-los parecer bonitos no Godot.

../../_images/tree_sway.gif

Comece com uma árvore

Eu peguei esta árvore do SketchFab:

../../_images/tree_base.png

https://sketchfab.com/models/ea5e6ed7f9d6445ba69589d503e8cebf

e a abri no Blender.

Pintar com cores de vértice (vertex colors)

A primeira coisa que você pode querer fazer é usar as cores de vértice para pintar o quanto a árvore vai balançar com o vento. Basta usar a ferramenta de pintura de cor de vértice do seu programa de modelagem 3D favorito e pintar algo assim:

../../_images/tree_vertex_paint.png

Isso está um pouco exagerado, mas a ideia é que a cor indica o quanto o balanço afeta cada parte da árvore. Esta escala aqui representa melhor:

../../_images/tree_gradient.png

Escreva um shader personalizado para as folhas

Este é um exemplo de um shader para folhas:

shader_type spatial;
render_mode depth_prepass_alpha, cull_disabled, world_vertex_coords;

Este é um shader espacial. Não há descarte de faces frontais/traseiras (culling), de modo que as folhas podem ser vistas de ambos os lados, e o pré-passe de alfa é usado para que haja menos artefatos de profundidade resultantes do uso de transparência (além de permitir que as folhas projetem sombras). Finalmente, para o efeito de balanço, coordenadas do mundo são recomendadas, para que a árvore possa ser duplicada, movida, etc., e ainda funcione em harmonia com as outras árvores.

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

Aqui, a textura é lida, bem como uma cor de transmissão (transmission color), que é usada para adicionar uma retroiluminação às folhas, simulando o subsurface scattering (espalhamento sob a superfície).

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;
}

Este é o código para criar o balanço das folhas. É básico (apenas usa uma onda senoidal multiplicada pelo tempo e pela posição do eixo, mas funciona bem). Observe que a força é multiplicada pela cor. Cada eixo usa um fator de multiplicação diferente e próximo de 1.0 para que os eixos não pareçam sincronizados.

Por fim, tudo o que resta é o fragment shader:

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

E é basicamente isso.

O shader do tronco é semelhante, exceto que não escreve no canal alfa (portanto, nenhum pré-passe de alfa é necessário) e não requer transmissão para funcionar. Ambos os shaders podem ser aprimorados adicionando mapeamento de normais, AO e outros mapas.

Melhorando o shader

Existem muitos outros recursos sobre como fazer isso que você pode ler. Agora que você conhece o básico, uma leitura recomendada é o capítulo do GPU Gems3 sobre como o Crysis faz isso (foque principalmente no código de balanço, já que muitas outras técnicas mostras ali estão obsoletas):

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