Jump to content
  • entries
    941
  • comments
    5,894
  • views
    867,967

About this blog

Learn about game development technology

Entries in this blog

Leadwerks 5 beta 2D Redux

Previously, we saw how the new renderer can combine multiple cameras and even multiple worlds in a single render to combine 3D and 2D graphics. During the process of implementing Z-sorting for multiple layers of transparency, I found that Vulkan does in fact respect rasterization order. That is, objects are in fact drawn in the same order you provide draw calls to a command buffer. Furthermore, individual primitives (polygons) are also rendered in the order they are stored in the indice b

Josh

Josh

Multipass Rendering in Leadwerks 5 beta

Current generation graphics hardware only supports up to a 32-bit floating point depth buffer, and that isn't adequate for large-scale rendering because there isn't enough precision to make objects appear in the correct order and prevent z-fighting. After trying out a few different approaches I found that the best way to support large-scale rendering is to allow the user to create several cameras. The first camera should have a range of 0.1-1000 meters, the second would use the same n

Josh

Josh

Leadwerks 5 beta Update

A big update is now available for beta subscribers! Multipass Rendering You can use several cameras to increase the depth range or mix 2D and 3D graphics. 2D Graphics As discussed earlier, 2D graphics are now supported using persistent 2D objects. Depth Sorting Multiple layers of transparency will now render in correct order, with lighting in each layer. Note that I used an empty script called "null.lua" to prevent the glass surfaces here from being collapsed at loa

Josh

Josh

Joint Class Finished

I'm happy to say the physics joint class in the new engine is completed. I made all the members that are not meant to be accessed private. One interesting part is the parent and child public members, which are constant pointers to private members. This should result in a read-only member in C++. A sol property is used to expose this to Lua in a read-only manner. The upvector joint will align an object's Y axis to any vector you set, but still allow rotation around the axis. This is perfect

Josh

Josh

GLTF Loader Update

The following changes have been made to the GLTF model loader: Correctly loaded rotations and orientations. Mesh collision caching for faster loading. Supports transforms with negative scale and correct face orientation. Support for adjustable alpha cutoff value. Support for KHR_materials_unlit extension (full bright materials). This model from SketchFab was useful for testing because it uses so many features of the GLTF format: https://sketchfab.com/

Josh

Josh

GLTF Loading Speed

There are two aspects of GLTF files that have non-optimal loading speed. First, the vertex data is not stored in the same exact layout and format as our vertex structure. I found the difference in performance for this was pretty small, even for large models, so I was willing to let it go. Tangents can take a bit longer to build, but those are usually included in the model if they are needed. The second issue is the triangle tree structure which is used for raycasting (the pick commands). I

Josh

Josh

2D Drawing in Leadwerks 5 beta

Previously I described how multiple cameras can be combined in the new renderer to create an unlimited depth buffer. That discussion lead into multi-world rendering and 2D drawing. Surprisingly, there is a lot of overlap in these features, and it makes sense to solve all of it at one time. Old 2D rendering systems are designed around the idea of storing a hierarchy of state changes. The renderer would crawl through the hierarchy and perform commands as it went along, rendering all 2D elemen

Josh

Josh

Offroad Racing Game Template

I'm putting together ideas for a racing game template to add to Leadwerks. We already support vehicles. The challenge is to put together that looks and feels slick and professional, like a real game people want to play. The finished demo will be submitted to Greenlight, GameJolt, IndieDB, itch.io, etc.   Gameplay First, I wanted to think about what style of racing I want this to be. I don't want street racing because it's kind of boring, and the level design is more involved. I don't wan

Josh

Josh

Next Steps

Still a lot of things left to do. Now that I have very large-scale rendering working, people want to fill it up with very big terrains. A special system will be required to handle this, which adds another layer to the terrain system. Also, I want to resume work on the voxel GI system, as I feel these results are much better than the performance penalty of ray-tracing. There are a few odds and ends like AI navigation and cascaded shadow maps to finish up. I am planning to have the engine mor

Josh

Josh

Message Boxes

If were a user of BlitzMax in the past, you will love these convenience commands in Turbo Engine: int Notify(const std::wstring& title, const std::wstring& message, shared_ptr<Window> window = nullptr, const int icon = 0) int Confirm(const std::wstring& title, const std::wstring& message, shared_ptr<Window> window = nullptr, const int icon = 0) int Proceed(const std::wstring& title, const std::wstring& message, shared_ptr<Window> window = nullptr, co

Josh

Josh

Multi-monitor Support

New commands in Turbo Engine will add better support for multiple monitors. The new Display class lets you iterate through all your monitors: for (int n = 0; n < CountDisplays(); ++n) { auto display = GetDisplay(n); Print(display->GetPosition()); //monitor XY coordinates Print(display->GetSize()); //monitor size Print(display->GetScale()); //DPI scaling } The CreateWindow() function now takes a parameter for the monitor to create the window on / relative to. auto displ

Josh

Josh

Leadwerks 5 beta Mega Update

A huge update is available for Turbo Engine Beta. Hardware tessellation adds geometric detail to your models and smooths out sharp corners. The new terrain system is live, with fast performance, displacement, and support for up to 255 material layers. Plugins are now working, with sample code for loading MD3 models and VTF textures. Shader families eliminate the need to specify a lot of different shaders in a material file. Support for multiple monitors and be

Josh

Josh

Terrain in Leadwerks 5

I wanted to work on something a bit easier before going back into voxel ray tracing, which is another difficult problem. "Something easier" was terrain, and it ended up consuming the entire month of August, but I think you will agree it was worthwhile. In Leadwerks Game Engine, I used clipmaps to pre-render the terrain around the camera to a series of cascading textures. You can read about the implementation here: This worked very well with the hardware we had available at the time, b

Josh

Josh

Texture Load Plugins

Texture loading plugins allow us to move some big libraries like FreeImage into separate optional plugins, and it also allows you to write plugins to load new texture and image formats. To demonstrate the feature, I have added a working VTF plugin to the GMF2 SDK. This plugin will load Valve texture files used in Source Engine games like Half-Life 2 and Portal. Here are the results, showing a texture loaded directly from VTF format and also displayed in Nem’s nifty VTFEdit tool.

Josh

Josh

Terrain Normal Update Multithreading

Multithreading is very useful for processes that can be split into a lot of parallel parts, like image and video processing. I wanted to speed up the normal updating for the new terrain system so I added a new thread creation function that accepts any function as the input, so I can use std::bind with it, the same way I have been easily using this to send instructions in between threads: shared_ptr<Thread> CreateThread(std::function<void()> instruction); The terrain update nor

Josh

Josh

Precomputed BSP Trees and Static Meshes

The GMF2 data format gives us fine control to enable fast load times. Vertex and indice data is stored in the exact same format the GPU uses so everything is read straight into video memory. There are some other optimizations I have wanted to make for a long time, and our use of big CAD models makes this a perfect time to implement these improvements. Precomputed BSP Trees For raycast (pick) operations, a BSP structure needs to be constructed from the mesh data. In Leadwerks Engine thi

Josh

Josh

Compressed Vertex Arrays

My work with the MD3 format and its funny short vertex positions made me think about vertex array sizes. (Interestingly, the Quake 2 MD2 format uses a single char for vertex positions!) Smaller vertex formats run faster, so it made sense to look into this. Here was our vertex format before, weighing in at 72 bytes: struct Vertex { Vec3 position; float displacement; Vec3 normal; Vec2 texcoords[2]; Vec4 tangent; unsigned char color[4]; unsigned char boneweights[4]; unsigned char b

Josh

Josh

GMF2 SDK Update

The GMF2 SDK has been updated with tangents and bounds calculation, object colors, and save-to-file functionality. The GMF2 SDK is a lightweight engine-agnostic open-source toolkit for loading and saving of game models. The GMF2 format can work as a standalone file format or simply as a data format for import and export plugins. This gives us a protocol we can pull model data into and export model data from, and a format that loads large data much faster than alternative file formats.

Josh

Josh

GMF2, Plugins, and Modding

I wanted to get a working example of the plugin system together. One thing led to another, and...well, this is going to be a very different blog. GMF2 The first thing I had to do is figure out a way for plugins to communicate with the main program. I considered using a structure they both share in memory, but those always inevitably get out of sync when either the structure changes or there is a small difference between the compilers used for the program and DLL. This scared me so I we

Josh

Josh

Using Multiple Entity Scripts in Turbo Game Engine

During development of Leadwerks Game Engine, there was some debate on whether we should allow multiple scripts per entity or just associate a single script with an entity. My first iteration of the scripting system actually used multiple scripts, but after using it to develop the Darkness Awaits example I saw a lot of problems with this. Each script used a different classname to store its variables and functions in, so you ended up with code like this: function Script:HurtEnemy(amount) if s

Josh

Josh

Tessellation in Action

With tessellation now fully implemented, I was very curious to see how it would perform when applied to arbitrary models. With tessellation, vertices act like control points for a Bezier mesh that is subdivided dynamically in screen space. Could tessellation be used to add new details to any low-poly model? Here is a low-res character model with a pointy head and obvious sharp edges all around his silhouette: When tessellation is enabled, the sharp edges go away and the mes

Josh

Josh

Vulkan Tessellation Made Practical

Now that I have all the Vulkan knowledge I need, and most work is being done with GLSL shader code, development is moving faster. Before starting voxel ray tracing, another hard problem, I decided to work one some *relatively* easier things for a few days. I want tessellation to be an every day feature in the new engine, so I decided to work out a useful implementation of it. While there are a ton of examples out there showing how to split a triangle up into smaller triangles, useful discus

Josh

Josh

Single-file SPIR-V shaders for Vulkan

It is now possible to compile shaders into a single self-contained file that can loaded by any Vulkan program, but it's not obvious how this is done. After poking around for a while I found all the pieces I needed to put this together. Compiling First, you need to compile each shader stage from a source code file into a precompiled SPIR-V file. There are several tools available to do this, but I prefer GLSlangValidator because it supports the Google #include extension. Put your vertex

Josh

Josh

Three improvements I made to Leadwerks Game Engine 5 today

First, I was experiencing some crashes due to race conditions. These are very very bad, and very hard to track down. The problems were being caused by reuse of thread returned objects. Basically, a thread performs some tasks, returns an object with all the processed data, and then once the parent thread is done with that data it is returned to a pool of objects available for the thread to use. This is pretty complicated, and I found that when I switched to just creating a new return object each

Josh

Josh

Getting Started with Vulkan

The latest design of my OpenGL renderer using bindless textures has some problems, and although these can be resolved, I think I have hit the limit on how useful an initial OpenGL implementation will be for the new engine. I decided it was time to dive into the Vulkan API. This is sort of scary, because I feel like it sets me back quite a lot, but at the same time the work I do with this will carry forward much better. A Vulkan-based renderer can run on Windows, Linux, Mac, iOS, Android, PS4, an

Josh

Josh

×
×
  • Create New...