Jump to content

Three improvements I made to Leadwerks Game Engine 5 today

Josh

2,481 views

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 time the thread runs, the speed was the same as before. So the system is nice and stable now. I tend to be very careful about sharing data between threads and only doing it in a prescribed manner (through a command buffer and using separate objects) and I will continue to use this approach.

Second, I added a built-in mouselook mode for cameras. You can call Camera::SetFreeLook(true) and get a automatic mouse controls that make the camera look around. I am not doing this to make things easier, I am doing it because it allows fast snappy mouse looking even if your game is running at a lower frequency. So you can run your game at 30 hz, giving you 33 milliseconds for all your game code to complete, but it will feel like 60+ hz because the mouse will update in the rendering thread, which is running at a faster speed. The same idea will be used to eliminate head movement latency in VR.

Finally, I switched the instance indexes that are uploaded to the GPU from integers to 16-bit unsigned shorts. You can still have up to 131072 instances of a single object, because the engine will store instances above and below 65536 in two separate batches, and then send an integer to the shader to add to the instance index. Again, this is an example of a hard limit I am putting in place in order to make a more structured and faster performing engine, but it seems like the constraints I am setting so far are unlikely to even be noticed.

Animation is working great, and performance is just as fast as before I started adding it, so things are looking good. Here's a funny picture of me trying to add things to the renderer to slow it down and failing :D:

Image1.thumb.jpg.1d49aa6bb1e108e1784c0f2964ab1036.jpg

I'm not sure what I will tackle next. I could work on threading the physics and AI, spend some time exploring new graphics options, or implement lighting so that we have a basic usable version of Leadwerks 5 for indoors games. What would you like to see next in the Leadwerks Game Engine 5 Alpha?

  • Sad 1


29 Comments


Recommended Comments



5 hours ago, gamecreator said:

Same.  Curious if we'll be able to do something like this again: https://www.youtube.com/watch?v=V4uh5j4BM7w

I don't understand. What does that video do that you can't do right now?

11 hours ago, tournamentdan said:

Have you decided to move forward to PBR?

I've looked into it, and here is what "PBR" means:

  • A texture lookup is used for light reflection instead of a dot product equation.
  • A cubemap is always in use, with mipmaps. The "roughness" value in a material or texture corresponds to the mip level to use in the cubemap lookup.
  • There's a user-adjustable value for the Fresnel reflection value.

As always, good art will look good and bad art will look bad.

9 hours ago, SpiderPig said:

I would like to see your approach to lighting.  Very interested to see how it effects performance.

Direct lighting will be the same as Leadwerks 4, although I might add some new light types. There's two approaches I could take with indirect lighting. One is to combine SSR and environment probes. This is what Doom 2016 does and it looks great. There are also some real-time GI techniques that are now becoming possible to do in realtime on high-end hardware. I am investigating this as well.

Share this comment


Link to comment
18 minutes ago, Josh said:

I don't understand. What does that video do that you can't do right now?

I don't think spotlights even work on vegetation now, do they?

Share this comment


Link to comment
10 minutes ago, gamecreator said:

I don't think spotlights even work on vegetation now, do they?

Ah, I see. Point and spotlight shadows are skipped on vegetation to save performance. The vegetation system is pretty heavy but is good at rendering millions of instances. I don't know if this will change, I have not thought about it really.

Share this comment


Link to comment
Quote

There are also some real-time GI techniques that are now becoming possible to do in realtime on high-end hardware. I am investigating this as well.

Looking forward to hearing more on this.

 

On the subject of lighting, are there techniques around that allow infinite distance shadow rendering?

Share this comment


Link to comment
5 hours ago, Josh said:

 

I've looked into it, and here is what "PBR" means:

  • A texture lookup is used for light reflection instead of a dot product equation.
  • A cubemap is always in use, with mipmaps. The "roughness" value in a material or texture corresponds to the mip level to use in the cubemap lookup.
  • There's a user-adjustable value for the Fresnel reflection value.

As always, good art will look good and bad art will look bad.

 

It also means that on the content creator side(for pbr). It is about a hundred times easier to create good art.

Share this comment


Link to comment
3 hours ago, SpiderPig said:

Looking forward to hearing more on this.

On the subject of lighting, are there techniques around that allow infinite distance shadow rendering?

Raytracing.

It also means that on the content creator side(for pbr). It is about a hundred times easier to create good art.

Do you have any materials you would like me to try?

Share this comment


Link to comment
23 minutes ago, Josh said:

 

 

25 minutes ago, Josh said:

Do you have any materials you would like me to try?

I am in Puerto Rico right now away from my computer. Let me head home and I can send you several.

Share this comment


Link to comment
17 hours ago, tournamentdan said:

Have you decided to move forward to PBR?

You are absolutely right. PBR is the nextgen rendering solution and it is more realistic than traditional rendering.

This is a nice page to compare them: https://warthunder.com/en/devblog/current/806 Slide the red line in the middle of the pictures below right and left to see the difference both them.

Share this comment


Link to comment
5 minutes ago, Berken said:

You are absolutely right. PBR is the nextgen rendering solution and it is more realistic than traditional rendering.

This is a nice page to compare them to: https://warthunder.com/en/devblog/current/806 Slide the red line in the middle of the pictures below right and left to see the difference both them.

Do you have any PBR materials you would like me to try?

Share this comment


Link to comment

For me PBR provides a standardised consistency regardless of lightning environment. I know my assets will look similar regardless of the 3d application/engine they are being rendered in.

Share this comment


Link to comment
13 minutes ago, Josh said:

Do you have any PBR materials you would like me to try?

You can try these materials. A brick and a rusted metal.

PBRs.rar

  • Thanks 1

Share this comment


Link to comment
57 minutes ago, Berken said:

You can try these materials. A brick and a rusted metal.

PBRs.rar

Do you have a BRDF for those?

Share this comment


Link to comment
6 hours ago, aiaf said:

Exploring new graphics options and more lights :)

I am looking into a CPU-based voxel GI system right now. This can be done on the GPU, but it has terrible framerates even on high-end hardware. If I dedicate a couple of CPU threads to this in the background they could just send the result to the GPU whenever they are finished. I think the performance in the GI update would be nice and fast with a sparse voxel octree but dynamic reflections might lag behind too much. I'm thinking if I cache static geometry and pre-rasterize all dynamic models, the updates should be pretty fast, but I don't really know until I try it. The GI update would be dealing with only voxel data after the first rasterization, and would not be re-rasterizing everything over and over each frame. I could store two GI data sets in the GPU and do a smooth transition between them as new updates are fed to the GPU.

I think the problem will parallelize well and we do have 18 core CPUs in existence today.

Also, rasterizing triangles on the GPU into a 3D texture is extremely complicated and uses a bunch of new techniques I have never used. This by itself is not a good reason not to do it, but I am not very eager to spend two weeks implementing that when I already know it is too slow for practical use.

Share this comment


Link to comment
2 minutes ago, martyj said:

When will we see textured models in the LE5 demos?

Bwahaha, someday. It's just not a priority right now. :D

Share this comment


Link to comment
9 hours ago, Josh said:

Ah, I see. Point and spotlight shadows are skipped on vegetation to save performance. The vegetation system is pretty heavy but is good at rendering millions of instances. I don't know if this will change, I have not thought about it really.

I understand that it would be a challenge.  I hope you're up for it.  :)

lantern_forest_by_retrolex.jpg

  • Like 1

Share this comment


Link to comment

Optimize lighting and shadows and fix/reduce shadow banding. 

LE5 is already better than LE4 due to it not slowing down after a few objects and skeletons. Looking forward to the final product.

Share this comment


Link to comment
23 hours ago, Josh said:

although I might add some new light types.

ooh! area lights please!

 

Share this comment


Link to comment

Lighting and materials are closely linked because the material needs some kind of ambient light to reflect. This can come in the form of a cubemap or global illumination.

I think I will pursue the GI thing and perhaps the next update to the library can have lighting with GI and PBR materials working. It won't include terrain, particles, sprites, GUI, etc. but it will be usable.

  • Like 2

Share this comment


Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

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.

  • Blog Entries

    • By Josh in Josh's Dev Blog 0
      Textures in Leadwerks don't actually store any pixel data in system memory. Instead the data is sent straight from the hard drive to the GPU and dumped from memory, because there is no reason to have all that data sitting around in RAM. However, I needed to implement texture saving for our terrain system so I implemented a simple "Pixmap" class for handling image data:
      class Pixmap : public SharedObject { VkFormat m_format; iVec2 m_size; shared_ptr<Buffer> m_pixels; int bpp; public: Pixmap(); const VkFormat& format; const iVec2& size; const shared_ptr<Buffer>& pixels; virtual shared_ptr<Pixmap> Copy(); virtual shared_ptr<Pixmap> Convert(const VkFormat format); virtual bool Save(const std::string& filename, const SaveFlags flags = SAVE_DEFAULT); virtual bool Save(shared_ptr<Stream>, const std::string& mimetype = "image/vnd-ms.dds", const SaveFlags flags = SAVE_DEFAULT); friend shared_ptr<Pixmap> CreatePixmap(const int, const int, const VkFormat, shared_ptr<Buffer> data); friend shared_ptr<Pixmap> LoadPixmap(const std::wstring&, const LoadFlags); }; shared_ptr<Pixmap> CreatePixmap(const int width, const int height, const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM, shared_ptr<Buffer> data = nullptr); shared_ptr<Pixmap> LoadPixmap(const std::wstring& path, const LoadFlags flags = LOAD_DEFAULT); You can convert a pixmap from one format to another in order to compress raw RGBA pixels into BCn compressed data. The supported conversion formats are very limited and are only being implemented as they are needed. Pixmaps can be saved as DDS files, and the same rules apply. Support for the most common formats is being added.
      As a result, the terrain system can now save out all processed images as DDS files. The modern DDS format supports a lot of pixel formats, so even heightmaps can be saved. All of these files can be easily viewed in Visual Studio itself. It's by far the most reliable DDS viewer, as even the built-in Windows preview function is missing support for DX10 formats. Unfortunately there's really no modern DDS viewer application like the old Windows Texture Viewer.

      Storing terrain data in an easy-to-open standard texture format will make development easier for you. I intend to eliminate all "black box" file formats so all your game data is always easily viewable in a variety of tools, right up until the final publish step.
    • By Josh in Josh's Dev Blog 1
      I wanted to see if any of the terrain data can be compressed down, mostly to reduce GPU memory usage. I implemented some fast texture compression algorithms for BC1, BC3, BC4, BC5, and BC7 compression. BC6 and BC7 are not terribly useful in this situation because they involve a complex lookup table, so data from different textures can't be mixed and matched. I found two areas where texture compression could be used, in alpha layers and normal maps. I implemented BC3 compression for terrain alpha and could not see any artifacts. The compression is very fast, always less than one second even with the biggest textures I would care to use (4096 x 4096).
      For normals, BC1 (DXT1 and BC3 (DXT5) produce artifacts: (I accidentally left tessellation turned on high in these shots, which is why the framerate is low):

      BC5 gives a better appearance on this bumpy area and closely matches the original uncompressed normals. BC5 takes 1 byte per pixel, one quarter the size of uncomompressed RGBA. However, it only supports two channels, so we need one texture for normals and another for tangents, leaving us with a total 50% reduced size.

      Here are the results:
      2048 x 2048 Uncompressed Terrain:
      Heightmap = 2048 * 2048 * 2 = 8388608 Normal / tangents map = 16777216 Secret sauce = 67108864 Secret sauce 2 = 16777216 Total = 104 MB 2048 x 2048 Compressed Terrain:
      Heightmap = 2048 * 2048 * 2 = 8388608 Normal map = 4194304 Tangents = 4194304 Secret sauce = 16777216 Secret sauce 2 = 16777216 Total = 48 MB Additionally, for editable terrain an extra 32 MB of data needs to be stored, but this can be dumped once the terrain is made static. There are other things you can do to reduce the file size but it would not change the memory usage, and processing time is very high for "super-compression" techniques. I investigated this thoroughly and found the best compression methods for this situation that are pretty much instantaneous with no noticeable loss of quality, so I am satisfied.
    • By jen in jen's Blog 0
      My small project will be called Foregate, it will be a dark medieval Diablo style single player action RPG.
      The graphics will be simple, no PBR, 256x256 map, reasonably low-res models.
      Camera style? Top-down-ish I think? Like in Diablo exactly - and because the camera is not directly in-front of the 3 models, I can get away with low-resolution assets - bonus. Also, with top-down view, I won't have to worry about high resolution sky-boxes. 
      What's my plan for this project?
      I plan to make this project as small and as simple as possible, possibly release it as open-source, and have fun with it of course.
      My previous experience with game development (1-2 years ago?) was amateurish I think, still is now. I want to give it a go again, this time with experience although my skill in C++ is not really that good? Maybe I can improve it in this project.
      More about the game
      The content is not set in stone yet but I have a general idea of how the mechanics is going to look and feel - Diablo-ish obviously. It'll have monsters (ancient & mythical probably), loot when killing a monster, gold as in-game currency, visual grid inventory, player stats (level, strength, agility, vitality, energy, &c.). 
      The game will be single-player. Possibly a coop multiplayer also? I don't have any interest in making massive multi-player. 
      I started my development yesterday with the basic preparations (setting up project environment, &c.), today I made my first step in developing the core components; worker class, game state, task class.
      I have a game state that keeps a single source of truth for the entire application; all game data will be stored in this class as "states". 
      I also have a "Worker" which will do the processing of tasks in the game.
      I also have "object" class, this can be a monster, the player, a weapon, a prop, or an NPC.
      So the idea is to have a CQRS type of interaction between the classes and the data. Any action in the game will be interpreted as "Task" for the Worker class. The worker class iterates through the Task. Tasks can be created by any class interfaced with the Worker class trough "addNewTask" and the new tasks can be of a certain type i.e.: ATTACK, IDLE, SAVE_GAME, EXIT_GAME, the new task will also have a payload data and it's processed according to its task type e.g. an ATTACK with payload "{ Damage: 10, Target: MonsterA }" will reduce the health of MonsterA by 10 - the worker class will change the game state; find MonsterA in MonsterState and reduce its health by 10. 
      I think it's advantageous to have this type of centralized module where all actions are processed; I can do all sorts of procedures during the processes, maybe debug data, filter actions, mutate payloads, and such.
      How much time am I going to put into this?
      A couple of hours a day for 3 days a week maybe.
      So it's all a rough sketch for now and it's heading the right direction. I'll have more to report later on. 

      This is Forgate Castle, minus the castle, in the map Forgate; the starting location for the player. The fortification will have merchants, and quest givers.
       
×
×
  • Create New...