How to get linear data from R, G, B & Alpha channels of a file?

Hi!
As long as we usually create Roughness, Metallic and some other channels as grayscale images with float/Linear profiles then I have the next question: is it possible to read different color channels separately from a file and use them as texture maps?

For exmaple, in Unreal Engine they do it like this: Red (1) channel is used for the Ambient Occlusion map, Green (2) — for the Roughness and Blue (3) — for the Metallic:

Thank you in advance!

Hi!
You can see in the docs of MeshStandardMaterial that aoMap reads red channel, roughnessMap reads green channel, metalnessMap reads blue channel of a texture. So you can write them in one texture.

3 Likes

Does this mean that I don’t have to do anything special for this to work and this is done by default?

Reading the docs on MeshStandardMaterial, pay attention to this sentence in the aoMap section`: The aoMap requires a second set of UVs.

And what does it mean in the context of Three.JS and gltf? I know how to make several UVs for one mesh in 3D editor. Is it what should be done?

Maybe this topic will be helpful: Help with aoMap of GLTF/GLB model - #3 by donmccurdy

PS Feel free to use “Search” on the forum :slight_smile:

Thanks, @prisoner849 this helped with understanding.
Unfortunatelly, all this is not so obvious when I read those short descriptions in the docs. Even for me who is familiar both with 3D graphics and JS.

1 Like

GLTFLoader will automatically create a second set of UVs (by copying the first) if the model has an AO map and needs it.

1 Like

Couldn’t find any examples of extracting data from the channels. I thought that if aoMap, roughnessMap and metalnessMap read color channels automatically, then something like this will work:

const carMaterial = new THREE.MeshStandardMaterial({
    map: textureLoader.load(`'car_color.png`),
    roughnessMap: textureLoader.load(`car_AO-RG-ML.png`),
    metalnessMap: textureLoader.load(`car_AO-RG-ML.png`),
    aoMap: textureLoader.load(`car_AO-RG-ML.png`),
    envMap: hdriTexture
});
carMaterial.side = THREE.DoubleSide;
carMaterial.metalness = 1;
carMaterial.map.encoding = THREE.sRGBEncoding;

…but it doesn’t work — the mesh is black.
In the example above in the car_AO-RG-ML.png file I have R, G & B channels containing information about AO, roughness & metalness respectively (exported from Substance Painter).

Could you please, show a code example of how you do this properly?

Is it a typo with ' in the beginning of the file name?

Could you provide an editable working live code example, that demonstrates the issue?

Yeah, that was a typo. It isn’t in the actual code.
The live code example will take some time — will post in a while.

Here is the repository: nordskill/cartest (github.com)

While working on it I noticed that the textures render as expected if set without the AO map. And with AO the model is black:

matCar = new THREE.MeshStandardMaterial({
    map: textureLoader.load(color),
    envMap: obj.hdri,
    roughnessMap: textureLoader.load(roughness),
    aoMap: textureLoader.load(ao), // this line creates an issue
    metalnessMap: textureLoader.load(metalness)
});

P.S. In the repository the textures are loaded in loadCar() function.

You can load that texture once and use it in three parameters of material.
Also, I used two directional lights in the scene. https://jsfiddle.net/prisoner849/81Lr0jyx/