Hi, I am studying the Rural Australia package and can't figure out how a texture channel has been packed and is being used.
The Blue channel in the Normals texture sample:
The comment suggest that two value ranges are being read somehow?
(below image) This is where the Blue channel leads. It looks like a little math is done to derive something useful. I can just punch in some values and make use of the shader, but if anybody can explain in simple terms what is being done here that would be awesome.
I did contact the author but he hasn't responded so far, if he does I'll pass on any info here.
Replies
from the author:
Hi!
There's a need to pack textures as tightly as possible in order to have as few texture fetches in shaders and less (texture) memory. There is a trad-eoff with quality however, some textures need high quality, and others don't. Normal maps typically need high quality as pixellation can otherwise be quite noticeable in the final result. Depending on your texture format, it also matters which channel you pack your textures in to. Regular DTX compression generally deteriorates the blue channel more than others, however other formats such as BC7 usually distribute the quality across channels evenly, at a higher cost. SSS and Roughness are 2 textures that don't really need high quality for a good end result, which is why I have packed both of those in to a single channel, and instead of using the full 0-255 range of the channel for one, i have split the range into 2, 1 for each texture. 0-128, and 129-255. This obviously reduces quality of each, but is barely noticeable in the end result.
I'm still not sure how I can put two textures into a single channel like that though. I guess it operates on assumption that the two values will always be somewhere in the specified range.
here's a link to get you started
https://gamedev.stackexchange.com/questions/7859/hlsl-pack-4-values-into-32-bit-float
I'm fairly confident it can be done in substance designer - it doesn't have bitwise operations but should be possible to use multiplies and adds
unreal may have bitwise operators in shaders - if so you should be able to render the packed version out of a shader
I think I need to understand some more 101 stuff first... for instance, there is a difference between targa file and png file. There is 8 bit depth, and 16 bit depth. But I don't know what the differences are, or why they matter, beyond a few basics. Like to have an alpha, that requires more bits (more data, I guess).
Is there any good resource that breaks this down at beginner level? I'm not sure what the subject would be called. I guess if I did some shader writing 101 that would probably cover it?
The practical application is that when I am looking through a material like this, I can understand why they use X compression method, and packed textures a certain way, used a certain image file, etc.
And of course, be able to optimize my materials better as well.
Personally I'd have taken the sss and roughness out, compressed them as a 2 channel texture and halved the size if I was desperate to save memory. if the cost of one extra texture read per tree material is causing you problems then I'd suggest something more fundamental is wrong
anyway..
I dont think you'll learn much about this if you google basic shader creation - this is verging on render/engine stuff .
I'll try to explain the very basics here..
All image formats are fundamentally the same thing. i.e a file contains a 2D array of floats, integers or (in the case of multi-channel images ) 1D arrays of floats or integers.
The actual file format is pretty much irrelevant outside of it's featureset - these can get pretty weird (tif is insanely flexible/complicated, exr can have shit loads of channels - all at different dimensions and bit-depths, jpegs are evil and tga is pointless now we have png) wikipedia is a pretty good place to look up the specifics
bit depth == precision
an 8 bit image has to 255 steps between 0 and 1, 16 bit has 65536 and 32bit has fucking loads - this is per channel. the more bits you have, the more gradations between black and white can be represented
This is all basically irrelevant once you import the image though. At that you're working with GPU friendly compressed data. there's a lot of compression formats and they all have pros and cons but they almost all result in less precision. I forget the name but the traditional basic rgb compression gives you 5, 6, 5 bits (r, g, b respectively) or 32, 64, 32 values - you'll note that this is a shit load less than the 65536 you started with.
it might be a bit tricky to link an unreal compression option with an actual named compression method since it's a cross platform engine but you'll be able to look up things like BC1, BC5, BC7 on wikipedia and get an idea of what the methods do.
I wouldn't get too worried about it unless you want to start poking engine code or get a couple of maths degrees and invent a new compression method, its enough to know what's the most appropriate option for your given use case and you work that out by trying them.
As a rule of thumb, if exporting a packed texture from photoshop, an 8 bit png will serve most purposes? Any reason to use higher bit depth?
Ben Cloward just uploaded a video covering just this topic on youtube, I'll leave link here as it adds on to info here and may also help someone searching in future.
It's been my experience that feeding 16bit textures into the compression process gets you better results - particularly with normal maps. This is not something I've tested properly in Unreal but as a rule the better quality your input- the better quality your output.
in practice you're very, very unlikely to see a notable difference with foliage - its much more likely to be a consideration on large flat surfaces
Probably worth noting that Unreal specifically does not handle 16bit color images in a friendly way. It treats them as if values are stored in linear space and automatically applies an sRGB transform - this is what causes the washed out basecolor/emissive that surprises everyone
If you're using substance designer to output textures this is fine because you can set your export up to accommodate - in photoshop it's a bit of a dick