Sponsored By

Mini-postmortem #1: Soft Particles Rendering

In the first post of my "mini-postmortem" series, I discuss my experience implementing the "Soft Particles" technique. I briefly explain why I made this demo, and go over what went right and wrong.

Gustavo Samour, Blogger

May 15, 2011

6 Min Read
Game Developer logo in a gray background | Game Developer

Intro

A few months ago, I found myself looking for new employment. One of the companies I was applying to asked for a code sample. Unfortunately, I couldn't show any of the code written at my previous job. I considered submitting some of my old code, but decided against it for two reasons. First, my coding has gotten better over time.

The older my code was, the more I would have had to "touch it up" to feel comfortable sending it as a portfolio piece. Second, some of my projects used extra tools and/or libraries. Even if I packaged everything together, anyone wanting to build and run my code had to at least install a few things.

After looking at several options, I landed on making a Soft Particles demo because it was a small project with enough code that would look cool. This would still require installing a couple of things (Visual Studio Express and DirectX SDK), but these are pretty easy to set up compared to other tools/libraries.

What Went Wrong

1. Being in the "this is a demo" mindset. Knowing I was making a demo kept me focused, but it also allowed me to write some code that I disliked afterwards. It wasn't awful code for a demo, but it definitely didn't scale well. For example, I made a few functions to create my resources like so:

CreateModels(Model** ppBox, Model** ppPlane);

If my world was made up of just boxes and planes, this is not bad. Even if I added another model, three parameters still doesn't seem so bad. But it gets worse:

CreateShaders(VShader** ppSceneVS, PShader** ppScenePS);

In this case, if I wanted to add a new effect, I would usually have to add two parameters, one for a vertex shader and one for a pixel shader. And it gets even worse:

CreateTextures(Texture** ppCrate, Texture** ppSky, Texture** ppFloor);

Even if I did have a world made up of boxes and planes, each would likely have a different texture.

The way the code was set up, these were functions inside my main.cpp and I had written both function prototypes at the top with their definitions at the bottom, leaving my main  function in the middle. So every time I wanted to add a resource, I had to change it in three places: in the prototype, in the function call, and in the definition. Even if this was just a demo, it would have been better (and easy enough) to open a list of resources from a file, then load those and reference them by name or ID.

2. Using DirectX9 shader interfaces instead of the Effects Framework. There's nothing wrong in using IDirect3DVertexShader9 and IDirect3DPixelShader9 for your shaders, and sometimes it could be desireable depending on your material system. But coding this demo would have been faster if I had used ID3DXEffect instead. All my shader files for this demo could have been merged into a single effect file. Also, even with the simple shaders I was writing, I had this issue at one point where my vertex shader output didn't exactly match my pixel shader input. This wouldn't have been a problem with the effects framework because I would have created a single struct and would have used it as both vertex shader output and pixel shader input.

3. Not testing on other PC's. I can't stress this enough. I've read many threads on Gamedev.net about people sharing their demo/game only to get feedback that it crashes or doesn't behave as expected. Some ways to get errors like these are:

a) Assuming all video cards support the 3D API's features you're using (forgetting to check device caps).

b) Assuming everyone has a gamepad or joystick.

c) Different version of an external tool/library/file you depend on.

My experience was with a function that had a simple purpose: to read a file. I had a bug where the function would not read the entire file, causing resource creation to fail. I discovered this a few days after submitting the code because I started developing on a different machine. On the original PC, the routine worked fine. But on other machines, it failed.

To avoid issues like these, make sure the user's PC meets the requirements of the program. Test on someone else's machine to see if everything works as expected. As a general tip, it's also important to program with assertions. If you assume something to be true, assert it!

What Went Right

1. Having a clear goal from the beginning. I'm glad I decided to code a demo for "Soft Particles" instead of "A Small Game" or "Something Cool". Knowing exactly what I was writing helped me make a list of the C++ classes, models, shaders, and textures I needed. Once I had the list, it was just a matter of taking one step at a time.

2. Using simple models and free textures. Instead of trying to use fancy 3D models or custom textures, I decided to generate boxes/planes in code and download free textures. Given that this was meant to be a code sample, the complexity and source of the assets was almost irrelevant. It would have taken me longer to put this demo together if I had made the assets or selected them for purchase and it wouldn't have added value to the code. Plus, it's really easy to compare hard and soft particles when they're intersecting with a box:

Soft Particles Off:
Soft Particles Off

Soft Particles Off




Soft Particles On:
Soft Particles On

Soft Particles On




3. Having a paper to start from. Aside from having a clear goal from the start, something that helped me finish the demo faster was using a guide. Instead of gathering information from multiple online sources, I downloaded the NVIDIA paper:

http://developer.download.nvidia.com/whitepapers/2007/SDK10/SoftParticles_hi.pdf

It's very straight-forward. I read it once, then went back to specific pages for reference.

Conclusion

Sometimes, certain key features are worth coding, even for a demo. Some don't take up as much time as you think ;) It's important to add checks in your code, and to test on multiple hardware configurations.

Try to have a clear idea of what you're trying to accomplish before you start writing code. Don't use fancy assets if you don't need them. Sometimes the basic ones will show off your project best. Also, it's usually a good idea to get your information from a single trusted source. That way you won't have to spend time "converting" information from different sources to match your setup.

Oh, and if you're wondering what happened with that job application... I can happily say the company was interested in me after looking at the code sample :)




EDIT: You can check out a video of the demo in action here.

Read more about:

Featured Blogs
Daily news, dev blogs, and stories from Game Developer straight to your inbox

You May Also Like