Jump to content

Josh

Staff
  • Posts

    23,339
  • Joined

  • Last visited

Blog Entries posted by Josh

  1. Josh
    The first step to building a character model is to establish the concept. Here are the images I have received. I have my favorite in mind, but what do you think? The purpose of this character is to serve as an enemy for a wide range of games. It could also be used as a main character with a third-person camera.
     
    Which one do you like best?
     

  2. Josh
    Lots of things are happening around here right now!
     
    First up, we've got some free professionally made animations for you to use with our futuristic soldier character. You can download the files here.
     
    Michael Betke of Pure3D has been cranking out AAA-quality 3D models ready to use in Leadwerks Engine. The following sets are available:

    Birch Trees 1.x (€22,00)
    Pine Trees 1.x (€22,00)
    Ground Plants 1.x (€19,00)
    Each set features new unreleased content. Buy a couple today and help support low-cost AAA media for independent developers.
     
    I've been spending a little time with C++, and it's not that bad. Mika Heinonen was kind enough to investigate a method of integrating Lua with C++. Here are the findings he reported:
     
     
    At this point, we have a simple C++ project with some math classes the engine uses, and we're making sure it compiles for all the various platforms I want to support.
     
    Finally, we're getting ready for the release of version 2.32. There are some physics features that need to be finished to support huge amounts of trees and rocks, and that information has been sent to the author of Newton Game Dynamics. Numerous bugs in the tracker have been resolved recently, and more fixes are on the way for small issues.
     
    That's all for now!
  3. Josh
    Just thinking out loud here, and I am considering designing the GUI like this:
     
    The GUI class handles events, window clipping, widget layout, etc. Rather than having a bunch of C++ classes that extend a base Widget class, there would just be the Widget class with a Lua script attached to it. The Lua script would handle all events and drawing, so it would determine what kind of widget the C++ object is. For example, here's a script for a simple button:
     

    function Script:Draw(x,y,width,height) if self.pointerhovered==true then self.widget.window:SetColor(self.background.r*1.2,self.background.g*1.2,self.background.b*1.2) else self.widget.window:SetColor(self.background.r,self.background.g,self.background.b) end self.widget.window:DrawRect(self.x,self.y,self.width,self.height) self.widget.window:SetColor(self.background.r,self.background.g,self.background.b) self.widget.window:DrawText(self.text,self.x,self.y,self.width,self.height,Text.Center+Text.VCenter) end function Script:MouseEnter(x,y) self.pointerhovered=true self:Draw(self.x,self.y,self.width,self.height) end function Script:MouseLeave(x,y) self.pointerhovered=false self:Draw(self.x,self.y,self.width,self.height) end function Script:MouseUp(x,y) if self.pointerhovered==true then self.widget.gui:EmitEvent(Widget.ActionEvent) end self.buttonpressed=false end function Script:MouseDown(x,y) if self.pointerhovered==true then self.buttonpressed=true end end
     
    The upside:
    It's infinitely extensible and can be used to make literally any kind of widget.

     
    The downside:
    The script needs to contains the logic and the drawing, so although skinning is possible, it's not as simple as choosing a couple of colors.
    Complexity in the interaction between C++ and Lua widget logic.
    Debugging editor scripts as they are running = not fun. If people modify the editor GUI scripts it could introduce crashes.
    Coding advanced widgets like a treeview will be quite complex in Lua.

     
    Anyways, I'm just experimenting with it for now.
     

  4. Josh
    An update is now available on the beta branch.
     
    A new decal entity type is available. Decals are used to project an image into surrounding geometry. A decal requires a material using a decal shader, located in the "Shaders\Decals" folder. The FPSGun.lua script has been updated to add bullet marks and gunshot wounds to objects a bullet hits. You can also place a decal in a map for adding large details to walls, terrain, or anything else.
     

     
    Decals are rendered similarly to the way a deferred light works; they are rendered onto the screen gbuffer. This allows them to work on any geometry, including animated models and GPU-generated details like tessellation. They will also map onto any surface, based on the direction of the surface normal. There are two new commands, Decals::Create() and Decal::SetRenderMode().
     
    Because decals render onto the scene gbuffer, a way to differentiate pixels is needed. Otherwise, a scene decal will appear on objects that pass through that area. The Decal::SetRenderMode(int mode) command can be used to indicate whether a decal should be a static scene decal (mode=0) or a dynamic decal, like for a bullet mark (mode=1). Materials also have a new parameter for their decal mode, which can be 0 (static), 1 (dynamic), or 2 (none).
     
    The blending of decals required that I modify the channel allocation of the gbuffer, and the lighting and model shaders have changed. Previously, data was stored like this:
    0: Diffuse RGBA
    1: Normal XYZ, specular
    2: Emission RGB, material flags
     
    Now the gbuffer is storing information as follows:
    0: Diffuse RGBA
    1: Normal XYZ, material flags
    2: Emission RGB, specular
     
    Any modified model shaders or shaders that are rendered before lighting need to be changed to accommodate this change, as well as any post-processing effects that read the specular value or material flags.
     
    Particle emitters will now use simple collision if the emitter has a collision type other than zero. This is a nice touch that makes bullet shrapnel bounce off floors instead of going straight through.
     
    I previously talked about four big features I was researching, terrain tessellation, terrain horizontal offsets, deferred decals, and vegetation. I made headway on each of these, but discovered that deferred decals were fairly easy to wrap up, while the other three features were more involved. Based on this development, I am revising my plan to release a new version in August with decals and the other recent improvements, then focus on finishing the vegetation system for a subsequent update. The important thing is to have the final update with vegetation out by November 1, at the latest, although that could end up being much sooner if things go smoothly.
     
    I also expect to release the game launcher in August, as an early preview release on Steam.
     
    (Build #691949 was update to #711604.)
  5. Josh
    Here is the amazing first shot of Leadwerks Engine 3. Behold not one, but TWO triangles! It's a dual display of isosceles inspiration.
     

     
    Believe it or not, this screenshot actually demonstrates a feature that's new for LE3...hardware multisampling. Look carefully at the edges of the triangle:
     

     
    This isn't the first time I've done multisampling, but until now it hasn't been possible to use with deferred rendering. It's now possible to combine these techniques with OpenGL4. You'll have our awesome lighting combined with high-quality 16x antialiasing for raytracer-like graphics. Oh yeah, multiple layers of transparency, each with proper light and shadows, will also be supported.
     
    I ran into problems getting Code::Blocks to import the glew library. Something struck me when I was Googling around for docs. I became aware that most Code::Blocks programmers are probably coding for Linux, and all the examples I read just assumed I was using MS Visual Studio. I didn't give in to the C++ monster just so I could go off on another "non-standard" (if there is such a thing) development route, so I am back on MSVC. I really don't like the poor (or complete lack of) error handling, but I am just going to have to adjust my coding style to this environment. If anyone knows if either the pro version of MSVC or the Intel compiler will stop on the first error and select the line it occurs on, I would gladly pay for that functionality.
     
    As annoying as C++ can be, there are some compelling reasons to write the next iteration of our technology in it. First, I need C++ source code to have something I can sell to professional studios. Second, it is extremely difficult to find programmers willing to work in either BlitzMax or C, and dealing with the interface between BlitzMax and C libraries can get ugly. It's not so technically difficult, but you are doing something in the world no one else is, so there's not any support for it. Having Leadwerks Engine 3 written in pure C++ code allows me to work with other programmers who can handle various tasks like networking, some special effects, and ports to other platforms. It also makes it easier to include external libraries for added features. Finally, only C++ can be used for all the platforms I want to support, including Android, iPhone, XBox, PS3, Wii, etc.
     
    C++ programmers will like this a lot because the LE3 command set allows them more power than they have had before. It's possible to write your own drivers for physics, graphics, device input, and have it all work with the core engine. You can also extends existing classes. This is particularly useful for entity programming.
     
    Should you switch to C++ for LE3? If you've already got another language you're comfortable with, I don't see any reason to. When you are programming a game, flexibility and production efficiency are more important than the raw speed of the final program. Let's say that C++ gave a 25% speed increase over another language. This is probably not realistic, but for the sake of argument let's use that number. That still doesn't mean much, if the user can get a 300% speed increase by switching the GPU or changing some quality settings. So unless you want to support a lot of extra platforms or you just like C++, I don't see any big advantage when it comes to actual game authoring. I need a C interface for use with BlitzMax, because I intend to continue making the editor with that language. Therefore, our policy of allowing you to "code the way you want", with any language you want, will continue.
     
    By the way, Khronos has done a really great job with the design of OpenGL 3.1 and onwards. A few points of interest are that immediate mode rendering is finally done away with:

    glBegin(GL_TRIANGLES); glVertex3f(1,2,3); glVertex3f(1,4,3); glVertex3f(1,2,4); glEnd();
    No more! It doesn't make sense to have three different ways of drawing primitives, and it just makes the drivers overly complicated. You should learn the one right way of doing things, from the start.
     
    Also, the shaders have all the remnants of the old fixed function pipeline cleaned out. The GPU doesn't have a "color array" or a "texcoord array". It just has vertex arrays and you decide what they are, and what format they should be in. So I can do things like compress surface normals into four bytes and not worry about needing the color array for something else.
     
    I didn't get much into it, but it looks like shaders have a nicer implementation of what used to be called "varyings". Variables are just "in" or "out" in the vertex and fragment shaders. Uniforms remain unchanged. I might have a play at geometry shaders, but two years later I am still not sure what they are for, other than something that would have been nice when stencil shadows were popular. Of course, what I am really looking forward to is the OpenGL4 hardware tessellation.
     
    Anyways, I am pretty comfortable with C++, and am happy to be back into graphics, my favorite area of technology. Thanks again to Roland Strålberg for his advice with some C++ details. Have a good week!
  6. Josh
    So after about three weeks of pain and frustration, I have successfully calculated my first path using Recast navigation. This has been a new experience for me. I've implemented half a dozen low-level C++ libraries, and never had any serious trouble, but Recast Navigation is something else.
     
    The technology underlying Recast is impressive. First they take triangle geometry, convert it to voxels, then calculate navigation, and convert it back into rough polygons. You can read about the process in more detail here:
    https://sites.google.com/site/recastnavigation/MikkoMononen_RecastSlides.pdf
     
    The results seem pretty reliable, and although the speed of regenerating a tile is slow, it can be done on a separate thread and doesn't have to be updated all that often. I have two criticisms of the library.
     
    First, the code is a total mess. I can't complain too much since it's a free library, and I definitely appreciate Mikko putting it out there, but integrating it into the engine was a hellish process. I wouldn't even call Recast a code library so much as it is an open-source program. The amount of work it took to figure out what was going on was far beyond any library I have worked with, and it could have been wrapped up into a set of much simpler commands (which is what my end result was).
     
    Second, I believe converting polygons to voxels and back is the technically wrong way to go about this. Constructive solid geometry is perfect for navmeshes, autogenerated or otherwise. It would be very fast to generate. It could be dynamically updated quickly. The results would also be 100% accurate virtually all the time. However, it would require all navigation geometry to be modeled with CSG, and although I would be fine with that, I know others will want to use arbitrary polygonal geometry. So that's one thing I would do different if I were making an engine for just myself. There's an example of why you need to be flexible with your goals sometimes.
     
    Still, it's great to be able to build navigation data for any scene and make a character walk around in it without any waypoints or ray casts. Below is my very first result with Recast. There's some obvious strange results with the path, but the point is that it's working, to some extent. It's a minor miracle I am able to plot any kind of path at all. The hard part is done, and I'm sure I'll get any remaining issues ironed out pretty quickly:

     
    Building AI features right into the engine will give us better integration than using a third-party add-on, or trying to build it on top of the engine. First example, we can use physics geometry instead of visual polygons, and make the engine automatically invalidate and update sections of a map when objects move. This will give you powerful AI features that work perfectly with the rest of the engine, so you can control characters with just a few lines of script code. When this is done, it's reasonable to expect to be able to program something like Left 4 Dead in just a couple hundred lines of script (or less, if you just feel dragging some premade scripts around and attaching them to entities).
     
    Once the pathfinding is all tidied up, it will be a big moment, because it means at that point I will know everything I need to finish Leadwerks3D! When setting out with Leadwerks3D, the things I hadn't done before were what I was most worried about. I attacked the unknown issues first. Now that we are coming to the end of this long research and development phase, all that remains is a lot of hard work. It's all stuff I have done before, so I expect the remaining tasks to go pretty quickly. It's also pretty awesome to have a clear picture of how this massive piece of technology all works...four platforms, with rendering technology stretching from fixed-function graphics all the way to Shader Model 5 hardware tessellation...plus the easiest art pipeline ever and a script and flowgraph system that no one has ever done. The scope of this engine is just so much bigger than anything I have ever done, and it actually works! B)
  7. Josh
    After three days of intense work, I am proud to show you this amazing screenshot:

    What is so special about this image? I am now successfully uploading voxel data to the GPU and writing lighting into another texture, using a texture buffer object to store the voxel positions as unsigned char uvec3s. The gray color is the ambient light term coming from the Blinn-Phong shading used in the GI direct light calculation. The next step is to create a light grid for the clustered forward renderer so that each light can be added to the calculation. Since voxel grids are cubic, I think I can just use the orthographic projection method to split lights up into different cells. In fact, the GI direct light shader actually includes the same lighting shader file that all the model shaders use. Once I have that done, that will be the direct lighting step, and then I can move on to calculating a bounce with cone step tracing.
    Clustered forward rendering, real-time global illumination, and physically-based rendering are all going to come together really nicely, but this is definitely one of the hardest features I have ever worked on!
    Here are a few wacky screenshots from the last few days.
    Why are half my voxels missing?!

    Why is only one texture layer being written to?!

    Ah, finally rendering to six texture layers simultaneously...

  8. Josh
    Vulkan is pretty wonderful because I can take all the optimal techniques I worked out in OpenGL and it just makes everything much faster. I've successfully completed the implementation of early Z-pass, which is important for our lighting system. We are using a forward clustered renderer, similar to the technique id Software's new DOOM games use. Because the fragment shader is fairly intensive, a depth pre-pass is rendered to ensure we only process each screen pixel once.

    This technique also easily supports transparency with multiple layers of shadows.

    Vulkan has a feature called subpasses specifically designed for this type of functionality. It's really fantastic to have this kind of fine control over the hardware, even if it does involved some pretty convoluted code.
    You can read more about this rendering technique below.
     
  9. Josh
    I recorded some clips from Dave's latest version of his scene he is working on. Somehow he managed to get more detail and faster speed. The octree optimizations in version 2.32 help a lot here. The renderer is really good at dealing with lots of small objects strewn across a scene, even if it did take some trouble before we got it working completely right. So here's a short video we'll be using to showcase the capabilities of Leadwerks Engine:
     
    Please share this on Facebook, Twitter, YouTube, etc. We want to get lots of views on this one. Thanks!
     


     

     
    Suggestions are welcome, as I will be doing a second cut with some small improvements.
  10. Josh
    To provide support for advanced GUI rendering, some of the features I implemented in the refactored window class are being brought into the 2D drawing command set. This includes a lot of text rendering features like word wrap, multiline, horizontal and vertical centering, and viewport clipping.
     
    A new text drawing function includes additional parameters for better control:

    Context::DrawText(std::string text, int x, int y, int width, int height, int style)
     
    The style parameter can be a combination of the following options:

    Text::Left Text::Center Text::Right Text::VCenter Text::WordWrap Text::Multiline
     
    Context-based GUIs are now rendered to a texture first, and then the texture is drawn onscreen. This allows GUIs to be partially drawn (only invalidated parts of the GUI are re-rendered). That means if you move the mouse over a button or something, only that button re-renders, and the rest of the UI is just cached in the texture and doesn't have to be redrawn. This makes the GUI performance fast, even when lots of text is shown onscreen. This is perfect for dialog boxes or help screens.
     
    The alpha blend drawing mode has also been changed to use a separate blend function for the alpha values. When a primitive is rendered with alpha blending, the maximum alpha value will be left in the rasterizer. This makes it so the resulting GUI rendered image blends correctly when drawn on top of the screen with alpha blending enabled.
     

  11. Josh
    The implementation of the Leadwerks Workshop has always been planned in two steps:
    Initial implementation using the Steam interface.
    Implementation of built-in interface in editor.

     
    I've been working on the second part for a couple days, and the results are pretty awesome so far. A built-in browser lets you view all items in the Workshop, search, and sort by rating or date uploaded.
     

     
    When you click on an item, you can view its detail view. Pressing the "Install" button will install the item into your current project. (If you aren't already subscribed to the item, you will be automatically.)
     

     
    This simplifies the process of acquiring items from the Workshop, since you no longer have to switch between Leadwerks and Steam, and you don't have to restart Leadwerks to get your item. I have always found the "subscribe" functionality a little confusing, and in the future I hope to make that part of it completely invisible to the end user.
     
    The fact that people are still using the old Downloads area sometimes tells me that the Workshop is not as easy as it could be. Basically, it's competing with zip file downloads. It needs to be easier than downloading and unzipping a zip file. I think we're getting there, because the new browser takes fewer steps.
     

  12. Josh
    I update to latest version of Newton and did a lot of work on character physics.
    All collisions below the step height will now be ignored, regardless of incline.
    Character collision in general is much more stable and accurate.
    Terrain collisions now work properly.
    Character collisions using an adaptive method that will be much faster overall.

     
    Opt into the beta branch on Steam to get the update. If you're using Lua, be sure to update your project to get the latest EXEs.
  13. Josh
    I picked up an Intel SSD for fairly cheap and installed the Windows 8 Release Preview on it. With this configuration boots up in about 5 seconds. I actually spend a lot longer waiting for BIOS to finish than for Windows to start, which is fantastic.
     
    Anyways, it makes sense to me to take screenshots for the docs from the newest version of Windows 8 since Windows is still the dominant operating system. I couldn't find a driver for my ATI 3850, so I swapped it out for a GEForce 480. Here's Leadwerks 3 running in Windows 8. It runs perfectly and doesn't look too bad.

     

     

  14. Josh
    An update is up which saves all menu settings into your game's config file.  When your program calls System:SetProperty() the inputted key-value pair is saved in a list of settings.  Your game automatically saves these settings to a file when it closes, located in C:\Users\<USERNAME>\AppData\local\<GAMENAME>\<GAMENAME>.cfg.
    The contents of the config file will look something like this:
    anisotropicfilter=8 antialias=1 lightquality=1 screenheight=720 screenwidth=1280 session_number=2 terrainquality=1 texturedetail=0 trilinearfilter=1 verticalsync=1 waterquality=1 When your game runs again, these settings will be automatically loaded and applied.  You can override config settings with a command line argument.  However, command lines arguments will not be saved in the config file.
    This has been my plan for a long time, and is the reason why your game is not set to use the editor settings.  Setting for running your game in real-time should be separate from editor settings.
  15. Josh
    Last week Valve founder and CEO Gabe Newell took to the stage at LinuxCon and proclaimed that "Linux is the future of gaming". Gabe talked about Linux gaming capabilities and promised to unveil something "on the hardware side" the following week. Today, Valve announced the upcoming release of SteamOS, a living-room operating system designed specifically to compete directly with the XBox, Playstation, and Wii console ecosystems. SteamOS will being openness to the console gaming world. This will have a lot of benefits for indie game developers:
    Console game development will no longer require expensive fees to publish and update games. If you can get your game on Steam, it can go on a console.
    Hardware manufacturers can compete to deliver better Steam-powered consoles. Gaming hardware will never again stand still for nearly ten years (as it did with the last generation of consoles).
    Steam-based game consoles will be backwards compatible and future-proof. Games you buy now on Steam will still be playable on consoles three generations in the future.

    I am very excited about this development and the future of open console gaming. Leadwerks will be available for SteamOS as soon as possible.
     

     

    Tech Progress
    The Leadwerks 3 engine has been successfully compiled for Ubuntu 13.04. However, when running the application, all I saw was a blue screen. I decided to focus on the OpenGL 4 deferred renderer for a while. While working out the depth reconstruction for the deferred renderer, I realized I was making unnecessary calls to glDepthRange(), which weren't needed at all. After removing these calls my depth reconstruction code worked correctly; this was the cause of the errors I experienced when developing a for GDC 2013. I also believe the calls to glDepthRange() were what caused the engine to not render anything when running on Ubuntu, though I won't know for sure until I try it out. 
    Leadwerks 3.1 features an OpenGL 4 deferred renderer with support for up to 32x MSAA. I was able to get this running in just a few days. I already had parts of the OpenGL 4 renderer done, and I've been working with deferred renderers since 2008, so it all came together quickly. It's easier today to write a deferred renderer for a couple of reasons.
     
    First, the state of OpenGL and driver support has gotten much better. Leadwerks 2 was written against the OpenGL 2.1 specification, which was not designed for deferred rendering. I relied on many vendor-specific extensions (some of which changed behavior halfway through the engine's life). OpenGL 4 was specifically designed for the type of things I am doing with it, so I am no longer fighting the spec. If a graphics driver has a problem, it's easier to get it fixed today than a few years ago, now that the rest of the industry has realized the benefits of deferred rendering.
     
    Second, hardware today is much more powerful than when Leadwerks 2 was developed. Leadwerk 2 was written for GEForce 8800-level hardware, and used a lot of optimizations to favor speed over quality. With modern hardware I don't have to rely on so many hacks and I can push the upper limits higher. For example, Leadwerks 2 used a random edge jitter that gave a grainy approximation of soft shadow edges. With Leadwerks 3 I can increase the blur kernel and display beautiful soft shadows that look more like an offline cg render than real-time graphics:
     

     

    Leadwerks Shwag Surfacing
    Leadwerks Shwag is beginning to appear in the real world. Post your photos of you modeling a stylish Leadwerks shirt or sticker so the rest of the community can see! 

  16. Josh
    I did a little experiment with FPS Creator Pack #75 by upsampling the images with Gigapixel, which uses deep learning to upsample images and infer details that don't appear in the original pixels. The AI neural network does a pretty impressive job, generating results that are look better than a simple sharpen filter: I doubled the size of the textures to 1024x1024. Then I generated normal maps from the high-res images using AMD's TGA to DOT3 tool, and saved the normal maps with BC5 DDS compression. The diffuse textures were saved with BC7 DDS compression. The images below are using a 4x magnification to demonstrate the difference.


    As you can see, the image that is upsampled with deep learning looks normal and the resized image looks like there is butter on the lens! It's hard to believe the above images came from a 256x128 section of an image.
    The workflow was pretty tedious, as I had to convert images to TGA, then to uncompressed or BC5 DDS, and then to BC7 in Visual Studio. Each BC7 texture took maybe 5-10 minutes to compress! So while this set represents the optimum quality for 2019 game tech, and the format for assets we want to use in LE5, the workflow has a lot of room for improvement.
    You can download the full package here:
    FPSCPack75TexturesHD.zip
  17. Josh
    After some initial difficulty, Leadwerks3D is now running on Android, with the exact same code that runs on iPhone, iPad, Windows, and Mac. A big thanks for Aria for all his help and expertise with the Android platform. This means Leadwerks3D is now running on all platforms we intend to support at launch, and it can be easily extended to support new ones.
     


     
    To celebrate, here's another cartoon I drew:

  18. Josh
    A "roughness" property has been added in the material editor. This is a simple slider with a value from zero to one. (The default material roughness value is 0.5, so all your existing materials won't turn into mirrors when the update comes). Changing the roughness value will have no visible effect unless an environment probe is visible in the scene, although I could modify the lighting shaders to make this control gloss in the specular calculation:
     

     
    Two new commands have also been added, Material::SetRoughness and Material::GetRoughness.
     
    All of the channels in our 4-texture gbuffer are already in use. To avoid allocating an additional texture to store the per-pixel roughness value, I used two flags in the materials flags value to make a simple 2-bit float. This is encoded in the geometry pass as follows:

    if (materialroughness>=0.5) { materialflags += 32; if (materialroughness>=0.75) materialflags += 64; } else { if (materialroughness>=0.25) materialflags += 64; }
     
    The probe shader then decodes it into a "roughness" integer:

    int roughness=1; if ((32 & materialflags)!=0) roughness += 4; if ((64 & materialflags)!=0) roughness += 2;
     
    The reflection cubemap lookup is then performed as follows:

    miplevel = max(int(textureQueryLod(texture5,shadowcoord).y),roughness); vec4 specular = textureLod(texture5,shadowcoord,miplevel) * specularity * lightspecular;
     
    This allows us to pack the roughness value into the gbuffer while avoiding additional texture memory use. We also have one final unused flag in the material flags value we can allocate in the future for additional functionality. Although this only allows four possible roughness values, I think it is a good solution. Just remember that "rough surface" equals "blurry reflection". The image below corresponds to a low roughness value and the reflections are sharp and clear.
     

     
    Notice that the reflections do not appear on the directly lit spheres, due to the "maximum" blend mode described here. While not technically accurate, this is a good way of dealing with the limitations of 8-bit color until ultrabright 10-bit monitors (or more) become the norm.
     
    Here is a shot using a medium roughness value, around 0.5:
     

     
    Finally, a very rough surface gives indistinct reflections that still look great because they correspond to the surrounding environment:
     


    Shader Updates
    To solve the problem described here, all shaders have been updated so that gbuffer normals are stored in world space instead of camera space. If you are using the beta branch, you must update your project to get the new shaders or lighting will not appear correctly. 
    Any third party shaders must be updated for this change. Most model shaders will have a section of code in the vertex program that looks something like this:

    mat3 nmat = mat3(camerainversematrix[0].xyz,camerainversematrix[1].xyz,camerainversematrix[2].xyz); nmat *= mat3(entitymatrix[0].xyz,entitymatrix[1].xyz,entitymatrix[2].xyz);
     
    The camera matrix multiplication can be removed and the code simplified to that below:

    mat3 nmat = mat3(entitymatrix);
     
    Some post-processing shaders retrieve the pixel normal with a piece of code like this in the fragment program:

    vec3 normal = normalize(normaldata.xyz*2.0-1.0);
     
    To update these shaders, first declare a new uniform before the main function:

    uniform mat3 camerainversenormalmatrix;
     
    And multiply the world normal by this to get the screen normal:

    vec3 normal = camerainversenormalmatrix * normalize(normaldata.xyz*2.0-1.0);

    Leadwerks Game Engine 4.1
    The new global illumination feature will be released in Leadwerks Game Engine 4.1. For comparison you can see a screenshot below of the Leadwerks 4.0 renderer, which looks good: 

     
    But the Leadwerks 4.1 render of the same scene looks absolutely fantastic:
     

     
    Until now, directly illuminated surfaces in Leadwerks looked the best, and now shaded areas look equally beautiful, or even better. Remaining tasks include testing on AMD and Intel hardware, which I have not done yet. I also have to do more work to selectively render objects in the GI reflection render. Objects that cast dynamic shadows are presently skipped, but I need to actually re-render all shadows so their shadows aren't visible in the reflection. I also need to remove entities like particle emitters and adjust quality settings so the GI render isn't rendering reflective water and other unnecessary things. Finally, the probe shader needs more work so it can handle rotation of the probe entity, which it presently does not do.
  19. Josh
    What an interesting first week. I compiled a C++ program for Android, made a programming language, learned about iPhone development, and figured out a lot of C++ stuff I did not know.
     
    It's nice to see that a port to Android will work pretty much like I was hoping. I just write an abstract driver for every system, and have specific drivers that extends that class:
    class GraphicsDriver {}
    class GL4GraphicsDriver : public GraphicsDriver {}
     
    Then when you have something like a surface that is dependent on the graphics driver, you do this:
    surface = GetGraphicsDriver().CreateSurface()
     
    And a GL4Surface object is returned. Of course, this is just the internal workings, and you will only have to call CreateSurface(). The GL4Surface is an extension of the Surface class, the same way the GL4 graphics driver extends the base graphics driver class.
     
    I would like to get something running on my HTC Evo, but the details of an Android, XBox, or PS3 version aren't too important right now. What is important is to get the C++ core done, in a way that makes it easy to add support for more platforms in the future. So as planned, you'll get a .lib file for C++, a .dll you can use with any language, and multiple Lua scripts can be attached to any entity.
     
    A roadmap of the development plan can be viewed here. I hope to accomplish most of stages 1 and 2 myself, and then recruit additional coders for the last leg. I don't intend to write the networking code myself, either. I figure it will be easier to develop streamed terrain from the beginning, instead of trying to tack it on two years from now, so I will see what I can do about that. I've never seen an infinite streamed world with the density and complexity I want, but Leadwerks seems to do best when we do really aggressive development:
    http://leadwerks.com/werkspace/index.php?/page/roadmap
     
    What I like best about this process is the code I write now is ForeverCode: It's good for any platform, and it will last for the life of the engine, which will be a very long time. I really can't imagine ever writing a version 4, because version 3 is being designed to be perfect.
     
    At this point I would like to thank Roland Stralberg, Mika Heinonen, and Ed Upton for their feedback and wisdom.
  20. Josh
    An early build of Leadwerks Game Engine 4.2 beta is available on the beta branch on Steam. This release will update the engine with the latest C++ tools and add new graphics and other features.
    Visual Studio 2017 support
    Compatible with the latest C++11 / GCC on Linux
    Refraction: apply "Materials\Effects\glass.mat" onto any object to see this in action.
    Heat haze: drag the heat haze emitter prefab into the scene to view ("Prefabs\Effects\heathaze.pfb").
    Spotlight texture: you can add a material to a spotlight and the first texture will be rendered onto the light (for flashlights).
    New animation commands
    Analytics (not working yet)

     
    It's funny that transparency with refraction used to be explained in a
    12 minute tutorial (in Leadwerks Game Engine 2), and now it is a simple effect you can drag into the scene. 

     

     


  21. Josh
    When considering the script system in Leadwerks 5, I looked at alternatives including Squirrel, which is used by Valve in many games, but these gave me a deeper appreciation for the simplicity of Lua. There are only a handful of rules you need to learn to use the language, it’s fun to use, yet somehow it does everything you could ever need.
    These were three big issues I had to solve. First, the Leadwerks 5 API makes extensive use of smart pointers, which our binding library tolua++ does not support. Second, I wanted better auto completion and a better user experience in the IDE in general. Third, if an external IDE is going to be used it needs to be able to interface with the Leadwerks debugging system.
    To support smart pointers, I found a new library called sol2 that does everything we need. @Rick and I discussed the idea at great length and I am happy to say we’ve come up with a design that is simple to use and quite a bit easier than Leadwerks 4.x even. The binding code is nowhere near done but at this point I can see that everything will work.
    @AggrorJorn suggested using Visual Studio Code as our official script IDE in Leadwerks 5, and after investigating I think it’s a great idea. The auto completion is quite good and the IDE feels more natural then anything I could come up with using a custom text editor made with Scintilla. In fact eliminating the built-in script editor in Leadwerks 5 relieves me of a lot of uncertainty and potential issues when this is written.
    Finally, VS Code has support for custom debuggers. I wrote an example command line debugger for Leadwerks and I will use this to show another programmer how to interface with Leadwerks. (I don’t plan on writing the debugger myself.)
    With your feedback and ideas are shaping up to make Leadwerks 5 a huge leap forward over our previous designs. The improved simplicity of the new script system is a big cognitive relief. Having fewer things to worry about makes life better in a subtle but definite way.
    There’s something else that consumes a lot of mental attention. Social media and the internet have grown and changed over the years and become more efficient at consuming our attention. (Many features of this site are designed the same way.)
    The scary thing is that normal non-technical people seem to be more vulnerable than nerds. We’ll fire up the Witcher and play for an hour, but regular people are checking their phones 24/7 for feedback and validation. It’s much much worse than any accusation we got as kids of being “Nintendo zombies” because we spent an afternoon playing games instead of staring passively at broadcast TV. People who play games generally don’t care about posting photographs of their food or collecting followers.
    Somewhere along the line the internet went from being a weird thing on your computer to the collective consciousness of humanity. Reality is online and the physical world around us is just a mirage, one possible instance of a million possible individual experiences. Maybe it was around the time they started using AI to optimize clickbait that things got out of hand.
    Although my career and the way I live my life are only possible through the internet, I am old enough to remember life before the web, and in many ways it was better. Things were more focused. Even the early web before clickbait ads and online echo chambers was pretty nice. You could go to a record store and hang out talking to people about new music. Printed paper magazines were a thing.
    I already removed the link to our Google+ page in the website footer and no one noticed. I think about deleting our Facebook and twitter accounts, or at least not linking to them on our site. Why must every website pay homage to these monopolies? What are they doing for me, besides a limited flow of hits that pale in comparison to what my own email list brings in? I have written about this before but now that it is fashionable to criticize social media I might act on it. I don’t know, we’ll see.
    Please like, share, and retweet.
  22. Josh
    Leadwerks 5 / Turbo makes extensive use of multithreading. Consequently, the API is stateless and more explicit. There is no such thing as a "current" world or context. Instead, you explicitly pass these variables to the appropriate commands.
    One interesting aspect of this design is code like that below works perfectly fine. See if you can work through it and understand what's going on:
    int main(int argc, const char *argv[]) { //Create a model ;) auto box = CreateBox(nullptr); //Create the world auto world = CreateWorld(); //Create a camera auto camera = CreateCamera(world); camera->Move(0,0,-5); //Create an instance of the model in the new world auto model = box->Instance(world); //Create a window auto window = CreateWindow(); //Create a rendering context auto context = CreateContext(window); while (not window->Closed()) { if (window->KeyDown(KEY_ESCAPE)) window->Close(); world->Update(); world->Render(context); } return 0; }  
  23. Josh
    In Leadwerks Engine 3, you can load a script and attach it to any entity. You can attach multiple scripts to any entity, and they will be called in the order they were attached. Right now, I am calling the script-side table "actor" because it is a little more descriptive than "object" but I'm not sure about all the syntax yet. Below is a sample script for a sliding door. When you attach this to a model, the script will control its behavior:

    ----------------------------- -- Sliding door script ----------------------------- --Attach this to any entity to turn it into a sliding door. --You can make the door move in any direction by adjusting the movement vector. --When the door opens or closes, a one-shot noise will play, along with looping --sound that will continue until the door comes to rest. --expose Sound opennoise --expose Sound closenoise --expose Sound movenoise --expose Sound stopnoise --expose Vec3 movement --expose function Open --expose function Close function actor:Start() if self.movement~=nil then self.openposition = self.entity.position + movement self.closeposition = self.entity.position end end function actor:Open() if self.openstate==0 then self.movestate=1 --Play one-shot noise, if it is set if self.opennoise~=nil then self.entity:EmitSound(self.opennoise) end --Play looping move noise if it is set if self.movenoise~=nil self.movesource = self.entity:EmitSound(self.movenoise,true) end end end function actor:Close() if self.openstate==1 then self.movestate=-1 --Play one-shot noise, if it is set if self.closenoise~=nil then self.entity:EmitSound(self.closenoise) end --Play looping move noise if it is set if self.movenoise~=nil self.movesource = self.entity:EmitSound(self.movenoise,true) end end end function actor:Update() local d local l if self.movestate~=0 --Calculate the difference between where we are and where we should be if self.openstate==1 d = self.openposition - self.entity.position else d = self.closeposition - self.entity.position end --Check to see if there is any difference l=d:Length() if l>0 then --Limit the difference if it is greater than the move speed of the door l = d:Length() if l>self.movespeed d = d:Normalize() * l end self.entity:Move(d,false) else self.movestate=0 --Disable looping noise source if it exists if self.movesource~=nil then self.movesource:Stop() --Play one-shot stop noise if it exists if self.stopnoise~=nil then self.entity:Emit(self.stopnoise) end end end
    Lua is pretty flexible, so I can make it work pretty much any way we want. When designing stuff like this, I find it's best to start with what the end user wants, and then work your way backwards to make it happen. What do you think?
  24. Josh
    Leadwerks 3.0 has been updated with bug fixes and productivity enhancements. To get the update, run the Leadwerks Updater. Use the Project Manager to update your project with the latest files.
     
    Resolved bug reports are listed in the Bug Report Forum. This release fixes a few issues including Android multitouch indexes sometimes not working right, sphere casting that was sometimes wrong, and several other small problems.
     
    Some new enhancements have been made to improve productivity. Camera entities will now show a volume when selected, indicating their view frustum:

     
    The asset browser now uses a solid background to indicate which file is selected. You can now use the arrow keys to navigate files in the asset browser, and the enter key will open the selected file:

     
    In order to achieve compliance with UAC and other OS permission systems, Leadwerks will now store the program log and config file in the correct "AppData" folder. On Windows, this is "C:\Users\(USERNAME)\AppData\Local\Leadwerks". On OSX this is "Library/Application Support/Leadwerks". If you want to edit your config file by hand you must find it there. You do not need to manually move any files, as the editor will automatically copy your config file to the correct location.
     
    The default location for projects has been moved to the user's Documents directory. This will not affect your existing installation, as the editor will read your current projects path from your configuration file. If you wish, you can change the default projects path in the Options dialog, under the Paths tab.
  25. Josh
    Based on a little observation, I've made the following changes to the publish routine on the beta branch:
    The FPS Player script has been updated so that the footstep sound files are explicitly named, so they don't get missed in the publish step. You will need to update your project to get the new script (or just copy FPSPlayer.lua to your project).
    There is now a checkbox to "Only include used files". If this is checked, then the new packing routine will be used, otherwise the old behavior of including all files is used.
    The file extension filter will now be used so you can include files like XML, TXT, or whatever else you want.
    The routine has been fixed to pick up terrain textures and include those.
    A few people suggested a "tagging" system so the user can mark files to be included or not. This is a very bad idea. The whole point of the selective file inclusion system is that the user doesn't want to maintain a clean directory. So adding a manual system to overcome the limitations of the automatic system...it would be easier just to delete the unwanted files. When your feature requests lead to more feature requests, to fix the problems of the previous feature, that is a strong sign of bad design. So we won't be going down that path.
    If you are using the selective file inclusion and you want to force a file to be included that would otherwise be impossible to detect, an easy way to do this is to just add a commented-out line in your main script that names the file:
    --myfile.tex Anyways, the new build is available now on the beta branch. Let me know how you like it.
×
×
  • Create New...