Jump to content

Decals Bug Demo


franck22000
 Share

Recommended Posts

I made a clean demo to show the decals performance bug to Josh, so i hope it will be finally fixed in the next update since im fighting for weeks for it :)

 

Please post your reports and the amount of FPS drop you have.

Everything is explained in the demo.

 

Posted in the bugtracker here: http://www.leadwerks.com/werkspace/tracker/issue-209-decal-performances-problem/

 

DOWNLOAD:

 

 

 

post-16-0-62024300-1316031349_thumb.png

 

post-16-0-65856700-1316031363_thumb.png

 

 

SOURCE CODE

 

#include "engine.h"
#include <iostream>
#include <string>

const int 	ScreenWidth = 800;
const int 	ScreenHeight = 600;
const char* AppTitle = "Decals Demo";

void ErrOut( const std::string& message ) { std::cerr << message << std::endl; }

//	-------------------------------
int main( int argn, char* argv[] )
{
// Initialize
if( !Initialize() )
	return 1;        
SetAppTitle( AppTitle ) ;

// Set graphics mode        
if( !Graphics(ScreenWidth,ScreenHeight) )
{                
	ErrOut( "Failed to set graphics mode."  );
	return 1;        
}

// Create framework object and set it to a global object so other scripts can access it
TFramework fw = CreateFramework();        
if( fw == NULL )        
{
	ErrOut( "Failed to initialize engine." );                
	return 1;        
}        

// Set Lua framework object        
SetGlobalObject( "fw", fw );                

// Set Lua framework variable        
BP lua = GetLuaState();        
lua_pushobject( lua, fw );        
lua_setglobal( lua, "fw" );        
lua_pop( lua, 1 );        

// Get framework main camera        
TCamera camera = GetLayerCamera( GetFrameworkLayer(0) );        
PositionEntity( camera, Vec3(0,0,-2) );        

// Create cube
TMaterial material = LoadMaterial( "abstract::cobblestones.mat" );        
TMesh mesh = CreateCube();        
PaintEntity( mesh, material );        

// Create ground
TMesh ground = CreateCube();        
ScaleEntity( ground, Vec3(10,1,10) );        
PositionEntity( ground, Vec3(0,-2,0) );        
PaintEntity( ground, material );        

// Add some light
TLight light = CreateDirectionalLight();        
RotateEntity( light, Vec3(45,45,45) );        

// Move the mouse cursor at the screen center and hide it
MoveMouse(GraphicsWidth()  / 2, GraphicsHeight() / 2);
HideMouse();

// Other Variables
TVec3 ViewCameraRotation = Vec3(0.0f,0.0f,0.0f);
float Move = 0.0f;
float Strafe = 0.0f;
float MouseForceX = 0.0f;
float MouseForceY = 0.0f;


// Spin cube until user hits Escape
while( !KeyHit() && !AppTerminate() )        
{                
	if( !AppSuspended() )
	{

		TurnEntity( mesh, Vec3( AppSpeed()*0.5f ) );     


		// DECAL CODE
		if (MouseHit(1))
		{

			TPick _Picked;

			if (CameraPick( &_Picked, camera, Vec3(GraphicsWidth() / 2, GraphicsHeight() / 2, 100), 0.0f))
			{

				if (_Picked.entity != NULL)
				{

					TMesh _Decal = CreateDecal(_Picked.surface, TFormPoint(Vec3(_Picked.X, _Picked.Y, _Picked.Z), NULL, _Picked.entity), 0.020f);

					EntityParent(_Decal , _Picked.entity, 0);
					PaintEntity(_Decal , LoadMaterial("abstract::bullethole.mat"));

					AddMesh(_Decal , _Picked.entity);
					UpdateMesh(_Decal);

				}

			}

		 }


		// CAMERA MOVEMENT CODE
		Move = 	(KeyDown(KEY_UP)-KeyDown(KEY_DOWN)) * 0.1f; 
		Strafe =	(KeyDown(KEY_RIGHT)-KeyDown(KEY_LEFT)) * 0.1f; 

		MouseForceX = Curve( MouseX() - GraphicsWidth() / 2.0f, MouseForceX, 2.0); 
		MouseForceY = Curve( MouseY() - GraphicsHeight() / 2.0f, MouseForceY, 2.0);

		LE::MoveMouse(GraphicsWidth()  / 2, GraphicsHeight() / 2);

		ViewCameraRotation.X = ViewCameraRotation.X + MouseForceY / 8.0; 
		ViewCameraRotation.Y = ViewCameraRotation.Y - MouseForceX / 8.0;

		RotateEntity(camera, ViewCameraRotation);
		MoveEntity(camera, Vec3 (Strafe*AppSpeed(), 0 , Move*AppSpeed()));


		// Update FrameWork
		UpdateFramework();                
		RenderFramework();                


		// TEXT
		SetBlend(BLEND_ALPHA);
		DrawText(1,15,"Move with arrowkeys, press mouseclick to drop a decal");
		DrawText(1,30,"Put something like 20 decals on a surface and move the camera close to this surface to see the FPS drop.");
		DrawText(1,45,"Then move the camera far from the surface to see the FPS getting back to a normal level.");

		SetBlend(BLEND_NONE);

		Flip( 0 );        
	}
}                

return Terminate();
}

You guys are going to be the death of me. Josh
Link to comment
Share on other sites

I have 805fps without decals and i loose like 30fps with each of the 10 first decals.

With 50 decals there are ~200fps left.

With 200 decals i have ~50fps left.

 

I tried it two times, once with all decals on the cube and once with all decals on the floor. Both tests had about the same results.

 

On my system there is no additional fps impact when i get closer to the decals.

(Win7 64bit) && (i7 3770K @ 3,5ghz) && (16gb DDR3 @ 1600mhz) && (Geforce660TI)

Link to comment
Share on other sites

..im really puzzled whats causing such massive FPS drop considering that decals are mostly instanced (it should be)..im not using any decals myself (not LE based), but constant requests from people here, makes me curious about it so i did some tests and yes..it appears to be real FPS killer..tested decals on other renderers and it appears to be no FPS impact with hundreds of them on scene...

 

Link to comment
Share on other sites

Same basic findings here. I added the stats to the program and the draw time was approaching 21mS when I had 100 decals on the screen. This decreases as you move away from the decals and increases again as you aproach them.

Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++

Link to comment
Share on other sites

I've been wondering whether it was Lua causing this issue.. guess I was wrong. Seems that decals cause quite an FPS delay.

 

(No decals)

190FPS - Looking at floor (why lower...?)

209FPS - Looking at cube

236FPS - Looking upwards

 

(3 Surfaces, 15 decals each)

135FPS - One surface visible

156FPS - Looking from opposite side (no decals visible)

65FPS - Close to one surface

 

(25+ decals on floor entity)

25FPS - Waaay slow

Link to comment
Share on other sites

i think the biggest problem with decals has always been the the fact that you have to create a new decal every time, instead of being able to copy from an existing decal... and with the way the command works you have to use it that way to get the benefit of how it wraps correctly onto a surface...

 

I can simulate a similar drop in FPS (granted not as large) by creating a plane each pick and placing it at the pick location... but if I create the plane beforehand and then just create copies of it, the effect on fps is negligible...

 

require("scripts/constants/engine_const")
require("scripts/math/math")
RegisterAbstractPath("")        
Graphics(800,600)        
fw=CreateFramework()        
fw.main.camera:SetPosition(Vec3(0,0,-2))
material=LoadMaterial("abstract::cobblestones.mat")
mesh=CreateCube()
mesh:Paint(material)

ground=CreateCube()
ground:SetScalef(10.0,1.0,10.0)
ground:SetPositionf(0.0,-2.0,0.0)
ground:Paint(material)

light=CreateDirectionalLight()
light:SetRotationf(45,45,45)

decal = CreatePlane()
decalmaterial = LoadMaterial("abstract::bullethole.mat")
decal:SetScale(Vec3(.0625,.0625,.0625))
decal:Paint(decalmaterial,1)
decal:Hide()
counter = 0

HideMouse()
gx = Round(GraphicsWidth()/2)
gy = Round(GraphicsHeight()/2) 
while KeyHit(KEY_ESCAPE)==0 do  
mesh:Turn(Vec3(AppSpeed()*0.5,AppSpeed()*0.5,AppSpeed()*0.5))
       move = Curve((KeyDown(KEY_W)-KeyDown(KEY_S)),move,3/AppSpeed())        
       strafe = Curve((KeyDown(KEY_D)-KeyDown(KEY_A)),strafe,3/AppSpeed())      
       fw.main.camera:Move(Vec3(strafe/15,0,move/15))
fw.main.camera:Point(mesh,3,1)

MoveMouse(gx,gy)
if MouseHit(1)==1 then
	local pick = CameraPick(fw.main.camera,Vec3(gx,gy,100),0,0)
	if pick~=nil then 
		--'this creates a new plane each pick
		--[[decal = CreatePlane()
		decalmaterial = LoadMaterial("abstract::bullethole.mat")
		decal:SetScale(Vec3(.0625,.0625,.0625))
		decal:Paint(decalmaterial,1)
		decal:SetParent(pick.entity)
		decal:SetPosition(pick.position,1)
		AlignToVector(decal,pick.normal,2,1)]]--'

		--'this creates a copy of previous plane each pick'
		local shot = decal:Copy(1)
		shot:Show()
		shot:SetParent(pick.entity)
		shot:SetPosition(pick.position,1)
		AlignToVector(shot,pick.normal,2,1)
		counter = counter + 1
	end
end

fw:Update()
fw:Render()
SetBlend(1)
DrawText("Number of 'decals': "..counter,0,20)
DrawText("Use WSAD to move camera",0,40)
       DrawText("Left-Click to apply 'decal'",0,60)
SetBlend(0)
collectgarbage(collect)
Flip()
end
ShowMouse()

 

but with the way the command works now I dont know how you could get the wrap effect by creating a copy...

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

I'm not programmer, but can wee move a decal ?

In that case you could gain an improvment by creating a stock of decals , then move them to the position you want, or move them far from the sceen if you don't use them ?

or make them invisible ?

 

So i think by limiting the number of decals simultanoues at screen would be a way !

Another way would be to activate only decals when they are near (for example decals used for tree shadows or dynamic "faked" lightmap, or whatever !

Stop toying and make games

Link to comment
Share on other sites

also, the fps drop when getting close to a textured surface is a separate issue from decals... you can see a large fps drop just by moving close to the spinning cube in both of our examples even without creating a single decal...

Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590

LE / 3DWS / BMX / Hexagon

macklebee's channel

Link to comment
Share on other sites

  • 3 months later...

Interestingly, whilst playing Skyrim the other day I experimented with decals by scorching the path in front of me. I was able to literally put down over 500 decals before I got bored of doing so with seemingly no noticeable reduction in frame speed. Why is it so low cost in their engine and so high cost in ours?

Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++

Link to comment
Share on other sites

Josh said that it was not a bug... it's due to the alpha calculation, but i dont think it would be so an FPS killer calculation... Maybe one day we will be able to use decals :)

Could there be a better way to implement the alpha calculation like layered rendering, instancing, etc? I believe this still should be fixed.

 

 

Interestingly, whilst playing Skyrim the other day I experimented with decals by scorching the path in front of me. I was able to literally put down over 500 decals before I got bored of doing so with seemingly no noticeable reduction in frame speed. Why is it so low cost in their engine and so high cost in ours?

Exactly. Several other game engines both commercial and indie, somehow have solved this conundrum. I can unload hundreds of decals onto a wall within Valve's Source engine, Cryengine, and many others. So how did they solve this problem?

 

Speaking of Skyrim, take a look at just the town of Whiterun. Within 2 minutes I lost count (100+) at the amount of decals placed on several dozen meshes.

 

Decals provide a huge boost in the content pipeline, and it would be great to have them updated. Is there a way to instance decals, or use a method similar method close to how other engines (like Overgowth) manage to accomplish this?

Link to comment
Share on other sites

+1 ... whilst I appreciate you probably don't want to start redesigning elements of LE2 Josh; it would be nice to see a better solution for this as it's currently far too restrictive.

Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++

Link to comment
Share on other sites

Decals aren't planes. They are random unique collections of triangles extracted from a mesh. They will wrap around the edges of meshes, and conform to 3D surfaces. They are not instanced because their geometry is very unpredictable. Unless a shot is fired in the exact same position, the texture coordinates will be different.

 

If all you want is a simple flat plane that does not wrap around edges, like the decals in Quake 3, use an instanced flat plane oriented to the normal of the hit triangle. I wouldn't be surprised if a lot of games use this, and just rely on people not noticing the inaccuracy.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

  • 3 weeks later...

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...