Or it might just be me, in which case, just substitute the "You" by "I" and the present tense with the past tense.
You start with simple, per-vertex shading and think that your sphere looks cool as soon as you use a smooth-shaded model. ("Hey! I can show stuff on screen!"). And you feel the pleasure of taking the first baby crawl.
Then you implement per-pixel lighting, and say wow, this looks so much better. ("Oh Snap! This stuff actually has shape! Look, my icosahedron actually looks like a sphere!"). And you see the beauty of standing up;
Then you add specular lighting, and materials, and wow again, I now have shiny things. ("Wow, this actually looks like smooth plastic! Nice, the floor looks like machined bronze!"). And it is like a baby walk.
Then you texture stuff and think that it is even cooler, you can actually show the earth now. And the baby is actually now a walking toddler.
By now, you are around the 2000's. Ok, graphics cards might not be strong enough to warrant per-pixel lighing, but the idea was there. You still have 12 years of progress to go, but you are on the order of not-completely dinosauric graphics. And now, with the programmable graphics pipeline and GLSL and HLSL at your disposal, it's just a matter of finding it and implementing it, or coming up with something new (hopefully).
Then, you implement normal mapping. And this is really, really wow. Bump mapping of any kind really adds realism to the object itself. Like the aforementioned kid running around.
Exit baby/kid example, enter technical info.
As far as tangent-space normal-mapping goes, I would venture to say that it is also at least an order of magnitude more difficult than all the rest combined. Not because of the math difficulty, although I imagine that for many people it might be hard to wrap around their heads. No, but because tangent space calculation is very easy on theory, but you can bump into many many gotchas, like image handedness, face winding, welds, seams, hard edges.
Exit baby/kid example, enter technical info.
As far as tangent-space normal-mapping goes, I would venture to say that it is also at least an order of magnitude more difficult than all the rest combined. Not because of the math difficulty, although I imagine that for many people it might be hard to wrap around their heads. No, but because tangent space calculation is very easy on theory, but you can bump into many many gotchas, like image handedness, face winding, welds, seams, hard edges.
In reality, the result really rewards you for your pains and the experience is great. So great, that I am happy I was lucky enough to get the wrong winding - I would have missed out on a lot of experience if it worked right in the first try.
That said, I dare say that that the most important addition is shadows, for various reasons.
Getting out of the shader and back to the general algorithms to implement a shadowing algorithm is very good for your Graphics mindset.
Firstly, all the rest we discussed so far have to do with how an object is shown. Which is all well and good, but as an engineer, your final product here is the scene, not the object. Shadows have to do with the scene. The object is your brick and mortar, but you are making a building here. No matter how intricate the object, you really need to sit back and think about the scene, because a collection of bricks will be just that...
To return to the kid example, it's like setting aside the one-foot-in-front-of-the-other aspect of running, and planning the strategy for a marathon.
Shadows take you back away from the GLSL/HLSL you were buried in for days, and get you back to big picture, software design, engineering, algorithms and elegant solutions or ugly hacks territory. There is no hard-and-fast Hardware implementation to grab here (there are hardware optimizations, of course! remember tex2Dproj), you will have to implement your own solution, choosing the algorithms you want, and with tradeoffs.
That said, I dare say that that the most important addition is shadows, for various reasons.
Getting out of the shader and back to the general algorithms to implement a shadowing algorithm is very good for your Graphics mindset.
Firstly, all the rest we discussed so far have to do with how an object is shown. Which is all well and good, but as an engineer, your final product here is the scene, not the object. Shadows have to do with the scene. The object is your brick and mortar, but you are making a building here. No matter how intricate the object, you really need to sit back and think about the scene, because a collection of bricks will be just that...
To return to the kid example, it's like setting aside the one-foot-in-front-of-the-other aspect of running, and planning the strategy for a marathon.
Shadows take you back away from the GLSL/HLSL you were buried in for days, and get you back to big picture, software design, engineering, algorithms and elegant solutions or ugly hacks territory. There is no hard-and-fast Hardware implementation to grab here (there are hardware optimizations, of course! remember tex2Dproj), you will have to implement your own solution, choosing the algorithms you want, and with tradeoffs.
The shadow map. This texture encodes the distance of objects from the light. It is created by using a fake "camera" positioned on the light, and rendering only the depth component on a texture |
The reason is that it is a brilliant, ingenious concept. It puts you in a really new mode of thinking - getting the GPU to do your dirty work without even realizing it by understanding what rendering really is.
Which is, taking the concept of some objects, and record in memory some information about them by utilizing projective geometry. This information is normally color, and the memory is then shown on a screen as an image of your scene, rinse repeat.
Which is all well and good, but, how do you use that to actually render the shadows? (or rather, to hide the shadowed objects from the light!)
In short, render the scene from the point of view of the light, record only the depths of the pixels, and not on screen, but on a texture. Then, do another pass to actually render, and read back these depths to see if a pixel (fragment actually) would be visible by the light (hence lit) or not (hence shadowed). Ingenious.
Which is, taking the concept of some objects, and record in memory some information about them by utilizing projective geometry. This information is normally color, and the memory is then shown on a screen as an image of your scene, rinse repeat.
The principle behind shadow mapping is simple, and is demonstrated on the screenshot below: The scene it shows actually has shadows. But, because the camera is positioned on the light, you cannot actually see any shadows - the objects themselves perfectly occlude them. Because, any point in space visible by the light is, by definition, lit, so, not in shadow. Many of you will find that obvious, but there you have it for those that do not.
This scene actually has shadows. You cannot see them because the camera is positioned on the light. But point in space visible by the light is, by definition, not shadowed. |
In short, render the scene from the point of view of the light, record only the depths of the pixels, and not on screen, but on a texture. Then, do another pass to actually render, and read back these depths to see if a pixel (fragment actually) would be visible by the light (hence lit) or not (hence shadowed). Ingenious.
Typical shadow mapping |
For now I have only implemented classic shadow mapping and a PCF soft-shadow variety. PCF is practically a semi-manual way to multi-sample the effect of the shadow, in order to soften its edges.
You just wow.
Now the kid is really into the professional sports territory. Good, bad, it matters not. But these are no longer toys - if you got that far, I believe it is just a matter of time before mastering the more advanced territory.
No comments:
Post a Comment