Transparent Textures are poo


MaRzY
02-14-2004, 07:56 PM
I don't know how none of us have noticed this before, or not mentioned it, and i'm sure it's not just on my PC. But transparent textures, really mess up your skins. And it seems the darker the skin using a transparent flag, the worse it looks. It seems to posterize the image some what, and adds colours that where never in the original skin, like purple etc. So my advice is if you can get away with out using transparent textures for your models, then do so. If not your better off, remaping the transparent parts of the model to a new UV map, as the difference it makes to a finished model, is very noticeable, especially with dark skins.

Trp. Jed
02-14-2004, 08:43 PM
I remember something when I worked in print design about darker colours banding more than lighter ones. Its something to do with the fact that we perscieve luminance more than actually colour I think.

As for transparent texture, yes I've noticed to that when a texture is toggled between transparent and non-transparent it seem to produce an effect like reducing the number of colours in the images palette.

The same effect is evident in HLMV and I'm wondering if its actually something in OpenGL about handling RGBA textures as opposed to plain RGB.

Saying that, in HLMV all textures are treated as RGBA just all the alpha bits are set as black.

- Jed

Genie
02-15-2004, 08:14 AM
Yeah, I noticed they reduce the texture quality. But that just gives modelers an excuse to make their models more high poly. :D

Mortar
02-15-2004, 10:02 AM
I've lately started to use transparent textures, just learned the trick few weeks ago, anyway... i did not notice any change in the texture quality, maybe it's because i used it for small parts but it looks fine to me.

anyway... i think it's better to use it for small parts of the model instead of adding more polygons and acctualy modeling those areas, saves lots of trouble, uv maping and reduces the poly count and improve your system performance.

again... i never checked the issue with large models, if i will ever do something like that then i noted your warning ;-]

MaRzY
02-15-2004, 11:00 AM
Here is a picture showing the same skin taken from my revised Mk 5 sten, the picture on the right is the one with the transparent flag enabled, where as the one on the left is the same skin without the transparent flag enabled, you can see the difference it makes. I intend to fix this and re-release it, by remaping the transparent part, the cooler sleeve, and other transparent parts the model uses, to there own Uv map.

Difference in quality pic (http://homepage.ntlworld.com/scitzo/transdif.jpg)

blyind420
02-15-2004, 11:37 AM
cool, i never noticed that b4, im glad i know know for future referance.i guess i got lucky by remapping the lenses on the gasmask of ssv4 by devin to a new uv map.

Trp. Jed
02-15-2004, 12:02 PM
Hmmm, I wonder if its downsampling the image to 16bit.

Cant remember what the numbers are now but theres a format something like
R4B4G4A4 which only uses 4 bits as opposed to 8bits per colour channel.

Maybe OpenGL is doing this automatically - downsampling it from 32bit to 16bit.

4bits per channel would explain the banding.

- Jed

Silverghost
02-15-2004, 12:59 PM
Textures in HL are 8bit. Well the one used for models are, they are indexed so the are made 8bit.

R3G3B2

So there is no real A channel. HL maps the blue as transparent.

I'm no expert at this, as you can probably tell, but I'm guessing that the blue dots take away from the data that could be used for the rest of the metal texture. The 2 bits for the blue channel is proably causing the banding.

Or something else along these lines...

MaRzY
02-15-2004, 01:09 PM
The transparent texture does not have to be blue, it can be any colour, as long as it's the last colour in the textures palette. Most peeps use true blue 0,0,255 because the odds of having this colour elsewhere in the texture would be slim.

Trp. Jed
02-15-2004, 01:12 PM
That might not be true for OpenGL and Direct3D modes.

The rendering code for HLMV which is based on the HL SDK takes the texture, looks up the RGB value in the palette for each pixel and does a direct conversion to 24 bit RGB.

The palette has 256 entries with a R,G,B value for each. The image data is just a chunk with 1 byte (8 bits) for each pixel telling it which palette entry to use. The actually colour components is taken from the palette.

All that happens is an alpha channel is constructed by saying that all bytes are opaque, except any entry which has a palette colour of index 255 which is made 100% transparent.

- Jed

Silverghost
02-15-2004, 01:23 PM
How does that explain the banding though?

ripa
02-15-2004, 04:02 PM
The problem's at the user's end. My textures were posterized just like that, but after messing around with drivers the problem is gone.

Trigger
02-15-2004, 04:06 PM
Do elaborate, ripa.

MaRzY
02-15-2004, 05:05 PM
Originally posted by ripa
The problem's at the user's end. My textures were posterized just like that, but after messing around with drivers the problem is gone.

That explains maybe why i never noticed it before, because i changed my graphics card over Christmas to a ATI Radeon, where i had a nivida before that.

Trp. Jed
02-15-2004, 05:08 PM
I still get it an I just got an FX5200 card. Its not that pronounced though.

- Jed

Cheeto
02-15-2004, 05:56 PM
I brought this up a long time ago, that's why I asked for that high poly, re-skinned bazooka of Dillingers' to be released without transparency.

ripa
02-22-2004, 02:08 PM
Sorry I was away for a week. I think it's that texture compression option that's making the textures look horrible.

Trp. Jed
02-22-2004, 07:14 PM
Do you mean the "cliptotextures" option?

I noticed that too, in fact, when I compiled my U-boat I cropped down the textures by hand and compiled it with a different STUDIOMDL from the 1.1 version and the textures looked much better.

BTW; anyone noticed that $cliptotextures no longer works in the 1.1 compiler?

- Jed

Mortar
02-23-2004, 06:35 AM
I never understood what does cliptotextures stands for, can some1 explain it for me?

MaRzY
02-23-2004, 06:48 AM
"cliptotextures"

If you don't use this command in your QC file, when you compile your model it will crop the textures to the edge of you UV mesh. The only problem is, it's not very good at it, and you lose some quality. So one way to make a better job of it, is to crop the image by hand in Photoshop, as it does a better job. I try to stay clear of not using the cliptotextures command though, because if it crops your image to a size thats not dividable by the power of 2, halflife only resizes it ingame to a size that is, which again i would think you would lose some quality in doing this. I may be wrong though as i'm no expert, but i think it works this way ingame. I just think, it must be better to use a texture that is of a size, that halflife can use without it having to resize the image ingame.

Trp. Jed
02-23-2004, 08:35 AM
Marzy,

I had one of my insomnia bouts last night and sat up at 4am staring at the source code for STUDIOMDL and HLMV again trying to make some sense of all this.

When STUDIOMDL clips the texture its actually not that bad. It doesn't do any re-sizing of the texture - all it does it look at the maxium square area of the texture that the UV Map covers and crops the image down to that.

You can get proof that it doesnt have a detrimental effect on the texture internally by exporting it from HLMV to a BMP and looking at it. While its blurred in HLMV, the exported BMP is the same as your original, just cropped smaller.

Now, as for the blurring in HLMV there appears to be a couple of known "issues".

First up, its a requirement for compatibility with OpenGL and most 3D graphic cards that textures, when in the cards memory need to be power-of-2. I think some of the newer ones can handle non-power-of-2 sizes with the relevant OpenGL extensions, but its down to drivers. Anyway, one assumes because of its age, the HL engine expects power-of-2 anyway when dealing with textures internally. Saying that, seems that one comment in the source seems to only check their multiples of 4 but thats not reliable enough to base anything on.

Now, when HLMV loads the texture from the MDL it has to scale it to the nearest power-of-2 size based on the textures width and height.

If during compile STUDIOMDL cropped your image down to say 400 x 508 pixels what it does is stretch the image out to 512x512 using a pretty basic routine. OpenGL actually has its own routine built in for doing this but its so slow its ridiculous.

The problem is that to stretch the texture out to the right size, it needs to blur things a little in the process which is why textures always look so damn bad.

Basically what it boils down to is that if your textures is NOT a power-of-2 texture inside the MDL file post-compile, HLMV will be forced to stretch and blur it for compliance. The closer your texture is to the next power-of-2 number the less it will have to be stretched.

However, if your original textures are power-of-2 HLMV will NOT stretch the texture. For this reason, many people use 512x512 textures and $cliptotextures to force the texture NOT to be clipped. That way HLMV will not have to re-sample and stretch it.

Onto other things...

As I said earlier it seems that support for non-power-of-2 textures is hardware specific and dependant on your hardware drivers. This article (http://www.gamedev.net/community/forums/topic.asp?topic_id=204373) touches on the subject a little.

To summarise what's been said as non-technically as I can, the ability to handle non-power-of-2 textures is device specific. In the case of some cards the following limits may apply:

- The texture can be no bigger in width or height than 256 pixels.
- The texture must be a square, i.e. have the same width and height.

There is also the issue that IF your card is unable to handle non-power-of-2 textures, the cards drivers may re-size the texture for you. You could have the following nightmare situation - HLMV scales your texture UP to 512x512 but your graphic card can't handle textures that big so the drivers scale it back down to 256x256. Welcome to crap texture city...

I used OpenGL Extension Viewer (http://www.realtech-vr.com/glview/) to check my card and it says I'm ok for textures up to 4096x4096 but other people might find there card has limits.

Truth is, with a lot of work I could probably improve the rendering in HLMV but I run the risk of "false advertising" as I don't want to end up making stuff in HLMV look better than it every would under the HL engine!

As for transparent textures blurring, Im working on that but you'll need to be my beta tester for that Marzy.

- Jed

Dillinger
02-23-2004, 10:51 AM
I've gotten this stuff a lot, too. If I use a model with transparency in DoD running in 16bit, it makes the textures ugly, but as long as I run DoD in 32bpp it works fine and there's no texture degredation at all.

Trp. Jed
02-23-2004, 11:34 AM
I think I mentioned before, it could be how the driver handles downsampling a RGB + Alpha texture which is 32 bit down to 16 bit. I think it drops a number of colour bits which results in the texture looking crappy. Does the same thing on my machine if I'm running in 16-bit mode.

- Jed

MaRzY
02-24-2004, 09:12 AM
So it seems that transparent textures get down sampled in HLMV and HL, and running HL in 32bit or playing with different drivers can help fix the problem. Trouble is because we all use different drivers and hardware, and don't all run in 32bit, these solutions wont benefit us all. So for now at least, the only way i can see that all can benefit, is by re mapping the transparent parts of a model to there own UV map. Then it does not seem to matter what drivers, hardware or colour depth your using. And although the transparent UV map still gets down sampled, it's hardly noticeable, because the parts are small, and no longer effect the main skins.

About cropping, if HLMV is showing a cropped texture as blurred, then i guess it's the same for HL, so is it not best to avoid using, not unless you crop the image down to a size that equals the power of 2. Because it just seems to me that leaving a texture at a size thats equal to the power of 2, would be the best way to keep maximum quality. Which brings me on to a method i've just come up with, that allows you to have control over clipping textures to the power of 2.

Lets say you have remapped the transparent parts of a default model to there own UVmap, and arranged them to fit nice and neat as possible without resizing them, you will notice theres alot of wasted UV space. One way to get around this would then be to resize the UV map to fit the UV space better, but this can lead to problems, when resizing the saved out UV bmp image to fit the original parts of the texture in your paint package. So an easier and more accurate way of doing this is to use a triangle. So we arrange the transparent parts to take up as little room as possible, without resizing any of the UV map, thus leaving them the same size and shape as they where on the original textures. We then make a flat two polygon triangle square, and UV map it to use the same texture as the UV transparent map. Then if you resize the square on the UV map, so it fits around your transparent parts, you may end up with a rectangle, but thats ok, you just need to make sure that on the UV map it's of a size that is equal to the power of 2. You then delete one of the triangles that makes up your square or rectangle. You then resize and move your left over triangle and hide it in the right sleeve and assign it to bone 5. Then when you compile your model, without using the $cliptotextures command, it crops your transparent UV map to a size that equals the power of 2, so once ingame, it does not get resized and lose any quality. You can also use the method to stop other textures used by the model getting clipped, just remap a square using the same texture as the UV map you don't wont clipping, and make it so it covers the whole of the UV space. Then delete one triangle as before etc, and compile. It does provide much more control over clipping, and with only using one triangle for each UV map it's efficient.

What would be neat is, if someone could add a command or 2 to the compiler, so we had control over what textures get cropped and which don't, and that it always crops the image to the nearest numbers that are equal to the power of 2

Originally posted by Trp. Jed

As for transparent textures blurring, Im working on that but you'll need to be my beta tester for that Marzy.

- Jed

I don't mind being your beta tester, as long as you don't use the whip this time around.....:).

Trigger
02-24-2004, 01:28 PM
I don't see why all that is necessary, what's wrong with just using $cliptotextures? You should always do whatever cropping and resizing yourself before you compile the model anyway.

If, as in your example, you assigned a few faces that would include transparent textures to a new UV map, you don't need to waste texture space and memory to keep the size square. The simplest way to not waste any space and still keep the size of the UV maps realative to the others, is to resize the UV's to fill the entire map, and then simply resize the entire texture down to a size where you can copy over the transparent textures onto the new map. UV maps don't require the corresponding textures to be a certain size, only the proper proportions. There would be no problem scaling your uv's up, then sizing the entire texture back down so they are still the same relative size as when you started. Poorly explained, but a much cleaner method, unless there's something I'm missing.

Cheeto
02-24-2004, 01:53 PM
Originally posted by Trigger
I don't see why all that is necessary, what's wrong with just using $cliptotextures? You should always do whatever cropping and resizing yourself before you compile the model anyway. Because cliptotextures doesn't really work on my machine...

MaRzY
02-24-2004, 02:30 PM
Originally posted by Trigger
I don't see why all that is necessary, what's wrong with just using $cliptotextures? You should always do whatever cropping and resizing yourself before you compile the model anyway.

If, as in your example, you assigned a few faces that would include transparent textures to a new UV map, you don't need to waste texture space and memory to keep the size square. The simplest way to not waste any space and still keep the size of the UV maps realative to the others, is to resize the UV's to fill the entire map, and then simply resize the entire texture down to a size where you can copy over the transparent textures onto the new map. UV maps don't require the corresponding textures to be a certain size, only the proper proportions. There would be no problem scaling your uv's up, then sizing the entire texture back down so they are still the same relative size as when you started. Poorly explained, but a much cleaner method, unless there's something I'm missing.

Yes i understand what your saying Trigger, but this might work well for UV maps that are square, but if your original texture was say 256x128 that one transparent part came from, and another part off a 512,x512 etc, then resizing can be a pain in the arse, because some pieces you have to just resize, others need to be stretched and resized, and then you have the playing around in photoshop to resize the UV image to match the original texture sizes. You also run the risk of changing the UV's original shapes, and even knocking these out by one pixel, can cause problems, with transparent textures not lining up right etc. It's far easier to use the triangle method, and not only have you got control over what size the image gets cropped down to, you also have no resizing of UVmaps or UVtextures. And by having control over what size an image gets cropped to, means we can always crop are images to a size that equals the power of 2. Which means an image cropped this way, will not be resized by HL and look blurry ingame like most cropped textures do, due to the fact they have been cropped to a size that does not equal the power of 2.

So as i'm seeing it, to get the best results and keep the maximum quality from using transparent textures, and cropped images for everyone. Is to use a separate UV map for transparences, and keep cropped images to a size thats the power of 2. This way nothing gets resized by HL, and the only skin getting downsampled is the transparent parts, rather then full textures.

I mean don't get me wrong i always use the $cliptotextures command normally, but because i needed to crop one texture, out of 5 that a model was using. I came up with away i could do this without cropping the other 4 textures when compiled. This then lead to me using a triangle sized to the power of 2, so as to keep max quality of the texture ingame. If anyone can tell me any other methods for having full control over cropping then please share.

Originally posted by Trigger
I don't see why all that is necessary, what's wrong with just using $cliptotextures? You should always do whatever cropping and resizing yourself before you compile the model anyway.


How do you know what size to crop and resize your images to, if you have not run the model through a compiler without using the $cliptotextures command in your qc file first.

Trp. Jed
02-24-2004, 03:26 PM
Brace yourself... here comes a long one...

First, when compiling with studiomdl, stick "-p" in the command line. This tells it to force power-of-2 (Po2) textures . What it does is look at your source BMP's and, if they are less that a Po2 in either direction it tiles your original texture inside itself until it does fit into a Po2 bound image.

It doesn't stretch your image, it simply replicates the image in a tiling sense until the original fix the next Po2 dimension. If you don't know what I mean, try it out and look at the textures in HLMV.

The above technique wont shaft your UV Maps and the parts of the texture your using, just replicate parts to fill up the space needed.

Secondly, everyong SHOULD be using Po2 sizes for their texture BMPs. That means that in width or height, its dimensions should be either 8, 16, 32, 64, 128, 256 or 512 pixels.

If your texture dimensions are not one of those values, it will be scaled up to the next highest value. What this means is if your texture has an width of 257 pixels its going to to stretched to 512 pixels which us going to look, well, crap.

Lastly, heres an interesting little thing you may not of considered....

Images need to be Po2 for the sake of compatibility with 3D graphics cards. Its also slightly quicker to handle Po2 size textures if I recall. Something to do with DWORD alignment in the cards memory or something.

Anyway, the truth is, even if you don't use all of a 512x512 texure leave the area's blank and always compile with them as is and the "-p" flag.

But wait! Doesn't all that unused space make a waste?

Well lets see... Textures need to be Po2 for the graphic card compatibility and, at least in OpenGL (and more than likely D3D) they are being converted into RGBA textures before being put into the graphic cards memory. Basically this is what OpenGL refers to as "texture binding".

Now, a RGBA image requires 4 bytes for every pixel in your image, one for the Red, Green, Blue and Alpha component of that pixel.

Lets do some math....

Your original "cropped" non-Po2 texture is say 411 x 500 pixels. Convert that to the total number of bytes needed to store it is:

(411 x 500) x 4 = 822000 bytes

Now, what about a 512 x 512 texture?

(512 x 512) x 4 = 1048576 bytes

Aha! almost 22k more!

But hang on, aren't we forgetting something? The graphic card requires a Po2 texture or it wont be able to use it which means that HL now has to scale our texture up which means that after scaling our 411 x 500 texture is now 512 x 512 which means it is now going to use the same ammount of memory!

So has anyone spotted the catch yet?

Exactly, cropped or not, your texture is going to use the same ammount of memory after being scaled anyway - and being scaled it going to force it to be blurred.

So, regardless of if you use all of the available area for texturing or not it doesn't matter because memory usage is the same. Plus using textures that aren't Po2 means that the HL engine will blur it.

Therefore, by padding out your texture BMPs to be Po2, even if you don't use the space and compiling with the "-p" flag, will result in your textures looking as you want them and without wasting any additional memory.

The only way the extra unused texture space impacts performance is when the model is loaded into memory because it physically needs to transfer a slightly larger file. That said it doesn't take THAT long to shift an extra 100k into memory for a model with 5 512x512 textures.

- Jed

Effexx
02-25-2004, 01:47 AM
my brain hurts after all this... but, thankfully it all made sense...


...

MaRzY
02-25-2004, 02:07 AM
Thanks for the info Jed.

On the model i used the triangle method on, the image i cropped was 256x128 down to 96x128 saving 27kb on the overall model size, whilst leaving all other textures untouched. I've since found out that if you decompile this model, and remove the triangles, you can then compile it again using the $cliptotextures command. So you can get rid of the triangles once used for the first compile. The only trouble is, that the decompile and compile knocks the textures out a little, so they would have to be aligned again to make a proper job.

I've not yet looked into the -p command whilst compiling, but i shall do, although i'm not sure it would have helped me in this case, because i only needed 1 of 5 textures clipping that the model uses.

Trp. Jed
02-25-2004, 05:51 AM
Only thing is that 96 x128 is only Po2 in one direction, which means that HL and HLMV will scale it to 128x128 anyway so for all your tricks to stop it cropping, its going to blur anyway.

If you compile it with -p it will make it 128x128 for you. Im not sure if it crops to the UV map, all I know is that it fills out the missing space by tiling the texture.

- Jed

MaRzY
02-25-2004, 06:05 AM
Oh right i see, so if using the triangle method it has to be a square or if a rectangle it has to divide by half or a quarter etc, e.g 128x64 or 128x32 or 128x16, to stop it stretching, is that right. It's no probs, i can just adjust my triangle so it crops it off at 128 rather then 96, as it's easy to setup using a grid. I can't seem to get the -p command working from out of HLMV, so i've still not tried the method yet, although i would prefer it if i did not have to crop all the textures, even though i know the end result will be the same, apart from seeing tiling on all textures.

BTW when you compile a model in HLMV, can we have it automatically load the model into HLMV when it's finished compiling, as i'm getting sick of doing it manually....LMAO.

Trp. Jed
02-25-2004, 08:03 AM
You know what your problem is? You want the bloody moon on a stick you do! :eek:

- Jed

MaRzY
02-25-2004, 08:09 AM
According to string theory, it already is.........LMAO, infact according to that theory it could be connected to my D*CK...lol

Trp. Jed
02-25-2004, 08:18 AM
I think I just found a new quote for my sig...

- Jed

Cheeto
02-25-2004, 09:22 AM
Originally posted by Trp. Jed
I think I just found a new quote for my sig...

- Jed But what about my quote! :(

Day of Defeat Forum Archive created by Neil Jedrzejewski.

This in an partial archive of the old Day of Defeat forums orignally hosted by Valve Software LLC.
Material has been archived for the purpose of creating a knowledge base from messages posted between 2003 and 2008.