El-Cheapo Fullbrights

Post tutorials on how to do certain tasks within game or engine code here.
Post Reply
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

El-Cheapo Fullbrights

Post by mh »

This one ain't a copy and paste tutorial.

So, here's a way of using the same texture object for fullbrights as you use for the main texture. Neat for saving on texture memory, faster loading times, and may run faster if your hardware is able to figure out that it can cache the result of a texture lookup and reuse it rather than needing to do a second texture lookup.

I'm assuming that you've got multitexture and a minimum of 3 TMUs available. If neither of these apply you can still get the texture memory saving but you'll need to figure out the blend modes for yourself.

You'll also need to do more work yourself if you've got external textures or a legit use for BSP or MDL textures with an alpha channel.

On to the info.

First thing is that we build a second copy of d_8to24table; this one has an alpha channel of 0 for entries below 224 but it keeps the same r, g and b. Entries 224 and above are the same as your regular d_8to24table.

Then we use that as the palette when uploading a texture that has fullbright colours in it.

Finally when rendering, we set up our texture environment for these textures like so:

Code: Select all

// diffuse - regular texture
glActiveTexture (GL_TEXTURE0);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

// lightmap - optionally use GL_RGB_SCALE for overbrighting
glActiveTexture (GL_TEXTURE1);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

// fullbright
glActiveTexture (GL_TEXTURE2);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
Now we just bind the regular texture to both TMU 0 and 2, the lightmap to TMU1, and draw. That's it. The GL_DECAL environment will give you the following result:

Code: Select all

(tex * lm) * (1.0f - tex.a) + (fb.a * tex.rgb)
Which is exactly what we need for fullbrights - areas covered by fullbright pixels are replaced by them, areas not so covered are left alone. Result.
Last edited by mh on Sun Aug 14, 2011 10:52 pm, edited 1 time in total.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
metlslime
Posts: 316
Joined: Tue Feb 05, 2008 11:03 pm

Post by metlslime »

Nice.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Post by Baker »

Make a d_8to32table with colors 224 and greater will have alpha of 1.

Upload all textures with any fullbright pixels as 4 bytes per color (RGBA, BGRA, whatever).

Turn on ALPHA_TEST during fullbright drawing pass.

No need to maintain a fullbright texture at all. No fullbright texture to upload. No multiple tables to maintain.

Just a thought.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
leileilol
Posts: 2783
Joined: Fri Oct 15, 2004 3:23 am

Re: El-Cheapo Fullbrights

Post by leileilol »

mh wrote:this one has an alpha channel of 0 for entries below 224 but it keeps the same r, g and b. Entries 224 and above are the same as your regular d_8to24table.
The end byte of colormap.lmp stores the number of fullbright ranges so you should just be able to 256 - that for the base instead of hardcoding it up to 224 colors.
i should not be here
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Re: El-Cheapo Fullbrights

Post by mh »

leileilol wrote:
mh wrote:this one has an alpha channel of 0 for entries below 224 but it keeps the same r, g and b. Entries 224 and above are the same as your regular d_8to24table.
The end byte of colormap.lmp stores the number of fullbright ranges so you should just be able to 256 - that for the base instead of hardcoding it up to 224 colors.
It's also possible to scan down each column and check for colour changes. If there are none - it's fullbright.

Problem 1 there is that column 0 in ID1 is all black so that will also register as fullbright.

Problem 2 is that a mod can contain a weird colormap, with some columns possibly having an inverted range.

A variation of this trick can handle fullbrights and regular textures in a single pass without needing to even do any state changes between them. Use the same state for both.

Big problem occurs with coloured light and overbrighting. It's sometimes the case that the final combination with the fullbright comes out darker than if the fullbright was not used. You can see this at the red arrows pointing to the e1 entry in the start map. Solution is to calculate both and take the max, but that needs a shader.

Another idea is to upload the colormap as a texture, upload the raw palette indexes for each texture (using a GL_INTENSITY formatm you'd also need to use the 8-bit mipmap and resample functions, and GL_NEAREST_MIPMAP_NEAREST for the min filter), then do some dependent texture lookups in a shader. That would give you an almost exact match to how software Quake looked. A neat thing about that too is that - if you weren't bothered about coloured light - you can pack all 4 lightstyles into a BGRA texture. So a lookup on the main texture gives you the s texcoord, a lookup on the lightmap gives you the t, then use those for a third lookup on the colormap texture. Like I said though - needs shaders, and I'm not certain of how it would interact with dynamic lights.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
metlslime
Posts: 316
Joined: Tue Feb 05, 2008 11:03 pm

Post by metlslime »

Just wanted to mention, that some of the proposed ideas could add complexity when supporting external textures. Most (or all?) external textures were authored to use additive blending rather than alpha blending, which means if your pipeline is set up for alpha blending you will need a special case for external textures. (this is why i switched to additive for all fullbrights in the last version of fitzquake, so that the renderer doesn't have to care where the texture came from.)

On the other hand a special case could be worth it if it means the main path can be really fast.
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Re: El-Cheapo Fullbrights

Post by mh »

mh wrote:You'll also need to do more work yourself if you've got external textures or a legit use for BSP or MDL textures with an alpha channel.
;)

Simplest approach is to just calculate the light blend as normal, then take the max of that and the fullbright image as the final fragment colour. That also deals with situations where the fullbright colour is going to be darker than the normal light blend - this happens in a few places in ID1 maps.

Image
Image

I guess you couldn't do it with the fixed pipeline though...

The "use the same texture" approach is ideally suited to situations where you might be memory-limited, in which case having it not work with external textures is the least of your worries. If you're already memory-limited with a few extra 64x64 textures, I guess that loading loads of 512x512 textures is not something you're going to be wildly interested in.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
Post Reply