Jump to content

Per Triangle Bilboarding


SpiderPig
 Share

Recommended Posts

I'm currently trying to write a shader that makes every triangle of the mesh point to the position of the camera regardless of the camera's rotation.  I think I can multiply the vertex positions in the vertex shader by a one of the matrices but I'm not sure which one or how.  And I think the camera matrix will rotate the triangle to the same orientation as the camera and not just point to it's position?

Basically I need the vertex shader (or geometry if it's easier) to do what Entity::Point() does but on each triangle and not the mesh as a whole.  Anyone got any ideas on how to do this?  ?

 

EDIT : I've been getting the direction the camera like this;

normalize(vsModelVertexPosition.xyz - cameraposition)

 

Link to comment
Share on other sites

I ended up finding a way, below is a snippet of code on how i got it to work.  It's not as exact as using trig functions like cos(), sin() and atan2(), but the speed outweighs the accuracy. And it's not off by much.  There's still a few things I can do to perfect it.  ?

 

float _diffX = _camPos.x - _mdlPos.x;
float _diffZ = _camPos.z - _mdlPos.z;
Vec2 _yVec = Vec2(_diffX, _camPos.z - _mdlPos.z).Normalize();

float _xzPart = sqrt((_diffX * _diffX) + (_diffZ * _diffZ));
Vec2 _xVec = Vec2(_camPos.y - _mdlPos.y, _xzPart).Normalize();

const float magicNumber = 6.343830794f;
const float radToPi = 57.29577951f;
const float sinCos45 = 0.707106781f;

if (_yVec.x <= 0.0f && _yVec.y <= 0.0f) {//bottomLeft
	if (_yVec.x >= -sinCos45) {
		_yAngle = ((-_yVec.x) * radToPi) + (-_yVec.x * magicNumber);
	}
	else {
		_yAngle = 90.0f - (((-_yVec.y) * radToPi) + (-_yVec.y * magicNumber));
	}
}
else if (_yVec.x > 0.0f && _yVec.y < 0.0f) {//bottomRight
	if (_yVec.x <= sinCos45) {
		_yAngle = -((_yVec.x * radToPi) + (_yVec.x * magicNumber));
	}
	else {
		_yAngle = -90.0f + (((-_yVec.y) * radToPi) + (-_yVec.y * magicNumber));
	}
}
else if (_yVec.x > 0.0f && _yVec.y > 0.0f) {//TopRight
	if (_yVec.x <= sinCos45) {
		_yAngle = (_yVec.x * radToPi) + (_yVec.x * magicNumber) - 180.0f;
	}
	else {
		_yAngle = (((-_yVec.y) * radToPi) + (-_yVec.y * magicNumber)) - 90.0f;
	}
}
else if (_yVec.x <= 0.0f && _yVec.y > 0.0f) {//TopLeft
	if (_yVec.x >= -sinCos45) {
		_yAngle = 180.0f - ((-_yVec.x * radToPi) + (-_yVec.x * magicNumber));
	}
	else {
		_yAngle = 90.0f + ((_yVec.y * radToPi) + (_yVec.y * magicNumber));
	}
}


if (_xVec.x <= 0.0f && _xVec.y <= 0.0f) {//bottomLeft
	if (_xVec.x >= -sinCos45) {
		_xAngle = ((-_xVec.x) * radToPi) + (-_xVec.x * magicNumber);
	}
	else {
		_xAngle = 90.0f - (((-_xVec.y) * radToPi) + (-_xVec.y * magicNumber));
	}
}
else if (_xVec.x > 0.0f && _xVec.y < 0.0f) {//bottomRight
	if (_xVec.x <= sinCos45) {
		_xAngle = -((_xVec.x * radToPi) + (_xVec.x * magicNumber));
	}
	else {
		_xAngle = -90.0f + (((-_xVec.y) * radToPi) + (-_xVec.y * magicNumber));
	}
}
else if (_xVec.x > 0.0f && _xVec.y > 0.0f) {//TopRight
	if (_xVec.x <= sinCos45) {
		_xAngle = (_xVec.x * radToPi) + (_xVec.x * magicNumber) - 180.0f;
	}
	else {
		_xAngle = (((-_xVec.y) * radToPi) + (-_xVec.y * magicNumber)) - 90.0f;
	}
}
else if (_xVec.x <= 0.0f && _xVec.y > 0.0f) {//TopLeft
	if (_xVec.x >= -sinCos45) {
		_xAngle = 180.0f - ((-_xVec.x * radToPi) + (-_xVec.x * magicNumber));
	}
	else {
		_xAngle = 90.0f + ((_xVec.y * radToPi) + (_xVec.y * magicNumber));
	}
}

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...