Jump to content

Josh

Staff
  • Posts

    23,303
  • Joined

  • Last visited

Blog Entries posted by Josh

  1. Josh
    I'm really happy to see all the great and scary games coming out for the Halloween Game Tournament. I have something of my own to share with you.
     
    The Leadwerks 3 vegetation system is a groundbreaking new technology. All vegetation instances are procedural and dynamically placed, so that physics and rendering of any amount of instances can occur with zero memory usage. This demo proves that the idea actually works!
     
    This demo shows the new Leadwerks Game Engine 3 vegetation system in action. It uses three vegetation layers for trees, brushes, and dense grass. Without any adjustment of vegetation settings for different hardware, I am getting the following results:
    NVidia GEForce GTX 780: 301 FPS
    AMD Radeon R9 290: 142 FPS
    Intel HD Graphics 400: 15 FPS

     
    The view distances can be further adjusted to make the system run faster on low-end hardware.
     

  2. Josh
    Today I am happy to say I worked out the problems that the vegetation system prototype had on AMD and Intel graphics. I started by upgrading the system from using texture buffers to using vertex buffers, as recommended in Daniel Rakos' excellent RasterGrid blog. He made this change for speed, but in my case it gave me simpler code I was able to eliminate the OpenGL errors with.
     
    The most interesting part of this was discovering the glVertexAttribDivisor command. (Fortunately, it's in the 4.0 spec!) This allows you to set a vertex attribute that only changes per instance instead of per vertex rendered. So in other words you can have a per-instance attribute stored in a vertex buffer...which is completely crazy but very useful in this case.
     
    So here is my results on Intel. It's a purely technical shot showing 1.6 million polygons rendered on integrated graphics. There's no billboarding at this time, so it's totally overloading the graphics chip, but the fact this even works is awesome. There's no culling performed on the CPU and no memory usage, so the whole bottleneck is just raw GPU performance. Billboarding will cut the performance demand down so we will have lush vegetation everywhere at very little cost.
     
    This was the hard part of developing the system, now it's just a matter of dealing with my own code to finish it out.
     

  3. Josh
    This video shows the player interacting with vegetation objects. Vegetation objects are special because they aren't stored in memory at all, but instead are dynamically generated in real-time according to a special algorithm! You can have infinitely dense forests without using any memory.
     


  4. Josh
    I got my hands on the GDC showcase scene by Michael Betke, and it's much more beautiful than I thought. I used this scene to rewrite and test the vegetation rendering code. Collision isn't working yet, but it's built into the routine. The results speak for themselves.
     
    Fortunately, Pure3D is soon offering a set of game-ready vegetation models, so you can create gorgeous landscapes like this.
  5. Josh
    Billboards, transitions, and rendering are now done, and as you can see in the screenshot below, the idea works great. In Leadwerks 2, this application would have used hundreds of megabytes of data to store all the individual 4x4 matrices of each object. In Leadwerks 3, the instances are generated on the fly, so the application uses no more memory than a map with a blank terrain:
     

     
    Still to do:
    Fade out billboards as they approach max view distance.
    Add rows to break up generated billboard textures.
    Add DXT compression to generated billboard textures.
    Add sub-grid rendering so GPU is only evaluating instances within a certain distance to the camera.
    Add physics collision.
    Vegetation painting tools in editor.

  6. Josh
    I just had a breakthrough with the physics. There's a lot of optimization work left to do, but I can see at this point the idea works.
     
    Newton Game Dynamics provides a mechanism for a user-defined collision shape. This accepts a bounding box and calls a user-defined callback any time an object intersects the bounding box. The callback builds a mesh dynamically for the area that the other object occupies. Internally, Newton uses this mechanism to process heightmap terrain without having to store a triangle mesh for the entire terrain geometry. It can also be used for things like dynamically calculated voxel physics.
     
    In our case, we are using this to build a mesh for the relevant instances around the colliding object. In the image below, the car has an AABB around its extents, and this AABB is used to retrieve all relevant instances within that volume. The mesh is constructed and sent back to Newton for processing collisions.
     

     
    This allows us to simulate vegetation of any complexity without having to store each vegetation instance in memory.
  7. Josh
    The Leadwerks 3 vegetation system is being designed to side-step the bottlenecks that limited the Leadwerks 2 vegetation system. The Leadwerks 2 system involved large collections of 4x4 matrices for each instance, resulting in hundreds of megs of data stored with the map. Eliminating this data results in small map sizes and reduction of memory usage.
     
    Here we have 10,000 trees being rendered (with no billboards), for a total geometry count of 14 million polygons. Memory usage is...zero!
     

     
    The framerate for this is 130 in debug and release mode, which tells me it's hitting the ceiling on the GPU vertex shader. Obviously we will use billboards to reduce the polygon count, but this tells me we're on the right track.
  8. Josh
    The Leadwerks 2 vegetation system used a grid of "cells" that each contained a quantity of vegetation instances. If the cell was close enough, each instance was checked against the camera frustum like a regular entity and then all visible instances were rendered in a batch. Cells that were further away were collapsed into a single surface consisting of a quad for each instance. This is how we were able to draw massive amounts of foliage in the distance at a fast framerate:
     


     
    This was good, but limited by the scene management performed by the CPU. It also used very large amounts of memory to store all the 4x4 matrices of the individual instances. The above map used about half a gigabyte of data to store all positions for each tree int he scene.
     
    The Leadwerks 3 vegetation system is being designed around modern hardware capabilities, taking advantage of the features of OpenGL 4. This has two goals:
    Remove the overhead of scene management performed on the CPU.
    Reduce memory usage of vegetation data.


    Transform Feedback
    One of the most interesting things OpenGL 4 supports is transform feedback, which allows you to render data to an arbitrary buffer. This can be combined with a geometry shader to selectively output information in ways a normal render-to-texture can't. This schematic from RasterGrid's OpenGL blog shows how the system works: 

     
    Below you can see my implementation working. The scene consists of 91 million polygons, with about 28 million visible at any given time. (This number will be reduced through the use of billboards.) The edges of the camera frustum are pulled in to make the culling visible.
     


     
    Use of the transform feedback feature in OpenGL 4 relieves the CPU from the expensive overhead of large-scale scene management.

    Tiling Matrices
    The need for individual instance matrices is being totally eliminated by using a tiling grid of 4x4 matrices. This creates a repeating pattern of rotations across the scene. I think when the trees are placed on a hilly terrain the tiling appearance won't be visible, but there are other tricks I can use to increase the randomness. The physics system will work by dynamically retrieving the relevant 4x4 matrices of nearby instances, totally eliminating the need to store any of this massive data in memory. The fact that no instance data is being sent over the PCIE bridge also means this system will be much faster than Leadwerks 2. 
    Vegetation in Leadwerks 3 will be a virtually zero-overhead system and allow for much greater volumes of geometry than Leadwerks 2 could render, at effectively no cost on most hardware.
  9. Josh
    An update is available on the beta branch which adds the new vegetation system. You can open the attached map in the editor to see the system in action. Be sure to create a new project, or update your existing one, in order to get the new shaders and models.
    vegetationsample.zip
     
    To get this update early you must opt in to the beta branch on Steam.
     
    The new vegetation system is special because it does not use persistent objects stored in memory. Rendering and physics are executed according to a distribution algorithm that dynamically generates instances each frame. This allows the system to manage an infinite number of instances, with much denser placement and faster performance than a conventional vegetation system would allow (such as what Leadwerks 2 used.)
     

     
    You can select the vegetation tool in the terrain tools dropdown box. Usage is pretty self-explanatory.
     
    Models that are to be used as vegetation layers much have a material with a vegetation shader applied. There are two new slots in shaders list in the material editor, for the vegetation and vegetation shadow shaders. These can be selected from the "Shaders\Vegetation" folder.
     
    Models with a default physics shape and collision enabled will be collideable.
     
    A new "Pick mode" setting has been added in the material editor. This allows you to disable picking on some materials (like leaves and grass). This allows bullets to pass through objects that should not stop them.
     
    At this time, vegetation will only appear when texture+lighting render mode is in use.
     
    The default models have been donated generously by Pure3D.de.
  10. Josh
    I've made progress with the new vehicle system and it is shaping up nicely. The vehicle wheels consist of a slider joint with a spring (the strut) connected to a pivot, connected to the wheel by a hinge joint (the axle). If the wheel can be steered, an additional pivot is inserted between the strut and axle, with a motorized hinge to control steering. There were two big problems in addition to this that need to be solved in order to make a vehicle that is stable at high speeds.
    First, the mass matrix of the tires needs to be spherical. The mass matrix is the distribution of mass across an object. A brick and a 2x4 piece of lumber probably have about the same mass, but have a different mass matrix. Therefore the brick should spin more easily than the lumber. If you don't make the mass matrix for the tires spherical you will get bad wobbling at high speeds, like this video shows:
    When the mass matrix is fixed this problem goes away. The vehicle gets up to 90 MPH, and although there are other issues, there is no tire wobble.
    The other issue that needs to be solved can be seen in the video above. At high speeds the tire collisions become inaccurate and the vehicle bounces a lot. We need to replace the default collision with a volume raycast coming from the top position the wheel can sit on the shock, going down to the extended position of the strut. This is the part I haven't done yet, but I know it can be done.
    I think the new vehicle system will offer a lot of flexibility and possibilities for future features since it is mostly made with the standard physics features.
  11. Josh
    The revision of our vehicle system has been a long time coming, and I am happy to say the wait will soon be worthwhile.  The new system uses a hyperrealistic slip differencial system to adjust the power given to each wheel.

    The results are a clear cut above any game vehicle physics you've ever seen.
    I am also taking steps to make the vehicle system easier to use.  The AddTire() command can now accept an entity as a parameter for the tire object.  This would typically be a child limb found within a loaded car model.  The object's size can be used to calculate the exact width and radius for the tire.  This simplifies the vehicle setup code so you just load up the model, find the wheel limbs, add tires and axles, and build the vehicle:
    //Load car model auto chassis = Model::Load("Models/Desert Patrol/Desert Patrol.mdl"); chassis->SetMass(2000); vehicle = Vehicle::Create(chassis); //Add tires vehicle->AddTire(chassis->FindChild("WheelFL"), true); vehicle->AddTire(chassis->FindChild("wheelFR"), true); vehicle->AddTire(chassis->FindChild("WheelBL14")); vehicle->AddTire(chassis->FindChild("WheelBL15")); //Add axles vehicle->AddAxle(0, 1); vehicle->AddAxle(2, 3); //Finalize the vehicle vehicle->Build(); It's very easy to load up a model and turn it into a working vehicle without worrying about the exact tire sizes and positions.

    You no longer have to position the visible tire models yourself to match the tire orientations, as this is all done automatically.  So we've taken a very complicated advanced system and made it very accessible and quick to get running.
  12. Josh
    Here's a look at the new vehicle system that is being developed. The API has been simplified so you simply create a vehicle, add as many tires as you want, and start using it. The AddTire() command now accepts a model and the dimensions of the tire are calculated from the bounds of the mesh.
    class Vehicle { int AddTire(Model* model, bool steering=false, const float spring=500.0f, const float springrelaxation = 0.1f, const float springdamping = 10.0f); void SetGas(const float accel); void SetBrakes(const float brakes); void SetSteering(const float angle); static Vehicle* Create(Entity* entity); }; A script will be provided which turns any vehicle model into a ready-to-use playable vehicle. The script searches for limb names that start with "wheel" or "tire" and turns those limbs into wheels. If they are positioned towards the front of the car, the script assumes the wheels can be turned with steering. You can also reverse the orientation of the vehicle if the model was designed backwards.
    There is one big issue to solve still. When a vehicle drives on flat terrain the tires catch on the edges of the terrain triangles and the whole vehicle bounces around badly. I'm looking into how this can be solved with custom collision overrides. I do not know how long this will take, so it might or might not be ready by Christmas.
  13. Josh
    I've uploaded a release candidate of version 4.3 on the beta branch. This is a full build, for Windows and Linux. The Game Launcher beta branch is also updated.
     
    If all is well this will go onto the stable branch in a few days.
  14. Josh
    Leadwerks Game Engine 4.4 has been updated on the beta branch on Steam.
    Networking finished and documented. GUI finished. All new physics features finished. The character controller physics and picking up objects has been improved and made smoother.  There is a problem with the player sliding down slopes, as seen in the FPS Character Controller example map.  I will work this out.
    I also noticed during testing that picking up some objects in the FPS / AI map will freeze the game.  Will check it out.
    I have not actually tested compiling on Linux yet, because my Linux machine is in the office and I am at home right now.  I'm heading in this afternoon, at which point I will complete Linux testing.
    The only other problem is that vehicles are not working yet.  I'm not sure yet how I will proceed with this.
    Updating C++ Projects
    The following changes are needed to update your C++ projects:
    Visual Studio
    Add these include header search directories:
    $(LeadwerksHeaderPath)\Libraries\NewtonDynamics\packages\thirdParty\timeTracker Add these input libraries:
    newton_d.lib;dContainers_d.lib;dCustomJoints_d.lib; (debug) newton.lib;dContainers.lib;dCustomJoints.lib; (release) Code::Blocks
    Add these include header search directories:
    $(LeadwerksPath)/Include/Libraries/NewtonDynamics/packages/thirdParty/timeTracker You also need the dev files for libcurl:
    sudo apt-get install libcurl4-openssl-dev This is pretty much the finished 4.4, so please test it and post any bug reports you have.  Thank you.
  15. Josh
    The beta branch on Steam is updated with some fairly big changes.
    Leadwerks Engine is now compiled with and uses Visual Studio 2017. It is now compiled on Ubuntu 16.04.  I do not know yet what changes this means for the end user but I had to add some dependencies in the editor. In addition to that, ZIP import is now working (File > Import).
    The VR command set is finished and documented.  A VR project template is forthcoming.
    The new vehicles are not yet ready.
    Leadwerks Game Engine 4.5 will be released December 22nd.
     
  16. Josh
    Version 4.5 will feature official support for VR (Vive and Oculus) and a new super realistic vehicle system.  These features are more or less already done, but need some work to make them release-ready.  The new vehicle system is so good, and I am so grateful to Julio for his help making this happen, that I think we might do a racing-themed winter tournament.   I am trying to think of a clever pun to call it.
    At the same time, I have implemented the first build of version 5 in the same source code, adding Unicode support and using C++11 shared pointers for all objects that were previously created as pointers.  The changes to the source code were extensive, and though I used preprocessor definitions to separate the 4.x and 5 builds, there may be some errors in the engine at this time.
    So the next few weeks is going to be a process of testing the engine and documenting the new features.  I plan to have a beta of 4.5 up shortly on Steam.  4.5 will be released before Christmas, along with the first beta of version 5, for people who bought the $5 subscription.  The enterprise version will be updated a couple weeks after the release of 4.5.
  17. Josh
    There are three low-level advancements I would like to make to Leadwerks Game Engine in the future:
    Move Leadwerks over to the new Vulkan graphics API.
    Replace Windows API and GTK with our own custom UI. This will closely resemble the Windows GUI but allow new UI features that are presently impossible, and give us more independence from each operating system.
    Compile the editor with BlitzMaxNG. This is a BMX-to-C++ translator that allows compilation with GCC (or VS, I suppose). This would allow the editor to be built in 64-bit mode.

     
    None of these enhancements will result in more or better games, and thus do not support our overarching goal. They also will each involve a significant amount of backtracking. For example, a new Vulkan renderer is pretty much guaranteed to be slower than our existing OpenGL renderer, for the first six months, and it won't even run on a Mac. A new GUI will involve lots of bugs that set us back.
     
    This is likely to be stuff that I just explore slowly in the background. I'm not going to take the next three months to replace our renderer with Vulkan. But this is the direction I want to move in.
  18. Josh
    You can now view detailed sales records of your game assets in Leadwerks Marketplace. First, log into your Leadwerks account and navigate to the Leadwerks Marketplace main page. In the bottom-right, below the categories, a link to your paid files will appear.

    Here you can see a list of all your paid items:

    When you click on an item, you can see a list of people who have purchased it, along with sales dates.

    If you wish to give a free license to any member for any reason, you can do so by clicking the "Generate Purchase" button. A window will pop up where you can type in the member's name and add the item to their account for free.

    These tools give you more control over your game assets and better information on sales.
  19. Josh
    I've got orthographic viewport navigation done. I decided to build some grid commands into the camera class so that the graphics driver itself can handle the grid rendering, rather than having the editor make a bunch of OpenGL calls in a callback function. The grid can be rendered from any angle, and the math was a little tricky, but I got it worked out. I paid extra attention to showing the border where the world ends. The sliders that pan the viewport are very accurate, and stop right at the end of the world space. By default, this is one kilometer, but the world size can be changed at any time.
     
    One thing that was tricky was that the grid can be any resolution, and the world can be any size, so there's no guarantee the edge of a grid patch will match the edge of the world. I ended up using clipping planes to solve this problem.
     

     


  20. Josh
    The Leadwerks 2 terrain system was expansive and very fast, which allowed rendering of huge landscapes. However, it had some limitations. Texture splatting was done in real-time in the pixel shader. Because of the limitations of hardware texture units, only four texture units per terrain were supported. This limited the ability of the artist to make terrains with a lot of variation. The landscapes were beautiful, but somewhat monotonous.
    With the Leadwerks 3 terrain system, I wanted to retain the advantages of terrain in Leadwerks 2, but overcome some of the limitations. There were three different approaches we could use to increase the number of terrain textures.
    Increase the number of textures used in the shader. Allow up to four textures per terrain chunk. These would be determined either programmatically based on which texture layers were in use on that section, or defined by the artist. Implement a virtual texture system like id Software used in the game "Rage". Since Leadwerks 3 runs on mobile devices as well as PC and Mac, we couldn't use any more texture units than we had before, so the first option was out. The second option is how Crysis handles terrain layers. If you start painting layers in the Crysis editor, you will see when "old" layers disappear as you paint new ones on. This struck me as a bad approach because it would either involve the engine "guessing" which layers should have priority, or involve a tedious process of user-defined layers for each terrain chunk.
    A virtual texturing approach seemed liked the ideal choice. Basically, this would render near sections of the terrain at a high resolution, and far sections of the terrain at low resolutions, with a shader that chose between them. If done correctly, the result should be the same as using one impossibly huge texture (like 1,048,576 x 1,048,576 pixels) at a much lower memory cost. However, there were some serious challenges to be overcome, so much so that I added a disclaimer in our Kickstarter campaign basically saying "this might not work"..
    Previous Work
    id Software pioneered this technique with the game Rage (a previous implementation was in Quake Wars). However, id's "megatexture" technique had some serious downsides. First, the data size requirements of storing completely unique textures for the entire world were prohibitive. "Rage" takes about 20 gigs of hard drive space, with terrains much smaller than the size I wanted to be able to use. The second problem with id's approach is that both games using this technique have some pretty blurry textures in the foreground, although the unique texturing looks beautiful from a distance.

    I decided to overcome the data size problem by dynamically generating the megatexture data, rather than storing in on the hard drive. This involves a pre-rendering step where layers are rendered to the terrain virtual textures, and then the virtual textures are applied to the terrain. Since id's art pipeline was basically just conventional texture splatting combined with "stamps" (decals), I didn't see any reason to permanently store that data. I did not have a simple solution to the blurry texture problem, so I just went ahead and started implementing my idea, with the understanding that the texture resolution issue could kill it.
    I had two prior examples to work from. One was a blog from a developer at Frictional Games (Amnesia: The Dark Descent and Penumbra). The other was a presentation describing the technique's use in the game Halo Wars. In both of these games, a fixed camera distance could be relied on, which made the job of adjusting texture resolution much easier. Leadwerks, on the other hand, is a general-purpose game engine for making any kind of game. Would it be possible to write an implementation that would provide acceptable texture resolution for everything from flight sims to first-person shooters? I had no idea if it would work, but I went forward anyway.
    Implementation
    Because both Frictional Games and id had split the terrain into "cells" and used a texture for each section, I tried that approach first. Our terrain already gets split up and rendered in identical chunks, but I needed smaller pieces for the near sections. I adjusted the algorithm to render the nearest chunks in smaller pieces. I then allocated a 2048x2048 texture for each inner section, and used a 1024x1024 texture for each outer section:

    The memory requirements of this approach can be calculated as follows:
    1024 * 1024 * 4 * 12 = 50331648 bytes
    2048 * 2048 * 4 * 8 = 134217728
    Total = 184549376 bytes = 176 megabytes
    176 megs is a lot of texture data. In addition, the texture resolution wasn't even that good at near distances. You can see my attempt with this approach in the image below. The red area is beyond the virtual texture range, and only uses a single low-res baked texture. The draw distance was low, the memory consumption high, and the resolution was too low.

    This was a failure, and I thought maybe this technique was just impractical for anything but very controlled cases in certain games. I wasn't ready to give up yet without trying one last approach. Instead of allocating textures for a grid section, I tried creating a radiating series of textures extending away from the camera:

    The resulting resolution wasn't great, but the memory consumption was a lot lower, and terrain texturing was now completely decoupled from the terrain geometry. I found by adjusting the distances at which the texture switches, I could get a pretty good resolution in the foreground. I was using only three texture stages, so I increased the number to six and found I could get a good resolution at all distances, using just six 1024x1024 textures. The memory consumption for this was just 24 megabytes, a very reasonable number. Since the texturing is independent from terrain geometry, the user can fine-tune the texture distances to accommodate flight sims, RPGs, or whatever kind of game they are making.

    The last step was to add some padding around each virtual texture, so the virtual textures did not have to be complete redrawn each time the camera moves. I used a value of 0.25 the size of the texture range so the various virtual textures only get redrawn once in a while.
    Advantages of Virtual Textures
    First, because the terrain shader only has to perform a few lookups each pixel with almost no math, the new terrain shader runs much faster than the old one. When the bottleneck for most games is the pixel fillrate, this will make Leadwerks 3 games faster. Second, this allows us to use any number of texture layers on a terrain, with virtually no difference in rendering speed. This gives artists the flexibility to paint anything they want on the terrain, without worrying about budgets and constraints. A third advantage is that this allows the addition of "stamps", which are decals rendered directly into the virtual texture. This allows you to add craters, clumps of rocks, and other details directly onto the terrain. The cost of rendering them in is negligible, and the resulting virtual texture runs at the exact same speed, no matter how much detail you pack into it. Below you can see a simple example. The smiley face is baked into the virtual texture, not rendered on top of the terrain:

    Conclusion
    The texture resolution problem I feared might make this approach impossible was solved by using a graduated series of six textures radiating out around the camera. I plan to implement some reasonable default settings, and it's only a minor hassle for the user to adjust the virtual texture draw distances beyond that.
    Rendering the virtual textures dynamically eliminates the high space requirements of id's megatexture technique, and also gets rid of the problems of paging texture data dynamically from the hard drive. At the same time, most of the flexibility of the megatexture technique is retained.
    Having the ability to paint terrain with any number of texture layers, plus the added stamping feature gives the artist a lot more flexibility than our old technique offered, and it even runs faster than the old terrain. This removes a major source of uncertainty from the development of Leadwerks 3.1 and turned out to be one of my favorite features in the new engine.
  21. Josh
    I experienced some problems this week when I tried to create an executable with Visual Studio 2008 for deployment. On Windows 7 test machines I would get this error:
     
    I finally tracked the solution down to a Visual Studio project setting. In Project Settings > Configuration Properties > C/C++ > Code Generation there is a property called "Runtime Library". By default it is set to rely on external DLLs. Change these values to non-DLL settings (like MT or MTd) and they will include the runtime library in the executable. This makes for bigger executables, but they will run everywhere.

     
    Having experienced this problem with Visual Studio 2010, I guessed this was the same issue. I uninstalled the Visual C++ 2010 Redistributable Package from my Windows XP machine, then created a simple test program on another Windows 7 machine. First I made sure I could create the problem, by using the default runtime library. Ever seen this error?:

     
    I've seen this issue come up before on this forum. Now you know how to solve it and build Debug or Release executables that will run everywhere, with Visual Studio 2008 and 2010. Here is my test application from Visual Studio 2010, "testapp.MDd.bat" will only run if you have the 2010 Redistributable Package installed. "testapp.MTd.bat" will run everywhere:
    testapp.zip
     
    Since we no longer have problems creating executables for Windows XP with Visual Studio 2010, I see no reason not to move our project on to a newer version. Visual Studio 2012 currently cannot make Windows XP executables, but Microsoft claims this will be supported soon. However, even if deployment to Windows XP is supported, Visual Studio 2012 itself will never run on Windows XP. Switching to Visual Studio 2012 would mean you cannot program Leadwerks with C++ on Windows XP.
     
    What do you think? Should we make the move to 2012, 2010, or stick with 2008?
  22. Josh
    The beta branch of the professional version is upgraded to use Visual Studio 2017. You can download the release candidate for free here:
    https://www.visualstudio.com/vs/visual-studio-2017-rc/
     
    Your existing projects should work with VS 2017 with no changes, but you might want to hold off while we test if you are in the middle of a project. New projects you create should open with VS 2017 by default.
     

  23. Josh
    A release candidate for Visual Studio 2017 was released in November. I took a chance that the final release would be out in December, but it isn't here yet. Releasing Leadwerks 4.2 built with VC 2017 could possibly cause the program to not run on some computers, because the Visual Studio 2017 redistributable is not out yet, and there is no option yet to make this part of the installation on Steam.
     
    Because of this, I am going to release Leadwerks 4.2 for use with Visual Studio 2015, and upgrade to 2017 when the final release is available.
     
    If you have a VS 2017 project, it is easy to downgrade it. Open the solution file and change the VS version to 14:
    VisualStudioVersion = 14.0.0.0
     
    Open the vcxproj file and change the tools version from 15 to 14:
    ToolsVersion="14.0"
     
    Find and replace all instances of "v141" with "v140", save the file, and you're done.
     
    You might even be able to continue using VS 2017 with no changes at all.
     
    If you want to stick with VS 2013, it might be possible to just install the 2015 build tools, but I don't know for sure. If you try it, be sure to let us know your results.
  24. Josh
    I had to spend several weeks just eliminating light leaks and other artifacts, and getting the results I wanted in a variety of scenes. The results are looking good. Everyone who tries implementing this technique has problems with light leaks but I have fortunately been able to avoid this with careful planning:

    Now that I have nice results with a single volume texture centered at the origin, it's time to add additional stages. The idea is to have a cascading series of volume textures around the camera, where each volume is twice the dimensions (and eight times the volume) of the previous one. This allows us to cover a large area of the scene, while using lower-resolution data for parts of the scene that are further away from the camera:

    Putting this into practice, in this shot you can see some ambient occlusion and reflections in the trench. (The metalness is turned up really high to make it more easily visible, so don't worry about the bright white specs.)

    A little bit further from the center of the scene, we see another trench. This appears in the second GI volume with half the voxel resolution of the previous image, so it has some small artifacts. However, this will also appear further from the camera so they won't be noticeable:

    The transition between stages is good enough. If you look carefully at the floor between stage 0 and 1, the reflection of the window is lost in the lower-resolution stage 1. On the wall in between stage 1 and 2 the boundary is visible. However, the camera is going to be further away so those artifacts won't be as apparent as they are now.

    From the outside, we can see four 64x64x64 volume textures can be used to cover the entire train station, with a base voxel size of 12.5 centimeters.

    To cover the same area with a single volume texture we would need a 512x512x512 texture. Using several cascaded volume textures brings our memory usage down to less than 1% what it would be otherwise:
    64*64*64*4 = 1048576
    512*512*512 = 134217728
    1048576 / 134217728 * 100 = 0.78125%
    There is still a lot of room for optimization. We can perform the voxelization step for all four stages in one single pass using multi-target rendering, like the pointlight shadow shader does. We could also distribute the GI stage updates so that only one gets drawn each frame, since even objects in motion probably won't cause a change in the voxelized result every single frame. Right now I am just focusing on optimizing the shader and rendering everything each frame, so I can deal with a worst case scenario before I start adding techniques that will make it harder to measure performance.
    Without doing any performance tests, the rendering seems quite fast. I am not even using this in a real-time application right now, but I definitely get a feel for how responsive the viewport rendering is to mouse movement, and it seems to be very snappy so far. I can definitely bog it down if I turn up the settings too high.
    There are a lot of settings that are very scalable for performance / quality such as voxel resolution, number of cascaded stages, maximum ray steps, and number of light bounces.
    I've done some initial tests trying to make the volumes move around with the camera, and that produced a lot of new and strange artifacts I didn't anticipate. So I think we can expect a few more weeks of slow but steady progress as I dive into this even deeper.
    There's a lot of academic papers and demos out there that show this technique, but delivering a complete solution that produces good results for any scene is quite a challenge, and I've been working on this for four years, with the last three months spent pretty much full-time, just on this feature! 
    But I am glad to do this, because my love for you is so great and I want you to be happy.

     
  25. Josh
    Adding emission into the cascaded voxel cone step tracing global illumination and dynamic reflections system (SEO ftw) was simple enough:
    There's some slight trailing but it looks okay to me. There is a bit of a "glitch" in that when the emissive surface gets near the wall, the ambient occlusion kicks in, even though the sphere is self-illuminating. This happens because the emission color is mixed with the light voxel during the rasterization step. I could fix this by storing emission in a separate texture, but I don't think the increase memory and processing time are justifiable and this is acceptable as-is.
    Changing the center of the voxel grid will probably cause the whole scene to display the same trailing, and at that point I think that would look really bad. I'm thinking the contents of the volume texture probably need to be shifted over when the camera moves one voxel unit. Can a texture be copied to itself in Vulkan? Let's see:
    Hmmm, that still does not tell me if I can copy a section of overlapping memory in a texture.  Hmmm, this might be what I am looking for...
    So I probably need to keep an extra "transfer" texture around to act as an intermediate image when copying the contents of the volume texture to itself.
×
×
  • Create New...