Page 1 of 2

A Better Self-Shadowing Bump Map?

PostPosted: Sun Jan 25, 2009 7:27 am
by coder0xff
I finally got around to reading Valve's SIGGRAPH2007 publication on self-shadowing bump maps. I have to admit, I had kinda mislead myself into thinking it was something that it isn't - probably encouraged by peoples over-enthusiasm for it.

Based on images I had seen, I thought they had figured out a way to accurately portray self shadowing from any arbitrary direction of incident light. I would be extremely impressed if Valve had managed to accomplish that. Cause I couldn't image how to accomplish that with only three axes. LOL. Anyway, It seems this is NOT true, after all.

If you take the time to really understand what the article is saying about the calculations, and tangent space blah blah, you realize something. The normal map stores shadows from three different directions - and those are all you get. If you go to an angle directly between two of those angles, you get half and half of those two (not really "half and half", but anyway). As for cave walls, it works pretty good, especially in one direction only. One of those three directions is lined up with the direction the player is facing - so the shadow they "should" see it pretty close to the one they "actually" see. Going the other direction isn't so good though - which is the "half and half" case.

This also means, that if you stay in the same direction of the surface, but change your angle (your slope) that you are shining a flashlight into it, the shadow doesn't grow longer or shorter. It only gets darker and lighter.

TIP: When you use ssbump, make sure one of the "basis directions" of your bump texture is aligned with the most likely direction the user will be viewing it from, for best results. The basis direction you'll prolly want to use, and have your player looking from this direction, is the positive U direction (The RED light)

Now.... the "better" part:

The publication talks about removing the signedness from the map (no negatives) resulting in more resolution and less computations. The new method doesn't require a scale and bias. I say, they should have kept it. If they had, though generating it wouldn't be so easy, they could have SIX basis directions. I'd like to see any body nitpick shadows from 6 different directions, nicely blended together. On top of that, I would be willing to bet that 128 levels of shadow darkness is still more than necessary. I would bit mask each channel into two channels , and that would allow two angles of incident (making for four total really, parallel in which case the face is not visible, 30 degress, 60 degrees, and perpendicular for no shadow) for 6 directions at 64 levels of shadow darkness...

Now THAT would be some believable shadowing...

I would imagine it could be taken further if a logarithmic scale was used to optimize the steps between darkness - however, the computation would be prohibitive on all but the best of hardware. I think that 30 and 60 are probably not the optimal angles really. The tangent of the angle determines shadow length - and that's what we're really concerned with.

Can you imagine if they had removed the goal of preserving texture size and alpha channel?

The image displaying ambient occlusion I think has been doctored to demonstrate the effect. I was just thinking how I would implement it - and it seems like that's how they were saying to do it - though they weren't specific. A hemi-sphere above the surface - the more of the sphere is visible from a point, the more lit it is. The image they show obviously doesn't use this method. I don't think I would cast "rays" at all though. I think I would do it in a strictly geometric manner. The geometry of the surrounding surface can be projected to the hemisphere's mesh and use a boolean operation to remove the blocked hemisphere surface. However much surface area remains of the sphere is the amount of visibility. It wouldn't even have to be done per texel - any coplanar area (imagining a height map) that is surrounded by un-occluded texels will also be un-occluded. That optimization could have been applied to either generation process. You could also reverse the projection of the surrounding geometry onto the surface itself, determining, in chunks, the occlusion of each chunk with only one "chopping" of the hemisphere.

It seems to me that Valve needs to hire some engineers. Not that I'm one. I'm just a guy who joined the Army instead of going to college.

If you made it this far - you are obviously some kind of geek :-p . Congrats for hanging in there with me! hehe.


P.S. Sry, there are no pretty pictures - but if you even bother to read this, you prolly are smart enough to make them up in your head. ;-)

Re: A Better Self-Shadowing Bump Map?

PostPosted: Sun Jan 25, 2009 7:38 am
by korge
Wow just for the sake of 3amnothingtodo I read all that and really havent a clue as to what any of the means.

Sounds interesting though. Thanks for the article. Maybe someday I will understand.

Re: A Better Self-Shadowing Bump Map?

PostPosted: Sun Jan 25, 2009 7:53 am
by ad_hominem
Really good. You wrote it in such a way that I understood what you were talking about where otherwise I'd have had trouble getting my hea round the subject. Plus you end with a self-esteem booster, which is always nice :D.

Re: A Better Self-Shadowing Bump Map?

PostPosted: Sun Jan 25, 2009 8:04 am
by coder0xff
Thanks. Usually my technical writing is incomprehensible. Glad you enjoyed it. (And coming from the freshest news guy - I feel special. lol )

Re: A Better Self-Shadowing Bump Map?

PostPosted: Sun Jan 25, 2009 9:49 am
by xoqolatl
Very nice!
As to why they kept "the goal of preserving texture size and alpha channel?" - notice the paper is titled "Efficient Self-Shadowed Radiosity Normal Mapping". Based on the data from Steam Hardware Survey, Valve's conservative approach to expensive real-time effects is a good one.
And about ambient occlusion: they are using it to generate bump maps, not in real time. Means that Valve has a tool that takes bump map and height map, does some ray tracing and gives you ambient-occluded bump map. This is very different from UEngine3 or CryEngine2 AO (or SSAO).
Valve wrote:We implemented an efficient multi-threaded SIMD ray tracing system
[Wald et al. ] in order to perform the hundreds of ray intersection
tests per texel necessary to generate accurate directional
ambient occlusion. Our offline utility takes as input an elevation
map and an elevation scale factor. A user-configurable bilateral filter
[Tomasi and Manduchi 1998] is applied to the input image to
reduce stair-stepping, and then 300 rays per output texel are traced
in order to generate bump maps with directional ambient occlusion
in our new format.

Also, I think that 3rd image is a bit wrong. AO is useful in situations where light comes form all directions. In this case, a single, point source of light, shadows would look more like 2nd image and less like 3rd one.

Re: A Better Self-Shadowing Bump Map?

PostPosted: Sun Jan 25, 2009 10:37 am
by coder0xff
I understand why they preserved texture sizes and the alpha channel. They didn't want to break everything like they usually do. :lol: I was just fantasizing about what could be achieved if they started from scratch.

Yes, their ambient occlusion is done before hand. Sorry if I made it sound otherwise. Honestly, I don't know how AO is done in realtime. I imagine it is something like associative light maps or something - low res references to other lightmap points near bye. When one point receives light, all points that refer to it also receive a small portion of the same color. Purely speculation of course.

Re: A Better Self-Shadowing Bump Map?

PostPosted: Sun Jan 25, 2009 11:22 am
by Enraged
Compared to what we had before it's a lot better, but your insight into the issue gives me a lot better understanding of the subject. I have already read the Valve report, but just assumed it literally meant it was making the computations for the shadows density and angle in response to multiple light sources as the game the texture found it in proceeded.I think they made the right decision not risking the alpha channel, but personally, I would have no problem handling uncompacted files, but I know I don't speak for everyone. They should of made an even higher tier resolution of the game that dide properly use self shadowing dynamically. Oh well... :(

Re: A Better Self-Shadowing Bump Map?

PostPosted: Sun Jan 25, 2009 11:47 am
by xoqolatl
Some AO discussions and papers: ... enSpaceAO/ doc/ScreenSpaceAO.pdf
cheapest method so far: ... Buffer.pdf

While it would be nice to have SSAO in Source, I think implementation of any of the advanced methods would be very hard. Also, considering that Source has very little dynamic elements of environment, it perhaps doesn't even need real-time SSAO (on models perhaps?).

Re: A Better Self-Shadowing Bump Map?

PostPosted: Sun Jan 25, 2009 12:39 pm
Is this something Valve could be working on implementing right now? Since we haven't heard anything at all regarding Episode 3, I'm thinking that they're working on something awesome to show us.

Re: A Better Self-Shadowing Bump Map?

PostPosted: Sun Jan 25, 2009 5:18 pm
by punky
It is possible, even better, it is already done, Valve just didn't bother to do it yet, the guys at Geardev have already implented it; scroll down to the "The Update" post.
You can create SS bumpmaps yourself by the way;$ssbump

Re: A Better Self-Shadowing Bump Map?

PostPosted: Sun Jan 25, 2009 7:46 pm
by stoopdapoop
hmm, I see. I don't know whether to be dissapointed or just happy with what they've given us (Actually, I'm just happy with what they've given us) But I'm surprised that nobody (including myself) has noticed that the shadows aren't growing and shrinking, only getting darker.

But why was the map signed to begin with, before they made it all SS?

Good stuff, as always coder.

Re: A Better Self-Shadowing Bump Map?

PostPosted: Sun Jan 25, 2009 10:20 pm
by coder0xff
stoopdapoop wrote:But why was the map signed to begin with, before they made it all SS?

Good stuff, as always coder.


The normal map texture is, naturally, not signed in the way we interpret it as RGB values. We don't have negative Red values for example. Though it can be interpreted as having a sign bit (which is also what I would have done, but I digress) The vectors in the tangent space need to be able to point left and right, up and down.

In case any one doesn't understand tangent space, it's simple really.

In object space normal maps, a vector that points up (0, 0, 1) points to the top of the object, down is down, etc - it's all based on the orientation of the WHOLE object. That's why we don't use it. What if Alyx flipped her hand upside down. The vectors that pointed up still point up, even though the mesh should have flipped them over. Why? Cause Alyx's model as a whole is still upright. The lighting would be calculated wrong and you have some bad looking crap.

Tangent space on the other hand, is done from the perspective of each triangle. Imagine our little gnome sitting on a triangle on the back of Alyx's hand. When she flips her hand upside down (ignoring gravity, hehe) it will seem to him that the triangle is staying in one place; it's the rest of the world, including it's lights, that are moving all over the place. So we do the lighting calcs from the triangles orientation. Why is it called tangent space? The tangent and bitangent are the two vectors that lie on the triangle (rather than pointing away like the normal). Those three vectors used together give an accurate representation of how the gnome (and the triangle) have been rotated, and so our "tangent space" normal can be rotated the same way. Voila! - physically correct lighting computation.

Anyway, that's why we need negatives - to represent not only vectors that lean towards the tangent and bitangent, but also the ones that lean away from them.

P.S. The calcs for tangent and bitangent are also dependent on the UV coords, but that's another article.

Re: A Better Self-Shadowing Bump Map?

PostPosted: Wed Jan 28, 2009 9:10 pm
by medestruit
I think this in general is a direct showing of how the Source engine is starting to fall behind. With the 3 axis vertex coloring and lightmapping calculations done in Source, it leaves a lot to be desired when you compare it to some of the newer engines. The mapping hierarchies in Unreal Engine for example are pretty godly in what they're able to compute and output inside the engine. SS maps inside the Unreal engine are pretty dynamic and capable of truly remarkable results. I wonder if Valve will think about building a new engine anytime soon to update it with the times. I understand they have no reason to looking at their playerbase, but I think secretly a lot of us would love to have some of these abilities other engines have without having to learn a new engine entirely.

Re: A Better Self-Shadowing Bump Map?

PostPosted: Thu Jan 29, 2009 5:46 am
by Lord Ned
Don't get me started on the Unreal Ed. For a static-mesh based engine (and not a bsp based) it's way of finding/placing static meshes is horrible.

Re: A Better Self-Shadowing Bump Map?

PostPosted: Wed Feb 04, 2009 6:35 pm
by MrTwoVideoCards
punky wrote:It is possible, even better, it is already done, Valve just didn't bother to do it yet, the guys at Geardev have already implented it; scroll down to the "The Update" post.
You can create SS bumpmaps yourself by the way;$ssbump

Thanks for that.

The main issue with AO is it's ability to look retarded on most images with a lot of complexity, therefore most Heightmaps aren't rendered with AO at all.


This is the same height image you saw within the publication, although computed with AO and some slight jitter testing with Full Occlusion. Computed with 300 rays and 4x AA.

Some more tests I ran, more over using different methods to actually render the final image, whether that be Direct X or OpenGL.


I think the main issue with calculating AO is the images base complexity, most of the time it ends up looking horrible unless the heightmap is actually simple. Then usually valve uses the heightmap in the alpha channel.

This image below uses white squares, and a simple black background, with only two levels of height, due to no shading:


Something I do find interesting is that ssbumps exists in the old Half Life 2 GCF's. There in fact very old it seems, just never implemented until recently, then L4D made a bigger Hoopla about them.

Though I do agree with everything said in the first post, but at least this is way better then using the standard method of bump mapping. This method uses less Texture memory, which in return doesn't jack up the Fillrate as much, giving mapper's obviously more room to play with cooler stuff.