Idea: Calculate Max Pixel Count for HOQs

Threads related to Google Summer of Code
Post Reply
tgraupmann
Gnoll
Posts: 696
Joined: Sun Feb 20, 2005 5:28 am
Contact:

Idea: Calculate Max Pixel Count for HOQs

Post by tgraupmann »

This should be an easy project for a student.

Utilize the HOQ Wiki Entry http://www.ogre3d.org/wiki/index.php/Ha ... ixel_Count to design an algorithm that can estimate the pixel count for an Ogre::Billboard at various resolutions and camera field of views.

lodi
Greenskin
Posts: 103
Joined: Sat Jul 24, 2004 7:06 pm

Post by lodi »

Why would you use an occlusion query on a billboard? You can just run the vertices through the current projection matrix and then do a simple formula to get the area in normalised screen coordinates (which you can easily change to # of pixels, or leave it as a ratio of total screen area, which is probably what you wanted in the first place.)

buddy
Google Summer of Code Student
Google Summer of Code Student
Posts: 78
Joined: Tue Mar 29, 2005 3:35 pm
Location: USA

Post by buddy »

lodi wrote: You can just run the vertices through the current projection matrix and then do a simple formula to get the area in normalised screen coordinates.
The idea seems to be about applying it to things like lens flares, and then you need to know how much of it was, well, occluded..

User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

Think that the student will be rewarded with 4500$ for this, so it shouldn't be that easily done.
Besides, this year seems to be a lot of really useful projects for Ogre!
Image

lodi
Greenskin
Posts: 103
Joined: Sat Jul 24, 2004 7:06 pm

Post by lodi »

Ahh yes, my bad. For some reason I was thinking only about using the pixel count for lod purposes, etc.

And I also agree that this isn't really worthy of a SoC project...

tgraupmann
Gnoll
Posts: 696
Joined: Sun Feb 20, 2005 5:28 am
Contact:

Post by tgraupmann »

Kencho wrote:Think that the student will be rewarded with 4500$ for this, so it shouldn't be that easily done.
Besides, this year seems to be a lot of really useful projects for Ogre!
Hey that's about 3 month's rent in Seattle.

buddy
Google Summer of Code Student
Google Summer of Code Student
Posts: 78
Joined: Tue Mar 29, 2005 3:35 pm
Location: USA

Post by buddy »

tgraupmann wrote:Hey that's about 3 month's rent in Seattle.
Well, in some parts of the world it isn't so. No way can SoC compete money-wise with your average tech internship in US, even at undergraduate level. Is it a reason to let "do-in-a-week" projects in? I dunno, but I doubt it ;).

User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19265
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66
Contact:

Post by sinbad »

I also think this is too small for a whole project, although if it were an extended proposal with a framework for using HOQs in various cases it would be worth consideration.

tgraupmann
Gnoll
Posts: 696
Joined: Sun Feb 20, 2005 5:28 am
Contact:

Post by tgraupmann »

lodi wrote:Why would you use an occlusion query on a billboard? You can just run the vertices through the current projection matrix and then do a simple formula to get the area in normalised screen coordinates (which you can easily change to # of pixels, or leave it as a ratio of total screen area, which is probably what you wanted in the first place.)
I had figured to get the corners of the billboard in screen coordinates to calculate width and height. This figuring area is simply width X height.

Man that sounds so easy. Is there a working example of this somewhere?

I'll post this in the wiki as soon as I figure it out...

lodi
Greenskin
Posts: 103
Joined: Sat Jul 24, 2004 7:06 pm

Post by lodi »

Well as buddy pointed out, I forgot about the case when part of the billboard is occluded by something. But you can still use that kind of idea for lod purposes etc.

The billboard is already orthogonal to the camera, so you don't even need to transform the vertices, you can just get a height and width vector and transform those. Multiply first by the inverse of the camera's view matrix and then the cameras projcection matrix. Normalize w, then height * height of the window * width * width of the window and you have your approximate pixel count. Probably more useful to just use height*width since that'll give you the percentage used (of the whole screen, regardless of resolution)

tgraupmann
Gnoll
Posts: 696
Joined: Sun Feb 20, 2005 5:28 am
Contact:

Post by tgraupmann »

This is not the most efficient code but it seems to be working. I'll refine in the morning.

ToScreenCoordinates

Code: Select all

inline Ogre::Vector2 ToScreenCoordinates(Ogre::Camera *_camera, const Ogre::Vector3 &_position)
{ 
	Ogre::Vector3 hcsPosition = _camera->getProjectionMatrix() * _camera->getViewMatrix() * _position;
	return Ogre::Vector2(0.5 - hcsPosition.x * 0.5f, hcsPosition.y * 0.5f + 0.5);
}
Sample code

Code: Select all

	// Get the pixel count
	unsigned int pixelCount = m_RenderableOcclusionPair->GetPixelCount();

	// Get the render window
	Ogre::RenderWindow* renderWindow = Game::GetSingleton()->GetWindow();
	assert (renderWindow);

	// Get the Camera Scene Node
	Ogre::Camera* camera = GetCamera();
	assert (camera);

	// Approximate area
	float halfWidth = m_BillboardWidth*0.5f;
	float halfHeight = m_BillboardHeight*0.5f;

	Ogre::Vector3 pos = m_OcclusionTestSceneNode->getPosition();
	Ogre::Vector3 nX = camera->getOrientation().xAxis().normalisedCopy();
	Ogre::Vector3 nY = camera->getOrientation().yAxis().normalisedCopy();

	Ogre::Vector2 topLeft = ToScreenCoordinates(camera, pos + nX*(-halfWidth) + nY*halfHeight);
	Ogre::Vector2 topRight = ToScreenCoordinates(camera, pos + nX*halfWidth + nY*halfHeight);
	Ogre::Vector2 bottomLeft = ToScreenCoordinates(camera, pos + nX*(-halfWidth) + nY*(-halfHeight));
	Ogre::Vector2 bottomRight = ToScreenCoordinates(camera, pos + nX*halfWidth + nY*(-halfHeight));

	float aX = std::min(0.0f, std::min(topLeft.x, std::min(topRight.x, std::min(bottomLeft.x, bottomRight.x))));
	float aY = std::min(0.0f, std::min(topLeft.y, std::min(topRight.y, std::min(bottomLeft.y, bottomRight.y))));
	float bX = std::max(1.0f, std::max(topLeft.x, std::max(topRight.x, std::max(bottomLeft.x, bottomRight.x))));
	float bY = std::min(1.0f, std::max(topLeft.y, std::max(topRight.y, std::max(bottomLeft.y, bottomRight.y))));

	float width = (bX - aX) * renderWindow->getWidth();
	float height = (bY - aY) * renderWindow->getHeight();
	float area = width*height;
	if (area)
	{
		float ratio = pixelCount/area;
	}

bleubleu
Kobold
Posts: 27
Joined: Mon Dec 11, 2006 4:38 am

Post by bleubleu »

One way to approximate the area would be to use the Camera::projectSphere() method.

Code: Select all

bool Ogre::Camera::projectSphere  (  const Sphere &  sphere,  
  Real *  left,  
  Real *  top,  
  Real *  right,  
  Real *  bottom 
 )  const [virtual]
This is nice because it returns the bounds of a square in screen coordinate so you can basically replace all your code with a single call. I will try this tonight.

Mat

Post Reply