Bäume erstellen

Dies ist eine kurze Anleitung, wie man Bäume und andere Arten von Vegetation von Grund auf erstellt.

Ziel ist es, sich nicht auf die Modellierungstechniken zu konzentrieren (dazu gibt es viele Anleitungen), sondern wie sie in Godot gut aussehen.

../../_images/tree_sway.gif

Beginne mit einem Baum

Ich habe diesen bei SketchFab heruntergeladen:

../../_images/tree_base.png

https://sketchfab.com/models/ea5e6ed7f9d6445ba69589d503e8cebf

und in Blender geöffnet.

Malen mit Vertex-Farben

Als erstes solltest Du durch die Verwendung von Vertex-Farben festlegen, wie stark sich der Baum später im Wind bewegen soll. Verwende einfach das Vertex-Farb-Malwerkzeug eines bevorzugten 3D-Modellierungsprogramms und male so etwas wie das hier:

../../_images/tree_vertex_paint.png

Dies ist hier ein wenig übertrieben dargestellt, aber die Idee ist, dass die Farbe anzeigt, wie beweglich jeder Teil des Baumes ist. Diese Skala hier stellt es besser dar:

../../_images/tree_gradient.png

Schreibe einen eigenen Shader für das Laub

Dies ist ein einfaches Beispiel für einen Shader für die Blätter:

shader_type spatial;
render_mode depth_draw_alpha_prepass, cull_disabled, world_vertex_coords;

Es handelt sich um einen räumlichen Shader. Es gibt keine Entfernung der Vorder- oder Rückflächen (so dass Blätter von beiden Seiten gesehen werden können) und Alpha-Prepass wird verwendet, so dass weniger Tiefenartefakte entstehen, die sich aus der Verwendung von Transparenz (und Schattenwurf) ergeben. Schließlich werden für den Bewegungseffekt Weltkoordinaten empfohlen, sodass der Baum kopiert oder verschoben werden kann und trotzdem mit anderen Bäumen synchronisiert bleibt.

uniform sampler2D texture_albedo : hint_albedo;
uniform vec4 transmission : hint_color;

Hier wird die Textur sowie eine Transmissionsfarbe ausgelesen, die dazu dient, die Blätter etwas hinterleuchtet darzustellen, um so die Streuung der Oberfläche zu simulieren.

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

Dies ist der Code, um die Bewegung der Blätter zu erzeugen. Es ist einfach (verwendet wird nur eine Sinuswelle, die mit der Zeit und der Achsenposition multipliziert wird, funktioniert aber gut). Beachte, dass die Stärke mit der Farbe multipliziert wird. Jede Achse verwendet einen anderen kleinen Multiplikationsfaktor nahe 1.0, so dass Achsen nicht synchron erscheinen.

Zum Schluss bleibt nur noch der 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;
    TRANSMISSION = transmission.rgb;
}

Und das ist so ziemlich alles.

Der Ast-Shader ist ähnlich, außer das er nicht in den Alphakanal schreibt (daher ist kein Alpha-Prepass erforderlich) und erfordert keine Transmission, um zu funktionieren. Beide Shader können durch Hinzufügen von Normal Maps, AO (Umgebungsbeleuchtung) und anderen Maps verbessert werden.

Shader verbessern

Es gibt viele weitere Ressourcen, die Du lesen kannst. Da Du nun die Grundlagen kennst, ist es empfehlenswert, das Kapitel von GPU Gems3 zu lesen, wie dies in Crysis umgesetzt wurde (konzentriere Dich hauptsächlich auf den Code der die Bewegungen beschreibt, da viele andere Techniken dort veraltet sind):

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