Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | mrdunk |
Hi, i’m new here.
I first tried Godot a month ago. I jumped in with V4.0. In retrospect, V3 might have been a better choice but V4.0 seems robust so far.
Ive no real previous game engine experience although i played with Babylon.js a few years ago.
Go easy on me.
So this started out as a question but i worked out the answer before i submitted.
There’s not much info online about the subject though so thought i’d post here in the hope that it helps someone else. (Or a future me when i forget what i’ve learned and go searching again.)
I want to draw trees. Many, many trees.
After a bit of online reading, it seems like i want some combination of multimesh, billboards and shaders is what i need to get the correct texture images showing from different view angles for all the trees in a forest.
This project https://github.com/wojtekpil/Godot-Octahedral-Impostors looks fantastic but not yet working on V4.0 and it’s likely overkill for my low-poly needs.
Reading online there’s a few people manipulating which texture gets drawn on the CPU but this seems like the wrong approach, particularly as i’ll need to get this working with MultiMeshInstance3D; The texture will need to be calculated per instance.
So here’s what i have so far that implements a working prototype.
Note that i still need to fix transparency, scaling, shadows, …etc…
shader_type spatial;
uniform sampler2D imported_texture;
uniform vec2 uv1_scale;
void vertex() {
// Bliiboard calculation. Make base geometry always face observer.
mat4 modified_model_view = VIEW_MATRIX * mat4(
INV_VIEW_MATRIX[0],
INV_VIEW_MATRIX[1],
INV_VIEW_MATRIX[2],
MODEL_MATRIX[3]
);
MODELVIEW_MATRIX = modified_model_view;
// Calculate view angle.
vec3 node_view = NODE_POSITION_WORLD - CAMERA_POSITION_WORLD;
node_view = normalize(node_view);
// The dot product potput stored in angle_y is not linear.
// If you wanted the real angle
// you'd want to do `real_angle = arcsing(angle_y)`.
float angle_y = dot(node_view, vec3(0.0, 1.0, 0.0));
node_view[1] = 0.0;
// angle_xz not real angle. See comment for angle_y.
float angle_xz = dot(node_view, vec3(0.0, 0.0, 1.0));
if(node_view[0] < 0.0) {
angle_xz = 2.0 - angle_xz;
}
if(angle_y < -0.707) {
// When viewed from above,
// the shows whole atlas texture.
// Just for demonstration purposes.
UV = UV;
} else if(angle_xz < 0.0) {
// FIrst quadrent of atlas texture.
UV = UV * uv1_scale + vec2(0, 0);
} else if(angle_xz < 1.0) {
UV = UV * uv1_scale + vec2(0.5, 0);
} else if(angle_xz < 2.0) {
UV = UV * uv1_scale + vec2(0, 0.5);
} else {
UV = UV * uv1_scale + vec2(0.5, 0.5);
}
}
void fragment() {
ALBEDO = texture(imported_texture, UV).xyz;
}
In this state, it draws my tree imposters from the right direction.
Next i need to fix transparency, scaling, etc.
There’s no reason this approach wouldn’t work for animated characters as well. You’d need to pass in a new uniform
value for the animation frame.
Anyway, i hope this helps someone.