Y Billboard shader that uses camera position instead of camera angle.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By bloqm

By default, a billboard will rotate to face the camera… but will also rotate just by looking around without moving, causing a weird effect and sometimes overlaps.

I want to have a Y-Billboard that rotates based on its direction to the camera, not simply the camera rotation.

I have tried implementing this as a script, and while it worked perfectly for the most part, except the shadow would rotate with the mesh instead of facing the light source like a regular billboard.

In case it is relevant, this is the code I used on the mesh to achieve the effect. What I need is a shader equivalent.

func _process(_delta):
  var target = get_viewport().get_camera().global_transform.origin
  target.y = global_transform.origin.y
  look_at(target, Vector3.UP)

I’ve already tried fiddling with generated shader code, but I only managed to replicate the default behaviour. This is my code for a Y-Billboard that respects scale:

MODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(vec4(normalize(cross(vec3(0.0, 1.0, 0.0), CAMERA_MATRIX[2].xyz)),0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(normalize(cross(CAMERA_MATRIX[0].xyz, vec3(0.0, 1.0, 0.0))),0.0), WORLD_MATRIX[3] ) * mat4(mat3(WORLD_MATRIX));

However it still rotates with the camera rotation, not with the angle to the camera.
Any ideas? Thanks.