Closed mysticfall closed 2 years ago
This is only the case with plane meshes, quad meshes work as expected.
I can confirm this bug for both 3.0.5 and master, although they produce different results.
In 3.0.5 using billboard on a plane will result in a plane that is slightly skewed when rotating the camera around the plane, this looks like it's just a bug in the shader.
In master (built just now) the plane isn't rendered at all, but I might have a clue as to why.
I'm speculating that the cube works because the shader is using positive Z as a normal, a cube does have a face with Z normal whereas the plane is facing positive Y (up). Using a prism you get the "front" of the prism (the triangular face with positive Z normal). A plane does not have any Z (or X) faces.
Adding an option to set the normal for the plane mesh would be a nice feature to have and might solve this problem. And/or add it as an option for SpatialMaterial and/or a render_mode option for ShaderMaterial.
Of course, all speculation on my part
Can you try this shader for a shader material on a cube and plane? (note: all the different axis matrices are for flipping what face is rendered towards the camera, you can remove the flip stuff entirely to get the pos Z, which is default)
EDIT: after experimenting this isn't optimal. Gotta find a better way.
shader_type spatial;
render_mode unshaded;
uniform sampler2D image;
uniform bool keep_scale = true;
varying vec4 test;
void vertex()
{
mat4 axis_x_pos = mat4(vec4(0, 0, 1, 0), vec4(0, 1, 0, 0), vec4(-1, 0, 0, 0), vec4(0, 0, 0, 1));
mat4 axis_x_neg = mat4(vec4(0, 0, -1, 0), vec4(0, 1, 0, 0), vec4(1, 0, 0, 0), vec4(0, 0, 0, 1));
mat4 axis_y_pos = mat4(vec4(1, 0, 0, 0), vec4(0, 0, 1, 0), vec4(0, -1, 0, 0), vec4(0, 0, 0, 1));
axis_y_pos *= mat4(vec4(-1, 0, 0, 0), vec4(0, 1, 0, 0), vec4(0, 0, -1, 0), vec4(0, 0, 0, 1));
mat4 axis_y_neg = mat4(vec4(1, 0, 0, 0), vec4(0, 0, -1, 0), vec4(0, 1, 0, 0), vec4(0, 0, 0, 1));
mat4 axis_z_pos = mat4(vec4(1, 0, 0, 0), vec4(0, 1, 0, 0), vec4(0, 0, 1, 0), vec4(0, 0, 0, 1));
mat4 axis_z_neg = mat4(vec4(1, 0, 0, 0), vec4(0, -1, 0, 0), vec4(0, 0, -1, 0), vec4(0, 0, 0, 1));
axis_z_neg *= mat4(vec4(-1, 0, 0, 0), vec4(0, -1, 0, 0), vec4(0, 0, 1, 0), vec4(0, 0, 0, 1));
mat4 flip = axis_y_pos; // CHANGE ME TO CHANGE WHAT FACE IS SHOWING
MODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0], CAMERA_MATRIX[1], CAMERA_MATRIX[2], WORLD_MATRIX[3]);
if (keep_scale)
MODELVIEW_MATRIX *= mat4(vec4(length(WORLD_MATRIX[0].xyz),0,0,0),vec4(0,length(WORLD_MATRIX[1].xyz),0,0),vec4(0,0,length(WORLD_MATRIX[2].xyz),0),vec4(0,0,0,1));
MODELVIEW_MATRIX[2][2] = 0.0;
MODELVIEW_MATRIX *= flip;
}
void fragment()
{
ALBEDO = texture(image, UV).rgb;
}
Made a small experiment on the upstream master, added translation and rotation for primitive meshes. Setting X rotation to 90 will face the plane to Z+ and that seems to work.
https://github.com/spongeboburu/godot/commit/fd474e232f8c6a500ed4439463987162c77fabf0
Try it out. If this is considered useful by enough users maybe I'll ask the devs if a pull request is in order or if they have a cleaner way of fixing it.
Seems to still happen in 3.2.2-rc1 although not sure why not just use quads instead of planes if they work correctly... I mean, they serve different purpose, so just pick the one that's fit better.
Closing in favor of https://github.com/godotengine/godot-proposals/issues/4516, which would resolve the original issue here (it can't be done without breaking compatibility).
The QuadMesh vs PlaneMesh differences are now documented in the class reference.
Godot version:
master
/ 2ff31badaOS/device including version: Manjaro Linux 17.1
Issue description: I'm not entirely certain if I understood the concept of billboard properly, but if I'm not mistaken it's supposed to be used to make something always face the camera.
If you set the billboard property to
enabled
, it'd make a plane mesh's thin side to face the camera so it can't be used to make an UI panel or item label to display properly.On the other hand, the
y-billboard
option makes such a plane like meshes to show its broad side to the camera, but this time the texture is flipped horizontally (tested with a viewport texture) and I couldn't find a way to correct its orientation.And even without the flipping problem, the mesh doesn't align property with respect to the current camera. Instead of facing the camera it tries to match its rotation, and sometimes the surface entirely disappears if you turn the camera to a certain angle.
Steps to reproduce: Try to make the UI panel in
gui_in_3d
scene from the official demo to always face the camera.