Just wondering if its possible to map texture channels to specific shader inputs. I am aware of the ORM map, but if you say wanted to pack the textures differently is it possible to remap them? I was looking through the API but couldn’t see a way to access the channels of a texture.
A custom shader would work I believe, but from I can see it may need a rewrite of the PBR implementation and how it handles each channel.
Upon further reading and investigation I can see that the most optimal channels have been chosen in the PBRMetallicRoughnessMaterial, so I guess the need to pack textures differently isn’t really needed.
That said, I could see cases where you could in theory pack say a roughness texture into the blue channel of a normal map and reconstruct the blue channel within the shader. Maybe the node based shader editor will allow for this flexibility eventually?
It is valid, since a packed channel is grayscale and would only result in a float from 0-1. I’m thinking of a scenario where your diffuse texture is a neutralized gray image, and a user can use a color picker to add the color. So a final color may look like:
// albedoColor is a float like 0.78...
vec3 finalColor = albedoColor * vec3(1.0, 0., 0.);
Maybe instead of ALBEDO_CHANNEL (or NORMAL_CHANNEL) being a number, it should be something like:
#define NORMAL_CHANNEL gba
then in the shader:
normal = vec3(normal.NORMAL_CHANNEL);
However, it won’t work as is because you need to supply at the end of vec3(…) as many zeros as necessary to reach 3 components (another define with something like “,0” ?):
I haven’t thought it all the way through, but you can reference a uniform array and convert the results into a vec3. The DEFINES just acts to filter out the logic, but let’s say you input an array of [1,2,3] for the normal map. Since this is a normal map, we can assume that we use three channels, but we could also send in the array length as a uniform.
int channels[3];
channels = int[](1, 2, 3); // This is the uniform
vec4 iColor = vec4(0., 1., 0., 0); // This is the inputed texture map
vec3 col = vec3(iColor[channels[0]], iColor[channels[1]], iColor[channels[2]]);
// Output to screen
fragColor = vec4(col,1.0); // This outputs red
So really the trick is just allowing the user to specify a list of channels and then in the shader we can convert that into any kind of vec3 we want. It’s already doing that for the ORM model on the metallic/roughness texture, but it could be a lot more flexible and allow for some clever texture packing schemes to boost load times.