Per Face Culling

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Mirror
Posts: 218
Joined: Sat Dec 01, 2007 4:09 pm

Re:

Post by Mirror »

PI wrote:I'd encourage you to optimise it! Also, I'd like to see this integrated into Irrlicht. Why?

Because I think animated meshes could benefit from this. Tell me if it's nonsense. Animated meshes are changing every frame, so - I guess - they won't benefit from VBOs at all. Hence there this technique could be handy.

Also, it'd be a great alternate solution for lower-end computers.

What do you think?

Cheers,
PI
my current understanding about animated meshes has it that in case of VBOs, animated meshes could benefit from VBOs. we could upload the index buffer once and make it static, and then only upload the vertex buffer every frame, this provided of course that in animated meshes only the vertices change ( their values actually ) and not the indices ( we still keep connecting the same vertices ). So if this is correct about how animated meshes work - i repeat this is my current understanding it may not be true - they could benefit from VBOs. Thus since this technique changes the index buffer it would be like not using VBOs at all.

anyway, i will try to optimize it even more to the final step.

About integration in irrlicht, i'm not the person to decide about this, there are around here people far more experienced and with more knowledge than me ( hybrid, rogerborg, blindside, bitplane etc ) who can decide if this indeed is useful as much as to be integrated. But let's wait first for the final optimization :D
bull
Posts: 36
Joined: Wed Sep 12, 2007 8:49 am
Location: s1Ng4p0R3

Post by bull »

Because I think animated meshes could benefit from this. Tell me if it's nonsense. Animated meshes are changing every frame, so - I guess - they won't benefit from VBOs at all. Hence there this technique could be handy.
If I'm not wrong, with hardware skinning, you can upload all the mesh data to your graphic card. Animation is then done through a vertex shader. Since the shader only modify the way the mesh is rendered without changing the mesh itself. The mesh is always static.
My name is bull, for we are many ...
varmint
Posts: 46
Joined: Fri Oct 06, 2006 4:33 pm

Post by varmint »

bull wrote:
Because I think animated meshes could benefit from this. Tell me if it's nonsense. Animated meshes are changing every frame, so - I guess - they won't benefit from VBOs at all. Hence there this technique could be handy.
If I'm not wrong, with hardware skinning, you can upload all the mesh data to your graphic card. Animation is then done through a vertex shader. Since the shader only modify the way the mesh is rendered without changing the mesh itself. The mesh is always static.
No you can do weight calcs this way too.. Xbox 360 does it this way and alot of the next gen consoles only get their power from doing such things on the GPU.. EA tries to offload alot of stuff like this onto the GPU...


the GPU is a PU. and you can use it for what ever your imagination sees fit.
Mirror
Posts: 218
Joined: Sat Dec 01, 2007 4:09 pm

Post by Mirror »

OK this is the final and most optimized version. i'm waiting results from PI agi_shi and the others :)

thanks to hybrid for optimizations tips and advice :D

http://irrlichtirc.g0dsoft.com/Ogami_It ... _final.exe
doqkhanh
Posts: 158
Joined: Sat Mar 01, 2008 3:14 am
Location: Tokyo, Japan
Contact:

Post by doqkhanh »

My computer: Intel(R) 82852/82855 GM/GME Graphics Controller (Microsoft Corporation - XDDM) ialmrnt5.dll 6.14.10.4656

Image

Image

Image
PI
Posts: 176
Joined: Tue Oct 09, 2007 7:15 pm
Location: Hungary

Re:

Post by PI »

Greatness! :D Better than ever:

Worst FPS: 470
Best FPS: 520

Now it simply outperforms my HW. With HW, it was at around 320 FPS.

But you should also check if the object is in the view fustum!

Another idea:
How about checking if the selected triangles are actually in/out of the screen?

Good work, keep it up! :)

Cheers,
PI
Mirror
Posts: 218
Joined: Sat Dec 01, 2007 4:09 pm

Re:

Post by Mirror »

PI wrote:Greatness! :D Better than ever:

Worst FPS: 470
Best FPS: 520

Now it simply outperforms my HW. With HW, it was at around 320 FPS.

But you should also check if the object is in the view fustum!

Another idea:
How about checking if the selected triangles are actually in/out of the screen?

Good work, keep it up! :)

Cheers,
PI
that's what OctTreeSceneNode does :D so this is the reason that if this will be ever integrated in irrlicht it must have as input, octtreescenenode's output.
Mirror
Posts: 218
Joined: Sat Dec 01, 2007 4:09 pm

Post by Mirror »

So here goes the final code. the variables declaration is a little messy :)

Code: Select all

#include "stdafx.h"
#include "time.h"
#include <irrlicht.h>

using namespace std;
 
using namespace irr;
 
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
#pragma comment(lib, "Irrlicht.lib")
//#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup") 
 
int main(int argc, char *argv[])
{
	IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D9, dimension2d<s32>(1024, 768), 32, true, true, false);
	if ( device == 0 ) return 1;
 
	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	IGUIEnvironment* guienv = device->getGUIEnvironment();
 
	driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);

	IGUIStaticText* fpstext = guienv->addStaticText(L"", rect<s32>(0,0,700,15), true, false, 0, -1, true);
 
	IGUIFont* font = guienv->getFont("fonthaettenschweiler.bmp");
	IGUISkin* skin = guienv->getSkin();
	if (font) skin->setFont(font);

 	scene::ICameraSceneNode* MMOCam = smgr->addCameraSceneNodeFPS(0,100,20,-1,0,0,0,100);
 
	MMOCam->setFarValue(1000000.0f);
	MMOCam->setNearValue(0.1f);
	MMOCam->setPosition(core::vector3df(0,120,0));
	MMOCam->setTarget(core::vector3df(0,100,100));


	scene::IAnimatedMesh* terrmesh1 = smgr->getMesh("sphere.obj");

	CMeshBuffer<S3DVertex>* buffer=(CMeshBuffer<S3DVertex>*)terrmesh1->getMeshBuffer(0); 
	printf("Vertex Count: %u\n",buffer->getVertexCount());
	printf("Index Count: %u\n\n",buffer->getIndexCount());
	printf("Total Triangles Count: %u\n\n",buffer->getIndexCount()/3);

	u16* indices = buffer->getIndices();
	void* vertices = buffer->getVertices();
	S3DVertex* vertex = (S3DVertex *) vertices;
	s32 indexc = buffer->getIndexCount();
	u16* indicesc = (u16* )malloc(sizeof(short int)*buffer->getIndexCount());
	vector3df* normals = (vector3df *)malloc(sizeof(vector3df)*buffer->getIndexCount()/3);
	vector3df* vertpnt = (vector3df *)malloc(sizeof(vector3df)*buffer->getIndexCount()/3);
	triangle3df poly;

	//precalculated faces normals and precalculated 1 point of intersection: normals/vertpnt
	memcpy(indicesc, indices, sizeof(short int)*buffer->getIndexCount());
	for(s32 i=0;i<indexc;i+=3) {
		poly.pointA = vertex[indicesc[i]].Pos;
		poly.pointB = vertex[indicesc[i+1]].Pos;
		poly.pointC = vertex[indicesc[i+2]].Pos;
		normals[i/3] = poly.getNormal().normalize();
		vertpnt[i/3] = vertex[indicesc[i]].Pos;
		//printf("%d",indicesc[i]);
		//printf(" %d",indicesc[i+1]);
		//printf(" %d\n",indicesc[i+2]);
	}

	video::SMaterial material;
	material.Lighting=false;
	material.Wireframe=true;
	material.BackfaceCulling=false;
	//ITexture* texture = driver->getTexture("world.topo.200408.3x5400x2700.jpg");
	//material.setTexture(0, texture);

	scene::ILightSceneNode* light1 = smgr->addLightSceneNode(0,vector3df(0,500,0),video::SColorf(1.0f,1.0f,1.0f,0.0f),10000,-1);

	int m=0,k=0;

	u32 t1,t2,dt=0;

/*	//uncomment this and comment out PerFaceCulling to test performance 
	scene::ISceneNode* terrnode1;
	//scene::ISceneNode* terrnode1 = smgr->addAnimatedMeshSceneNode(terrmesh1);
	scene::IMesh *mesh = terrmesh1->getMesh(0);
	mesh->getMeshBuffer(0)->setHardwareMappingHint(scene::EHM_STATIC);
    terrnode1 = smgr->addMeshSceneNode(mesh);

	//terrnode1->setMaterialTexture(0, driver->getTexture("world.topo.200408.3x5400x2700.jpg"));
	terrnode1->setMaterialFlag(video::EMF_WIREFRAME, false);
	terrnode1->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false);
	terrnode1->setMaterialFlag(video::EMF_LIGHTING, false);
	terrnode1->setPosition(core::vector3df(0,0,0));
	terrnode1->setVisible(true);
*/
	device->getCursorControl()->setVisible(false);
	vector3df campos, b;
	u32 c1,pos;
	stringw str;
	c1=0;
	pos=0;
	s32 i;
	indexc/=3;

	while(device->run())
	{
		str = L"FPS: ";str += driver->getFPS();
		str += " TRI:";str += driver->getPrimitiveCountDrawn();
		//comment out the following lines for better performance--start commenting
		//str += " Total Triangles: ";str += m;
		//str += " Visible Triangles: ";str += k;
		//str += " Not Visible Triangles: ";str += m-k;
		//str += " Index Count: ";str += k*3;
		//str += " dt:";str += dt;
		//--end commenting
		fpstext->setText(str.c_str());
		//m = k = 0;

		campos = MMOCam->getPosition();
		driver->setMaterial(material);
		driver->setTransform(video::ETS_WORLD, core::matrix4());

		driver->beginScene(true, true, 0);

// PER FACE CULLING - START

				driver->drawMeshBuffer(buffer);

				//t1 = device->getTimer()->getRealTime();
				buffer->Indices.erase(0, buffer->getIndexCount());
				//buffer->Indices.set_used(indexc);
				for(i=0;i<indexc;i++) {
					//m++;
					if ( normals[i].dotProduct(vertpnt[i] - campos ) < 0 ) {
						//buffer->Indices.push_back(indicesc[i*3]);
						//buffer->Indices.push_back(indicesc[i*3+1]);
						//buffer->Indices.push_back(indicesc[i*3+2]);
						//k++;
						c1++;
					}
					else {
						if (c1!=0) {
							c1*=3;
							pos+=c1;
							buffer->Indices.set_used(pos);
							memcpy(&indices[pos-c1], &indicesc[i*3-c1], c1*2);
							c1=0;
						}
					}
				}
				buffer->Indices.set_used(pos);
				pos=0;

				//t2 = device->getTimer()->getRealTime();
				//dt=t2-t1;
				//printf("%d\n",dt);

// PER FACE CULLING - END

			smgr->drawAll();
			guienv->drawAll();
		driver->endScene();
	}
	device->drop();
	return 0;
the implementation for meshes with more than 1 meshbuffer is left as an excercise to the reader :P
jeromegz
Posts: 14
Joined: Sat Aug 02, 2008 10:51 am

Post by jeromegz »

SUPER !!! you can use my lod for make low poly distant planets , and do a fast complete solar system , like celestia : you can make a complete solar system with multiple lod .
http://irrlicht.sourceforge.net/phpBB2/ ... 595#231595

Image result by nvidia gforce6150 edt opengl
try to scale but it is a little complicate
the multiple material :

Code: Select all

ITexture* texture = driver->getTexture("ll2.bmp"); 
ITexture* texture2 = driver->getTexture("ll2.bmp"); 
	video::SMaterial material;
	material.Lighting=false;
	//material.Wireframe=true;
	material.BackfaceCulling=false;
material.setTexture(0, texture);
material.setTexture(1, texture2);
Last edited by jeromegz on Tue Aug 31, 2010 12:13 pm, edited 6 times in total.
Hello
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

I ran the examples and here are the results ( on my Nvidia GTS 250)

Image

Image
Not much of improvement but still Good Job :wink:
Working on game: Marrbles (Currently stopped).
jeromegz
Posts: 14
Joined: Sat Aug 02, 2008 10:51 am

Post by jeromegz »

yes , very good :)
Hello
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Post by REDDemon »

ehi this idea is great. Just think that normally there is only 1 render thread running inside one cpu. Expand that idea. use the multicore power for culling faces and send less triangles to modern GPU letting them more free time for adding per fragment and per vertex shading XD
evandromillian
Posts: 40
Joined: Wed Apr 01, 2009 11:45 am
Location: São Paulo - Brazil

Post by evandromillian »

Hey guys, have you tried using geometry shader?

In this stage you have access to all primitive's vertices, and then test it's normal. If the primitive is back-faced, you only don't output it to pipeline.

Another point is that whole process is executed on GPU, that is too much faster than CPU.

Follow the link: http://www2.imm.dtu.dk/visiondag/VD07/g ... l/Emil.ppt (slide 21 and 22)
Next generation for Irrlicht!!!!!
Post Reply