October 13th, 2008
Whew — Things have been quite busy. There’s been a few changes in the direction that Dungeon Runners is going to take, as most of you know. Most of my time has been spent writing more code than creating art, which I am largely grateful for. Implementing graphics optimizations and improving the overall visual quality are my chief goals, as well as creating and integrating new items and armor into the game. I feel lucky that I can make sweeping changes on a code level as well as an art level, which is something that many projects don’t really encourage. Anyways, that’s my current focus, and also why I’ve been absent for a while.
I’ve been looking into implementing post-rendering and shadowing systems, so we’ll see where that goes. I’ve also been hacking around with SSE (Streaming SIMD Extensions) and getting pretty good results. I’ve created a particle engine in C++/Direct3D that received a hefty 30% fps boost simply by implementing SSE intrinsics directly into the most intensive calculations. SIMD really is fantastic and I urge every Tech. Artist out there to play around with any SIMD instruction sets/language extensions that you can; it really appeals to my nerdy desire to make things run as fast as possible. I’d really like to get a hold of a CUDA enabled graphics card at home to hack around with. I’ve seen some frighteningly impressive compute demonstrations utilizing CUDA, mostly in the latest GPU Gems 3 book.
I’ll catch you guys next time.
Posted in Game Dev | 2 Comments »
July 28th, 2008
I’ve been writing more and more HLSL these days, both for my own personal enjoyment and to pay for my apartment. I can’t really think of anything else that satisfies both the optimizer and artist in me more than shading programs. They are such compact pearls of code, with nothing that isn’t necessary for their functionality (if we did our job well). Recently I had the joy of optimizing and enhancing quite a few shaders, so naturally the mind begins to think about more that can be done with the simple (N . L) Lambertian lighting equation. We can forgive ourselves, and even welcome the deviation from the physical models of lighting when implementing real-time lighting algorithms. I suppose that’s another reason why I enjoy it — its a mathematical playground. We can scale by arbitrary values, re-insert energy into the system when we see fit, and construct novel solutions to bend the cosine to our artistic will.
The first thing to note about the Lambertian model, aesthetically, is that it is notoriously crisp around the penumbra, or where light turns to shadow. This is due to the dot product’s proportionality to the cosine of the angle between vectors N and L:
N.L = ||N||*||L||*cos(a)
When the lengths of N and L are 1, the dot product is simply cos(a). If we look at cosine we see a steep, near linear drop off exactly at PI/2 radians, or 90 degrees. This corresponds to the 0 dot product when the vectors are perpendicular, exactly where light falls to shadow. Making the choice to alleviate this effect, we can take advantage of cosine’s natural ease-in/ease-out behavior throughout the span of its period. Since we are only concerned with the values between 0 and 1 (negative values are normals facing away from us), we can scale cosine by half, and add .5 to it so that it now resides within the 0 and 1 range. We now have a shading value that “eases” into 0, but it wraps around past the perpendicular normal, so that the backs of our models are lit. This is not necessarily a bad thing. If we want to reduce this effect, we can simply raise our new function to a power to “tighten” up its hot spot, thereby causes the penumbra to contract as well.
Valve refers to this function as a “Half Lambert” term, and I’ve found it especially favorable for approximations of light emitted from broad surfaces, or just creating softer lighting effects. After seeing the difference between Lambert and this model, the eyes will clearly favor the latter.
Posted in Game Dev, Shaders | 1 Comment »
June 14th, 2008
Man, I feel like I haven’t posted in a while. I’ve been very involved with the goings-on at work and on my personal projects, which are both very exciting right now. I suppose that is a measure of happiness, since I can think of many people who aren’t excited with their work, and would rather think on other things! I have been getting more email lately, and I’m sorry if I haven’t gotten to it all as well as I could have. I do like hearing from people that are curious about this or that subject, so I still encourage you to write.
Decentralization
One thing I think about fairly often is how humans tend to architect these monolithic processes and structures. We are obsessed with the be-all, end-all solution to a complex problem. This is very typical when matters like money or schedules are involved, as there is a tendency to impose a lot of control over such situations. The idea is that the more we control a process, or the people in the process, the higher chance of success the process will have. The more time I invest thinking about it, the more I come to the same conclusion. One simply has to look at the world around them (the natural world) and they will see that the universe is decentralized. All systems rely on smaller objects which are allowed to perform their own jobs without really caring about the bigger picture. The vasculature of fungi and plants, cell structures, honeycombs, our own bodies, ecosystems, and on to the massively macroscopic are all great examples. If we also look at the systems in our lives that are the most successful, we will find these same patterns. The Internet is a great example of success in decentralization, as it truly is a fibrous network of connections between many nodes through which our knowledge can flow freely. However, if you look at governmental bureaucracy or bureaucracy in your own workplaces, you will know it to be ineffective.
I’m not saying wanton decentralization needs to happen indiscriminately, only that we ought to heed the successful systems around us, and see how they did it. The more organic our execution is, the more success will we reap. The last thing we need are hurdles to rigidify the creation process. Strict pipelines and processes are a bane to us all — a process should be able to be iterated on, changed, or completely scrapped to suit the goals of the system.
Abstraction
One of the most useful tools for decentralization. When we can trust the components to know their job, and depend on them to do so, the rest of the machine can keep running smoothly. The more trust there is, the less checking needs to happen, the more productivity the system will churn out, and the more the components will feel anthropomorphically satisfied. The more an individual component can rely on itself, the better. This is true for programming, and it is also true for systems of people working together. I’m very proud and humbled by the atmosphere that I am able to work within. Trusting in the individual, transparency, interoperability of processes, and communication are in abundance.
Anyways, I’m on a ramble. The point is, the pattern I’m experiencing is of self-sufficient nodes contributing to a whole. Take that as you will! I am going to see where this all fits into my code/art…
Posted in The Big Picture | 4 Comments »
May 1st, 2008
Hooray Interpolation!
If you ever really want to confuse someone that is looking at your script controllers, just use cubic polynomials to control imaginary splines. All kidding aside, scripted bez. interp. is awesome in 3ds Max for several reasons:
- Its faster than using native Max splines
- It gives full control over the in and out vectors, which animators love
- It really breaks rigs out of the inorganic box of right angles and linear blends
The first point was the real shocker for me. The first time I noticed this was while rigging some bendy cartoon arms that were driven by actual splines. Stretchy bones were strung between helpers that were path constrained along certain percentages of this spline, with constant velocity turned on for appropriate behavior. There was a noticeable slowdown that really took the fun out of animating the rig, so I had to look into other methods. It turns out that this formula saves the day:
(1-t)^3*p0 + 3*t*(1-t)^2*p1 + 3*t^2*(1-t)*p2 + t^3*p3
Where: t is a value between 0 and 1, and p0, p1, p2, p3 are the four points to interpolate through. p0 and p3 are the start and end, while p1 and p2 are the out and in vectors to control the interpolation. Really these vectors are what you are manipulating anytime you work with paths in Photoshop, or manipulate type in any vector-based illustration software (bezier handles). I just plug in the appropriate values into a script controller and I get magically fast interpolation. And since p1 and p2 are the out and in vectors, controlling these values with some control objects that feel like bezier handles lets animators express themselves more intuitively. Features like these are really what makes rigs interesting to create, animate with, and to watch in performance. The audience might not know it, but deep inside I believe they are bored with watching static linear interps. occuring between nearly every relationship in the hierarchy. This definitely isn’t something new, but it is something that should be implemented more often by more technical artists. If only Max splines were fast enough to begin with… but I suppose we have to work within the package the project is maintained in, or get fed up enough to write some C++.
Posted in Skinning, MAXScript | 5 Comments »
March 16th, 2008
Choices, choices
There really are quite a few options when it comes to packaging scripts for deployment. You have the completely MXS-written installer, third party install packages (like NSIS), shell scripts, or deployment via another language like Python. I suppose it depends on the environment, but the most important decision breaker for me is how fast the package can be updated and repackaged. Ideally, any necessary updates should be able to be integrated instantly.
The simplest way to get this fully automated scheme running is just a specified location on the network that all scripts are saved at, and loading these when Max starts with a startup (in /stdplugs for first execution) script. The script directory on the network has a folder structure similar to the Max installation so the load script can simply copy everything directly. This would be completely transparent to the artist, but has a drawback: if you have a set of macroscripts with icons, those icons will fail to load. The macroscripts will still appear in their correct categories (as long as you fileIn), but will lack icons. I believe there may be a method in the colorMan interface in Max 9 that reloads icons, but I haven’t had a chance to look. Anyways, this is a decent method nonetheless for deployment in terms of time to update/repackage/reinstall.
Aside from the auto-load approach, you have various installer scripts and executables that can run outside or from within Max, but all must be loaded explicitly by the user. I’ve used NSIS to package my scripts into a nice .exe with guided installation, but I really find this too tedious for production. It takes far too much time to update the install script, copy files, build the .exe, etc. The process can be automated somewhat by having a script that generates the install script according to a faux-Max directory structure, but this is just another thing to “deal with.” This is generally how I feel about using a third party language like C# or Python to perform the installation. Unless there is already a studio-wide distribution of a particular language, its a hassle to install packages on people’s machines for the sole purpose of installing MAXScripts.
Recently what I’ve been favoring are shell scripts. They can be run at computer startup, or explicitly. What makes them particularly nice is the ability to control a VCS like Perforce to grab the latest scripts, and then perform a looped file copy for the installation. Since its just copying all files in all folders in a certain directory, it never has to be updated. I simply write my scripts, check them in, and keep working. When someone needs scripts, they just run the shell script.
This is what’s working for me at the moment, but if anyone has any alternate methods or points to add I’d love to hear them!
Posted in MAXScript | No Comments »