Mesh points to the camera on only 2 axis with shaders

Hi,
I’m newbie with shaders and I didn’t use matrix for a while… (I’m not Neo :smile:)
I want meshes face to the camera only on 2 axis
I know it’s like billboard and I can take a look on THREE.Sprite but I’m not able to make it working…

From three.js sprite vertex glsl:

uniform float rotation;
uniform vec2 center;

void main() {
	
	vec3 labelpos = vec3( 0.0, 0.0, 0.0 );

	vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );
	
	vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) );
	
	vec2 rotatedPosition;
	rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;
	rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;
	
	mvPosition.xy += rotatedPosition;
	
	gl_Position = projectionMatrix * mvPosition;
}

Or mixing things found on internet and three.js docs :

void main() {
	gl_Position = projectionMatrix * (viewMatrix * modelMatrix * vec4(0.0, 0.0, 0.0, 1.0) + vec4(position.x, position.y, position.z, 0));
}

Both work but on 3 axis, I don’t kown what to change to only point the camera on X and Z axis :cry:

What does this supposed to mean? Do you mind describing in more detail your expected result?

@herve3d Hi!
You can do it on js side: https://jsfiddle.net/prisoner849/w19d5km7/

3 Likes

It’s like the prisoner849’s example, a lookat but with a rotation only on X and Z axis. Sorry my description was wrong about axis, I update it.
But I want to use shaders avoiding some loops in the AnimationLoop

Really nice example, I like this pixel art style :grin:
You understood my need despite my bad description, but I want to use shaders to manage it easily during scene or objects loading and remove/dispose, avoiding management of many arrays for my usecases. And for optimization too I think

I failed to use shaders, I’m giving up for now :confounded:

As I use a PointerLockControls this is how I did it following @prisoner849 example:

let t = new THREE.Vector3();
...
//t.copy(controls.getObject().position);
//t.y = 0;
t.x = controls.getObject().position.x;
t.z = controls.getObject().position.z;

planes.forEach(p => {
	p.lookAt(t);
});

Just recalled about this topic, surfing @hofk’s collection of examples.
Seems it works with InstancedMesh and slightly modified MeshBasicMaterial (modification), in which you pass a quaternion in uniform: https://jsfiddle.net/prisoner849/g8j24z0n/

2 Likes

Oh a solution with shader ! Super, this is what I wanted to do, I think it’s more optimized. Thanks

@herve3d You’re welcome :beers:

If someone’s interested in this effect with lights,
here is an option with THREE.SpotLight: https://jsfiddle.net/prisoner849/9v1eoxL3/