Development Diaries, Volume 9
Posted by Alex Jordan on
Well, let's just dive straight into it:
That, kids, is what we call "specularity", which is a really fancy term for "surfaces angled in a precise way so that it catches a beam of light and directs it right into your eyeballs." It's what makes bodies of water at dawn such a delight to look at. And it's also what makes you a complete prick because your iPod screen keeps reflecting light into my eyes on the Metro, for fuck's sake, point that thing elsewhere, God.
Oh, right, I guess some more technical explanations are in order.
The specularity is pretty easy, although attempts to write the shader code on my own kept ending in defeat. (I had to use a tutorial. Sigh.) It figures out where the light is coming from, where a given beam of light hits the surface of the water, and accounts for the normal map on the water surface. (Which, if you remember, allows me to figures out per-pixel surface direction so that I can do either shadow mapping or refraction.) It then bounces the light off that surface, and, if that beam of light reflects directly back into the 3D camera position: voila! White specular highlights!
You'll notice the specularity looks great when the light source is moving. It also looks pretty crappy when the light source isn't moving. That's because the refracted water effect is just the result of me constantly panning the water plane's normal map to the bottom right. That makes a neat refraction effect, sure, but the normal map is a static image, so the surface directions on it constantly stay the same. That means, if a particular wave is always pointing to up and to the left, it will always reflect light up and to the left, even if the image itself is moving. The white specular highlight will always look the same, even when the position of that highlight changes because the image is panning down and to the right.
Why is this? Because the surface of a real life body of water is constantly rippling with waves. Mine doesn't, it only uses a single normal map and just blandly pans it along. I could have the 3D surface of the water undulate, which might help, but I'm not sure if it's worth the extra effort. I'll look into it. Anyways, I plan on having Around The World utilize a constant day-to-night transition, so the light source will always be moving, no matter what. Problem solved?
Okay, remaining graphical to-do list:
- Fix normal mapping issues on the Xbox 360
- Finalize the water background and make it higher-contrast so that it shows up better on TVs (I'm currently using a transition from shallow sand to water on my Xbox 360 version. It looks like crap, of course: sand would be a natural transition from a topography map, but not a Mardi Gras-colored political map. Yuck.)
- Have the program figure out whether the game is running on a PC or an Xbox 360, and have it adjust accordingly for Widescreen or Standard displays.
- Put the camera into orthogonal view instead of perspective view, so that the Selector Icon (which currently shows the light position) always faces the exact same way
I'm also playing around with a toon shader for the Selector Icon, experimenting with edge detection and drawing cartoony borders. But that's basically just me screwing around. I've been so focused on learning HLSL these past few weeks that it's a bit daunting to realize that my graphics engine is almost done and that it's time to actually work on my game. I've gotten pretty good at writing code in HLSL, so it stands to reason that I'm reluctant to dive back into C# and XNA programming, as it'll mean sailing back into uncharted waters on new concepts, like saving and loading from the Xbox 360, Xbox Live Leaderboards, and all sorts of fun things that I need to learn from scratch.
Which is never, ever an excuse. These things have to be learned. I'll just resolve those four bullet points, and then, boom! I'll be off and running. Around The World for Christmas, anyone?