GoodGraphics24.png, Particles, Particles, PATICLEZ!

It seems like I just made one of these, huh?  And while this is just a first pass at the system, and running on programmer art, I’m excited enough to post about it.  After that, hopefully this post isn’t a huge let down.

So, particle effect systems!  I put it off all year because I just had so much stuff on my plate and all of it seemed super important and core to just getting the game to display.  And a good portion of it was features that have since been deprecated due to changes in design direction.  Not that I’m mad, it’s the nature of the beast here at DigiPen and I accept that.  But, now that we’re in the home stretch, it’s become a real crunch to finally get particles done for the huge polish factor they can add.  And after about a week at it (although I had to spend a fair amount of time during that week tracking down what turned out to be two major buffer under runs that were causing huge stability issues), I finally have it working and, I think, good enough to show people.  So, here you go!

 

GoodGraphics24.png, PATICLEZ!

 

I also need to give a huge shout out to Hayden Jackson for all the help he gave me while developing this.  The insight, feedback, and source code was absolutely invaluable, and I never would have designed a system that was nearly as elegant in the given time frame.  So, thanks dude!

Next up is finally integrating my spritesheet animation system from last year, and that might unfortunately be the last graphical feature I have time to add before I need to clean up loose ends and fix outstanding technical requirements before submission.  We’ll see, as I’d really like to find the time to add HDR and SSAO, but I’m trying to be realistic here.  Either way, I’m off to GDC next week and I’m glad I got particles in before that or else I’d have spent all week being driven crazy by it.  Anyone else that’s going, feel free to hit me up for grabbing some drinks!  Otherwise, expect more posts on getting prepped for final submission after I get back.

Edit:  I realized that a screen capture is a terrible way to show off a particle system, so I took this short video of it in action.  Enjoy!

 

GoodGraphics23.png, More Lighting, More Transparency, And Performance

So, a lot of backend updates have been happening in the last month, but the visual part of this update actually happened the day after the last GoodGraphics post.  But school’s been busy (what’s new?).  And then I got Premake and FXC working and wanted to post about that.  And then school’s been busy…  it isn’t like it’s a pattern or anything.

The visual part is that after talking with designers and artists, the simplest solution to dealing with transparency in the new lighting system was to just not illuminate transparent objects at all.  While it would be nice to have light partially “hit” and partially go through transparent objects, it just isn’t feasible for me to do it in a way that both looks good and keeps reasonable performance at this point in the year.  So, instead I just exclude transparent objects from the depth buffer used by the light accumulator.  The loss of not illuminating transparent objects is pretty minor compared to the gain of seeing light sources through them.

 

GoodGraphics23.png, lighting through transparent objects.

 

One of the major backend changes I’ve made is to start using instanced drawing.  I had originally, and incorrectly, assumed that I could write a very optimized material system to generate the fewest number of state changes and data transfers, and couple that with the reduced overhead of draw calls since DirectX 9, and be alright.  Turns out that while draw call overhead has been reduced, it is still pretty major, and making a separate draw call for every object takes a toll.  As a result, I’ve switched my lighting over to using DrawIndexedInstanced and it has made a huge difference.  A lot of our levels are now able to handle the entire light accumulation pass in a single draw call, and frame times have cut in half.  So, I’m pretty stoked about that.

Beyond that, I’ve been working to move as much calculation from pixel shaders to vertex shaders to cut down overall instruction counts without sacrificing visual fidelity, and it’s been pretty successful.  The only major outstanding calculation left in a pixel shader that I think I can move is the inverse view projection matrix multiplication in the light accumulation shader that uses depth to recreate pixel position in world space.  And I think the information in this thread has everything I need to solve that.  Here’s hoping!

So, that’s it.  I’ve nearly got our particle system working (finally), so hopefully there’ll be a new post up soon about that.  And if all goes well, it should be a two for one with texture animation as well (which I wrote last year, but still haven’t gotten around to integrating into this engine yet).  I’d really like to get it implemented and post about it before heading off to GDC next week, but you know, school.  We’ll see what happens.

Premake, FXC, And You

When I joined Team Fizz over last summer, I was introduced to the awesomeness that is Premake.  Shortly after that, this post on Bobby Anguelov’s blog introduced me to FXC and everything awesome that it could bring to the table.  I instantly wanted to use it.  The problem then became, how I can get Premake to generate projects and include the necessary custom build steps for my shader files to be able to utilize FXC?  I figured this would be a pretty common issue for people and it would either be intuitive to setup or there would be a lot of information online on how to make it happen.  I was completely wrong on both counts and I wasn’t able to make this work until just last night.

Semi-recently, Premake added support for two features that I felt could potentially solve my issue.  The buildrule function was supposed to allow me to set a custom build rule to files based on a configuration declaration, and this sounded like it would directly be the solution I was looking for.  I could just have the shader files in my project, the configuration declaration could look for files based on extension to apply the build rule to, and everything would work.  I’m not sure if we just didn’t set it up properly (the documentation for this feature isn’t great) or it just doesn’t work right, but it didn’t do what I needed it to.

The second option was project reference through the external function.  While less optimal, the plan was to manually create a project for my shaders, set the custom build tool on each shader file to use FXC, and then have Premake just add this project into the sln when it creates and links in all other projects.  This is what ended up working for me, so I thought I would document what I did in case anyone else runs into this issue.  I know I would have appreciated it about 6 months ago.

In your build script, assuming a current enough version of Premake, you can use the external command to reference a pre-existing project into the sln being made.  Just slide the command in anywhere that you would add “project” for a project that you wanted Premake to autogenerate, and make sure that you add the name to the startup project’s links so that the proper build dependency is made.  Here is what mine looks like:

 

 

Shader is the name of my vcxproj, which is what comes after external.  It’s also in a folder named Shader at the root of my sln directory, which is what goes in location.  Setting the kind to StaticLib (and making sure you actually set the project to match) might not be necessary, but it fit the rest of the architecture of our engine.  Uuid can be found by opening your vcxproj in notepad and looking for this:

 

  <PropertyGroup Label=”Globals”>
    <ProjectGuid>{7CF9442C-12F8-4675-9CE2-D54FEC4C31D0}</ProjectGuid>
    <RootNamespace>Shader</RootNamespace>
  </PropertyGroup>

 

Once you have the project made, setup, and your buildscript ready, you just need to setup your shader files’ properties to use FXC.  The link to Bobby’s blog from earlier in this post completely details the process so I won’t repeat it here.

So, there you have it.  I won’t say this is the best way to accomplish what I wanted, or even necessarily a good way, but it’s a way and it works for me.  Hopefully if anyone finds themselves in the situation I was in, it will be helpful.  And if anyone has a better way to solve this, please let me know; I would love to get that kind of feedback and improve things.