Sunday, January 3, 2010


This entire post turned out to be hogwash. I'm wiping it out to prevent the spread of misinformation. If you are interested in why it's all nonsense see my comment below. Thanks to Sean Barrett for pointing it out. The result of all of this has been positive ignoring the part of me looking extremely foolish. RGBM is more useful than I originally claimed because a larger scale factor can be used or if a fairly small range is required the gamma correction is likely not needed.


sebh said...

I am a big fan of this capcom presentation! (especially concerning their motion and DoF blur methods)

I really like your posts and your investigation on RGBM and RGBD. Concerning the accumulation problem, let's propose a new shader: the blend shader! ;)

Brian Karis said...

I would love to have programmable blending. The PS3 can kind of do it. You can sample the same texture you are rendering to and do the blending in the shader. I don't know if there's any gotchas with that as I haven't done it but the PS3 already has blendable FP16 so it's not really the problem. If you are willing the eat the cost it's there.

repi said...

That's one nice thing about LRB, it has programmable blending (see the Siggraph'09 Beyond Programmable Shading course).

Oh and good post! :)

Anonymous said...

I don't really understand this... is it possible we could get a graph or something?

Or at least an explanation of why dividing by (1/256 ... 255/256) somehow gives you more range than multiplying by (1 ... 255)?

I mean, it seems like the idea must be that you've contracted the multiplier (hence the 5.5 or 6 scalar) to handle some precision issues? But even if so, it's not clear why it's necessary or why these numbers arise. Why would you end up with 65025 vs 51? (As a commenter on the previous post said, where does 51 for 6.0 come from?)

I suspect I'm just missing a step (and an assumption).

Brian Karis said...

Well you just gave me an intellectual kick in the balls. So, much so that RGBD without as I presented it is less useful than RGBM. I hang my head in shame. The problem is I hadn't worked this out from the math side but from the "change things until I get good results" side. You are absolutely correct that an RGBM scale of 255 can be used instead of 6. I don't remember the exact situation I was testing that resulted in 6 being picked but I'm guessing the banding I was seeing was either due to the code not being the same as this final version or something else unrelated.

The theory on why an increase of range made sense to me is the distribution of values is different between x and 1/x. This results in more precision in the lower range. Unfortunately that increased precision is fairly useless because its only increased above 1 because the divisor is capped at 1. Below 1 it devolves to normal 8bit color precision. It's possible that a change to the encoding can take advantage of this property but I don't really care to mess with it anymore.

Since a RGBM scale of 255 has the exact same precision below 1 and the same range with an equivalent cost as RGBD, which one should be picked? I'm going with RGBM because you likely don't need a scale of 255. For instance a scale of 32 gives you a range in 2.0 gamma of 1024. It also gives the equivalent of 11bit color below 1.

Anonymous said...

Whoops, now I feel bad.

I certainly think it's plausible that the 1/x distribution might turn out to be better distributed... it allows darker things to be defined more finely, and coarser accuracy at the high end?

But some testing and analysis is probably needed.

Brian Karis said...

Nah, don't feel bad. I'd always pick truth over comfort. It's funny that links to this RGBD post seem to have spread around more than the RGBM post and you were the only one to question it.

There is a better distribution in the low end but only above 1. From 0 to 1 the only alpha value that is used is 1. If that finer distribution just above 1 can be moved down to start at 0 instead of 1 this property can be taken advantage of. It would cost instructions though. If you are willing to use more instructions storing the log or something like that might be more useful. It isn't really worth it for me to continue pursuing that direction because I don't need an improvement over how I showed RGBD to work here or better yet, RGBM with the scale increased now that you've shown me it works just fine. I'm curious now why Capcom used RGBM for light maps but RGBD for env maps. I went back to the env maps I was encoding and I found that I got just as decent of results with RGBM. There may be a difference because the encoding is DXT5 compressed but they both looked equally fine to me, once again, good enough for me not to spend more time on it. I choose to go with RGBM there as well because it's cheaper due to a scale being needed for both anyways.

Unknown said...

Way late to the party on this one, but .... I think the reason capcom went for RGBD (or rgbdiv8) is the fact that you can easily switch between a map with RGB only to a RGBD map without changing the shader code. DXT1 has an alpha of 1.0 output if there is a color, so input RGB == output RGB. In other words, artists can save space and not use more range, or they can use more range and use more space. The same shader gets used on both with no changes.

Unknown said...

"I'd always pick truth over comfort"

That's a great attitude - I try to do the same, although difficult sometimes.

Steve Sinclair said...

I'm not sure RGBD is complete hogwash - consider sRGB. Naive RGBM normalization will screw up precision in this color space.