How do I rotate a mesh toward something in a shader?

Godot Version

4.2.1

Question

Hello, I wanted to know how to rotate for example a plane to always face the player position in shader ? I’m pretty sure it’s possible but the only lead I got was “rotation matrice” but I’m not good enough at math to understand any of this …
Any help possible ?

Um I’m not sure how you rotate a shader, but typically 3d objects in gosot have a transform3d that should have a function to say looking_at(player.global_position)

I think there are three levels of liking at.

Node3D.looking_at
Transform3d.looking_at
Basis.looking_at

Maybe a primer?

You could create your own shader for it, depending on your exact needs. Maybe something like this:

void vertex(){
	//Modify the vertex normal so it's pointing towards the camera (positive Z)
	NORMAL = vec3(0.0, 1.0, 0.0);
	//Modify the model view matrix to make the vertex look at the camera
	MODELVIEW_MATRIX = VIEW_MATRIX * mat4(
		vec4(normalize(cross(vec3(0.0, 1.0, 0.0), INV_VIEW_MATRIX[2].xyz)), 0.0), 
		vec4(0.0, 1.0, 0.0, 0.0), 
		vec4(normalize(cross(INV_VIEW_MATRIX[0].xyz, vec3(0.0, 1.0, 0.0))), 0.0), 
		MODEL_MATRIX[3]
	);
}

Or you could use the built-in billboard mode of Spatial Material, which also should take care of shadows automatically for you. See: Standard Material 3D and ORM Material 3D — Godot Engine (latest) documentation in English

This will completely kill performance if done every frame, especially in GDScript. Doing billboards in the vertex shader is a much better solution and probably a few thousand times faster.

1 Like

It’s probably less then you think. It’s not rotating an entire mesh it just rotating a single transformer. Which happens every frame for potential thousands of spatial nodes.

It’s also mostly a native c++ function being invoked in the script.

After the transform is rotated then the mesh is calculated and rendered by the GPU.

The problem is I can’t wrap my head around all these “matrices” so I’m sorry but I don’t understand any of the shader code Armynator did, this is just too complicated for me …
Isn’t there something like look_at() in shader without the black magic of complicated math ?
And for pennyloafers : I think I can’t do look_at() for what I’m trying to do, because I want to rotate all the meshes of a multimeshinstance3D (is it even possible at all ?).
The billboard was the most interesting suggestion I think, but can I update the billboard rotation manually trough gdscript maybe ? Like make the billboard only have 90 degres angle (Probably not clear …)

Well, I guess there isn’t … I’ll be damned then, I won’t be able to understand this sort of math in my lifetime.

MODELVIEW_MATRIX = VIEW_MATRIX * mat4(INV_VIEW_MATRIX[0], INV_VIEW_MATRIX[1], INV_VIEW_MATRIX[2], MODEL_MATRIX[3]);

Just put this in the vertex shader, if you don’t want to modify the code beyond facing the camera you’ll be fine without understanding the matrices.

And like Armynator said using the built-in shader mode is a good option, which doesn’t require you to understand the matrices