Jump to content

Leadwerks 5 beta Update

Josh

647 views

An update for Leadwerks 5 is now available.

The Vulkan data transfer system has been revised and is now simpler but uses more memory. Data is likely to be quadruple-buffered, but it's a fairly small amount of data and this isn't a big concern. 

I fixed a bad bug where multiple threads were accessing a global variable in the Mat4::GetQuaternion function. This fixes the object flashing glitch that was visible in previous builds.

The engine is updated to the latest version of Newton Dynamics and kinematic joints work correctly now. The upvector joint is removed and a plane joint has been added for 2D physics, but I don't think it will work yet. Object picking up is implemented in the player controller script.

I switched out the default scene with a new one using some of @TWahl 's materials.

Added an FPSWeapon script that loads a gun and makes it sway.

Entity::AddScript() can now be called in the Start() function of another script with no problems.

Fullscreen windows are now working.

The window / display system is changed a bit. New display commands:

std::vector<shared_ptr<Display> > ListDisplays()
std::vector<iVec2> Display::GraphicsModes()

You must pass a display object in the window creation command now. Here's how I do it in Lua:

--Get the primary display
local displaylist = ListDisplays()
local display = displaylist[1];

--Get the display's highest resolution graphics mode
gfxmodes = display:GraphicsModes()
gfx = gfxmodes[#gfxmodes]

--Create a window
local fullscreenmode = false
local window
if fullscreenmode then
	window = CreateWindow(display, "My Game", 0, 0, gfx.x, gfx.y, WINDOW_FULLSCREEN)
else
	window = CreateWindow(display, "My Game", 0, 0, 1280 * display.scale.x, 720 * display.scale.y, WINDOW_CENTER + WINDOW_TITLEBAR)
end

And in C++:

	const bool fullscreenmode = false;

	//Get the primary display
	auto displays = ListDisplays();
	auto display = displays[0];

	//Create a window
	shared_ptr<Window> window;
	if (fullscreenmode)
	{
		auto gfxmodes = display->GraphicsModes();
		auto gfx = gfxmodes[gfxmodes.size() - 1];
		window = CreateWindow(display, L"My Game", 0, 0, gfx.x, gfx.y, WINDOW_FULLSCREEN);
	}
	else
	{
		Vec2 displayscale = display->GetScale();
		window = CreateWindow(display, L"My Game", 0, 0, 1280 * displayscale.x, 720 * displayscale.y, WINDOW_TITLEBAR | WINDOW_RESIZABLE | WINDOW_CENTER);
	}

The speed of the point light shadow updating is unbelievably fast. Point light shadows in Leadwerks 4 are very expensive to update because they require six different render passes for each of the six cubemap faces, but in Leadwerks 5 beta with Vulkan they are basically free. I'm sure it will slow down if I add enough points lights and have them all constantly updating, but I don't see any difference at all in the framerate right now when shadows are active. If you are having any trouble with their appearance you can set the global variable MULTIPASS_CUBEMAP to false in C++ at the very beginning of your program.

Untitled.thumb.jpg.81b687dbb6bfa7d1664ac108ae157d85.jpg

This script can be used to display performance statistics. At this time it only shows the framerate but I can expand on this in the future.

function Script:Start()
	self.statsEnabled = true
	self.textcache = {}
	self.font = LoadFont("Fonts/arial.ttf")
	self.fontsize = 16
	self.textalignment = TEXT_LEFT
	self.world:EnableStats(self.statsEnabled)
	self:BindKey(KEY_F11, self.ToggleStats)
end

function Script:ToggleStats()
	self.statsEnabled = not self.statsEnabled
	self.world:EnableStats(self.statsEnabled)
end

function Script:Update()

	--Return if disabled or font missing
	if self.statsEnabled == false or self.font == nil then return end

	--Hide previously used sprite
	if self.displayfps ~= nil then self.displayfps:Hide() end

	--Retrieve the framerate and convert to string
	--Convert to integer to limit the amount of different string values
	local fps = tostring(math.ceil(self.world.renderstats.framerate - 0.5)).." FPS"

	--Check for cached version and create it if it doesn't exist
	if self.textcache[fps] == nil then
		self.textcache[fps] = CreateText(self.world, self.font, fps, self.fontsize, self.textalignment, 1)
		self.textcache[fps]:SetPosition(4,4)
		self.textcache[fps]:SetColor(0,1,0,0.75)
	end

	--Set current sprite and show
	self.displayfps = self.textcache[fps]
	self.displayfps:Show()

end

It may seem like a lot of code just to draw a bit of text onscreen, but the benefit is extreme performance. Instead of drawing one character at a time like the Leadwerks renderer does, this creates persistent text objects and reuses them when needed. That cuts the performance cost of displaying text down to basically zero, making it great for complex GUIs and game interfaces.

  • Like 7


7 Comments


Recommended Comments

It also seems like the startup speed is much much faster now. I figured out that vkCreateInstance() and the vkGetExtensions() command (I can't remember the name right now) each take about one second, and the startup time total is about two seconds and you're in the game.

If you were loading a larger scene that took more time to load, you could kick off the rendering thread by calling World::Render() immediately after it is created, before the scene is loaded. This would cause the Vulkan initialization to be processed on the rendering thread while the scene is loading on the main thread. This would save the ~2 seconds of rendering initialization time, because it seems like the rest is pretty much instantaneous.

  • Like 3
Link to comment
33 minutes ago, Josh said:

If you were loading a larger scene that took more time to load, you could kick off the rendering thread by calling World::Render() immediately after it is created, before the scene is loaded. This would cause the Vulkan initialization to be processed on the rendering thread while the scene is loading on the main thread. This would save the ~2 seconds of rendering initialization time, because it seems like the rest is pretty much instantaneous.

God I hope this is a tip in one of the new tutorials (maybe in an optimization one) because I'm sure I'll forget this.

Link to comment

Are you using some fancy new technology like MVR or one of its predecessors for the single pass point-lights? If so, have you also evaluated, what happens on older GPUs?

  • Thanks 1
Link to comment
26 minutes ago, Ma-Shell said:

Are you using some fancy new technology like MVR or one of its predecessors for the single pass point-lights? If so, have you also evaluated, what happens on older GPUs?

Yes, it is core in Vulkan 1.1, with a minimum of six passes supported.

Link to comment

Although looking at their discussion, I would NOT use this for cascaded shadow mapping. The near stage will have far fewer objects in view than the further ones, and the extra geometry would have a much bigger impact than the savings of multiview rendering.

Link to comment
Guest
Add a comment...

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

×
×
  • Create New...