Inspired by one of the many beautiful pictures in The Stargazer's Guide to the Universe, I decided to try again at a procedural nebula shader. This time, I wanted to more accurately portray light passage through the nebula and the dazzling colors of back-lit galactic dust.
Yes, there's a reason why my post count is going to be down this month. It's the trap that every programmer falls into once they start learning 3D programming: the game engine trap. Yes, I'm going to build my own 3D game engine.
I've developed a sort of philosophy on the subject. I used to say that I would never get sucked into a pointless project like re-inventing the wheel; I always said that I would be the "smart" programmer and use the tools that others had created. If standing on the shoulders of giants could get me a job and a nice apartment in California, then I'd do it in a heartbeat. Unfortunately, I know now that it's not that simple. I've come to a realization: you can either spend a lifetime learning the intricacies of an engine that somebody else designed, or you can spend a lifetime creating your own. Either way, you've wasted a lifetime. Nobody wins. Ever.
In defense of my sanity, I assert that one cannot know how something works until one can build it without assistance. Creation is the ultimate proof of knowledge. So, unless you can create an engine from scratch, can you really understand one? I don't want to only partially understand somebody else's work. It's just not who I am. For the sake of A New Reality, I need to start from the bottom.
Don't judge me. You'll be happy that I'm doing this for you, future me.
I spent the entire day taking a first crack at starfield/nebula shaders. I couldn't be happier with the results! Below the output of a single shader that consists of thresholded pink noise (stars), and two turbulent-input multifractal perlin noise layers (nebula density/color).
Couple these results with a procedural planet, procedural terrain, and procedural sunset, and things will be starting to look pretty good for project A New Reality!
After implementing several new features in DirectX, including a bloom effect and a skydome primitive, I experimented with making skies that could pass as acceptable. Though not by any means blown away by the appearance of my procedural clouds (let's face it, when it comes right down to it, perlin noise doesn't look anything like real volumetric clouds), I was quite happy with the overall effect created by the skydome, the bloom shader, and a sunset-style fog.
Note that the cloud shader actually consists of a turbulent perlin noise, which gives the clouds a slightly nicer appearance than simple perlin noise would allow. Interestingly, the seed value of the noise can be animated, along with scrolling of the texture coordinate offset, to produce the illusion of moving, ever-changing clouds. Unfortunately, the technique is quite expensive, especially for high-resolution cloud maps. However, with the rapidly-expanding power of graphics cards, it may be viable to animate a full, dynamic, 1024 res cloudmap in at smooth framerates in the very near future.
My question: "What do you call the family of functions with both a variable base and a variable exponent, such as f(x) = x^x?"
The response: "Just an exponential function...there's nothing variable about that base: x^x = e^(xlnx)"
BAM. And my world came down, just like that.
In my silence over the past week, I've been experimenting a great deal with pixel shaders, hoping to get to a point where I feel that I can use procedural shaders to generate any type of texture - grass, rock, metal, etc. A procedural texture system will be critical in the development of a realistic virtual world.
To aid me in my search, I've created an innovative system (with the rather cheesy name "SlimShady") that writes, compiles, and executes procedural shaders. Not procedural in the sense that the shader generates procedural textures, rather, procedural in the sense that the shader is randomly generated by the program itself. Yes, SlimShady is a program that writes programs.
The real idea behind SlimShady is as follows: I can be working on something on my desktop and have SlimShady running on a laptop connected to my TV, such that the program will write a random shader, execute it and animate the seed value for a minute or so, then rinse and repeat. As I'm working, I can occassionaly glance at the TV to see if the shader catches my eye. If so, I hit return on a wireless keyboard, which instructs SlimShady to save a preview image and the full source code for whatever shader is currently executing. In essence, I can sift through an infinite number of shader permutations without having to touch the code! Not to mention, it makes a rediculously cool display...I could spend hours watching the program go to work on the TV.
Here are a few simple shaders written by an earlier version of SlimShady. The newer ones look even better! Also, note that the shaders are generally animated with a seed value - meaning they dynamically morph in real-time, making them far more interesting than can be conveyed in a static image.