IBillboardSceneNode, Z-Buffer and Projection from 3D to 2D

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Danny Gilbert
Posts: 54
Joined: Thu Oct 25, 2007 1:38 pm
Location: Montreal, Canada

IBillboardSceneNode, Z-Buffer and Projection from 3D to 2D

Post by Danny Gilbert »

I have created a "virtual" world of size 1000x1000 and I use a viewport equal to the size (resolution) of the screen to see this world. I use OrthogonalMatrix to do projection of 3D world on a 2D screen.

Until then, everything work in any screen resolution. I can put some IBillboardSceneNode (cards of a card game) anywhere in my 1000x1000 world and every nodes are always visible and at good position (and good size). My camera can see between near value = 0 and far value = 500.

When a node has a Z-value higher than 500, I cannot see it as expected. This value must be between 0 and 500. But, if this value "change" between 0 and 500, I expect the BILLBOARD to be smaller or bigger (the node is more close or more far away from my camera) !!!
It does not work !

Other thing... If a put many billboard and each one is behind another billboard (example: like a set of cards in a hand), the result is "random".

Example for 2 cards only:
-----------------------------
For 2 billboard, the first one has a Z-value of 10 and the second billboard has a Z-value of 20 (x value a little bit to the right to see both card).
The second billboard is in front of the first a little bit to the right ! It is supposed to be in the back. If I interchange the z-value of both billboards (first billboard Z = 20, second billboard Z = 10), it does not change anything !!! I tried many thing and the results are strange.

My Z value of all billboard material are enable.

Is there something that I don't understand with Z Buffer, viewport and OrthogonalMatrix for projection ?

:?

Thanks.
JP
Posts: 4526
Joined: Tue Sep 13, 2005 2:56 pm
Location: UK
Contact:

Post by JP »

if you're using an orthogonal camera then it doesn't do any perspective transformations so objects are always the same size no matter their distance from the camera. If you want then to be bigger the closer they are to the camera use a perspective camera (the standard ones are all perspective by default) or manually make them smaller by scaling them.

if you objects are disappearing beyond 500 on the z axis then this is probably because the far value of your camera is 500, anything beyond that value will not be rendered. you can increase the far value if you wish.
Image Image Image
Danny Gilbert
Posts: 54
Joined: Thu Oct 25, 2007 1:38 pm
Location: Montreal, Canada

camera

Post by Danny Gilbert »

I need to validate for my camera (I think this is a normal camera scene node). This is OK for the near-far value. Thanks.

My problem is with billboards that are one behind the other. If I want to show many cards in one hand, I need to control the Z-Buffer (and x-y coordinates to move a little bit the card). It seems that I have no control on z-buffer. My position is a vector3df(x,y,z) but Z value does nothing on the final result when billboard are one over the other !
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Re: IBillboardSceneNode, Z-Buffer and Projection from 3D t

Post by rogerborg »

Danny Gilbert wrote:But, if this value "change" between 0 and 500, I expect the BILLBOARD to be smaller or bigger (the node is more close or more far away from my camera) !!!
The whole point of an orthographic projection is that it does not scale the visuals according to their distance from the camera. That's what a perspective projection is for.

However, since you're using billboards, you can pretty easily do the scaling yourself just by changing the size of the billboards.

I don't know what's going on with your Z ordering. It Works For Me, as shown below:

Code: Select all

#include "irrlicht.h"
#include <math.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

void setBillboardPositionAndSize(IBillboardSceneNode * billboard,
								const vector3df & position)
{
	billboard->setPosition(position);
	
	f32 width = 100.f;
	f32 height = 150.f;
	const f32 depth = position.Z / 100.f;

	if(depth > 0.f)
	{
		width /= depth;
		height /= depth;
	}

	billboard->setSize(dimension2df(width, height));
}

int main()
{
	IrrlichtDevice *device = createDevice( EDT_OPENGL,
								 dimension2d<s32>(800, 600),
								 32);
	ISceneManager* smgr  = device->getSceneManager();
	IVideoDriver* driver = device->getVideoDriver();

	ICameraSceneNode * camera = smgr->addCameraSceneNode();
	matrix4 ortho;
	ortho.buildProjectionMatrixOrthoLH(640, 480, 1, 500);
	camera->setProjectionMatrix(ortho, true);
	camera->setPosition(vector3df(0, 0, 0));
	camera->updateAbsolutePosition();

	IBillboardSceneNode * bill1 = smgr->addBillboardSceneNode();
	bill1->setMaterialType(video::EMT_SOLID );
	bill1->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
	bill1->setMaterialFlag(video::EMF_LIGHTING, false);
	bill1->setMaterialFlag(video::EMF_ZBUFFER, true);
	setBillboardPositionAndSize(bill1, vector3df(0, 0, 100));

	IBillboardSceneNode * bill2 = smgr->addBillboardSceneNode();
	bill2->setMaterialType(video::EMT_SOLID );
	bill2->setMaterialTexture(0, driver->getTexture("../../media/terrain-texture.jpg"));
	bill2->setMaterialFlag(video::EMF_LIGHTING, false);
	bill2->setMaterialFlag(video::EMF_ZBUFFER, true);

	const u32 start = device->getTimer()->getTime();
	while (device->run())
	{
		const u32 now = device->getTimer()->getTime();
		const f32 depth = 100.f + 75.f * sin((f32)((now - start) % 2000) / 2000.f * 2.f * PI);
		setBillboardPositionAndSize(bill2, vector3df(60, 30, depth));

		driver->beginScene(true, true, video::SColor(0,100,100,100));
		smgr->drawAll();
		driver->endScene();
	}
}
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Post Reply