Shaders in OpenBRF and ingame (for previews)

Users who are viewing this thread


Sergeant Knight
Background: OpenBRF uses OpenGL, while the game (all versions, M&B 1.01, WB, wFaS...) uses Direct3D.
So it is not straightforward for OpenBRF to emulate the shaders used by the game, and to show exactly what you'll see in-game.

However, OpenBRF tries to guess what the game will do and to imitate it, to some extent, in order to give better previews. It uses a few rules of thumb for that.

Currently, the rules are:

[1] if alpha-transparency flags are set in the material, then ALPHA channel of color texture will be used for transparency.
[2] if the material uses a shader with "iron" in its name, then Alpha channel of color will modulate shininess.
[3] if the material uses a shineness map, that it will modulate the shininess (not the alpha) (*)
[4] if the material uses a normalmap, than it can used as normalmap (with or without shininess or alpha). (*) Normalmap is always assumed to be the Blue kind.

[2] overrides [1]. 
[3] overrides [2].

When shininess is enabled (rules 2 or 3, shininess color and exponent are tanken from material, and the game computes the highlight in a pretty similar way of what the game does (I've spied it :wink:)

Feel free to suggest better rules in this thread.
Anything can be used, like the name of the shader, or the "technique" used by the shader.



Grandmaster Knight
I think those rules sound about right.  Trying to think about what exceptions might need covered...

1.  standart_shader_skin_bump_nospec_high uses a normalmap, but does not have a specular map.
2.  grass_shader and flora_shader both presume that the alpha channel of the diffuse is used for alpha.  OpenBRF already handles that nicely, but I thought I'd note it (sorry for being a pedant).

In terms of display, I have a very nice GLSL normalmapping shader for bumpmaps that uses a reflectioncube that would provide a fairly reasonable match, if the specular power could be included.  Let me send it your way.


Sergeant Knight
The main problem, currently, is OpenBRF inability to distinguish when a "Green" or "Blue" based normalmap is being used.
Right now it always assumes "Blue" (whenever a normalmap is defined), so "Green" bumpmap aren't previewed correctly.

(my understanding is that the two kinds of bumpmaps are just the same thing, only with the B and G channel swapped. But I didn't test this actually)


Grandmaster Knight
Green normalmaps are compressed types that are being expanded in the fragment shader, IIRC.  It's supposed to save on bandwidth, and G or R is used because of the bit-depth in DXT1 (again, IIRC; I haven't written a normalmapping shader of that type, and only vaguely remember reading about it in something in a piece talking about Carmack's optimization and other tricks).


Sergeant Knight
mmm, let me check the actual content of these bumpmaps...

it seems the green kind actually consume MORE texture memory and bandwidth: they use DXT5 (whereas the blue kind use the cheaper DXT1).

The green ones use only the channels Green and Alpha, (for the Y and X component of normal respectively), leaving the Z component to be computed on the fly inside the fragment shader (whereas the Blue kind provide Y,X,Z normal coords in the R,G,B channels, respectively).

So, in total, the green kind consumes more memory, more bandwidth, and more GPU porcessing power. In exchange,  it provides a better quality: more bits per texture coords, i.e. less normal quantization. To me, Green seems a poor deal overall. 

Maybe that's why the shaders using the Blue kind of normalmap sometimes are assigned by TW to names like "something-something-new": it could be because they were introduced as an advancement over the "older" ones using the green bumpmaps.

Nevertheless, the games uses both kinds, so it would be nice that OpenBRF complied.


Grandmaster Knight
That makes sense.  I didn't know the G ones were using the alpha.  Weird- if they'd used RG, it'd be about the same effective amount of information, but using DXT1. 


Sergeant Knight at Arms
Dxt1's channels are usually weighted in a way that takes advantage of that already.
0.3086 Red
0.6094 Green
and only 0.082 Blue

I never read up on it but I would assume the Dxt5n (green) normal map compression are also weighted
to only take advantage of two channels.
3dc looks interesting but it would require some new shaders...and still only has the same compression ratio as Dxt5's, 4:1 vs Dxt1's, 6:1.

I haven't really payed it much attention but game developers will turn their uv's so the green channel contains the most details, things like wood grain will look terrible if kept is supposed to help but I never do it (maybe I'll start).
Also from what I have read generating the Z normal in the shader results in a higher quality than even uncompressed textures.

I just took a look at one of warband's dxt1 normal maps and it doesn't appear to be normalized  :???:.

Oh and if you want to generate those green normal maps for some reason, ati compressionator seems to be able to do it. (except they call it DXT5 ATI2n)


Sergeant Knight
Interesting, thanks.

Anyway, maybe OpenBRF can use compression schema as a quick heuristic to know how to interpret the bump. DXT1 => blue. DXT5 => green. That seems to work at least for native.

Not sure if it makes sense to expect that modders are following this rule, though.
If anybody knows elements for or against this, shoot.


Sergeant Knight at Arms
Makes sense, making a rule based on shader seems impossible because bump_static shader uses both versions (dxt1 and dxt5).
Top Bottom