# Mapping of Roughness map/ AO map/ Metalness Map into RGB channels

**URL:** <https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162>\
**Category:** Questions\
**Tags:** loaders, materials, textures\
**Created:** [June 11, 2022, 11:18am UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162 "2022-06-11T11:18:20Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gundeep\_Singh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/gundeep_singh/32/25485_2.png) [@Gundeep\_Singh](https://discourse.threejs.org/u/Gundeep_Singh)\
**Post date:** [June 11, 2022, 11:18am UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/1 "2022-06-11T11:18:20Z")

</div>

I need guidance, how we can map one texture into three different RGB channels in a GLB file and I am not loading any texture from outside I just need to manipulate that textures which are with GLB model. I write below code

```javascript
gltf.scene.traverse(function (child) {
                if (child instanceof THREE.Mesh) {
                    const mat = new THREE.MeshPhysicalMaterial({})
                    
                    if (value === 'normalMap') {
                        if (child.material.normalMap) {
                            child.material.map = child.material.normalMap;
                            child.material.needsUpdate = true;
                            console.log('Normal map exist');
                        }
                    }
                    if (value === 'alphaMap') {
                        if (child.material.alphaMap) {
                            child.material.map = child.material.alphaMap;
                            child.material.needsUpdate = true;
                            console.log('Alpha map exist');
                        }
                    }
                    if (value === 'aoMap') {
                        if (child.material.aoMap) {
                            child.material.map = child.material.roughnessMap;
                            child.material.needsUpdate = true;
                            console.log('AO map exist');
                        }
                    }
                    if (value === 'emissiveMap') {
                        if (child.material.emissiveMap) {
                            child.material.map = child.material.emissiveMap;
                            child.material.needsUpdate = true;
                            console.log('Emissive map exist');
                        }
                    }
                    if (value === 'roughnessMap') {
                        if (child.material.roughnessMap) {
                                                
                            
                            child.material.map = child.material.roughnessMap;
                            //mat.needsUpdate = true;
                            child.material.needsUpdate = true;
                            console.log("mat", mat)
                            console.log('Roughness map exist');
                        }
                    }
                    if (value === 'metalnessMap') {
                        if (child.material.metalnessMap) {
                            console.log(child.userData)
                            //child. = mat;
                            child.material.map = child.material.metalnessMap;
                            child.material.needsUpdate = true;
                            console.log('Metalness map exist');
                        }
                    }

```

In the above code roughness map, metalness map and ao map all share same textures and I don’t need how split this texture into three parts for RGB channels. Thanks for your time and help

---

<div class="post-metadata">

**Author:** ![aswwwcom](https://avatars.discourse-cdn.com/v4/letter/a/7ba0ec/32.png) [@aswwwcom](https://discourse.threejs.org/u/aswwwcom)\
**Post date:** [June 11, 2022, 11:53am UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/2 "2022-06-11T11:53:08Z")

</div>

Maby you have to show why isn’t working and, what is the message of the error

---

<div class="post-metadata">

**Author:** ![Gundeep\_Singh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/gundeep_singh/32/25485_2.png) [@Gundeep\_Singh](https://discourse.threejs.org/u/Gundeep_Singh)\
**Post date:** [June 11, 2022, 12:04pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/3 "2022-06-11T12:04:19Z")

</div>

It doesn’t giving me any error just wanna know how to split one texture into three RGB channels so I will assign one texture to three inputs

---

<div class="post-metadata">

**Author:** ![aswwwcom](https://avatars.discourse-cdn.com/v4/letter/a/7ba0ec/32.png) [@aswwwcom](https://discourse.threejs.org/u/aswwwcom)\
**Post date:** [June 11, 2022, 12:13pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/4 "2022-06-11T12:13:26Z")

</div>

I think three js isn’t blender. You have to split Image in to RGB channel, and just load it with texture loader.

Texture loader is for loading texture not only png, rgb file for local but also on online like base64 url

---

<div class="post-metadata">

**Author:** ![Gundeep\_Singh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/gundeep_singh/32/25485_2.png) [@Gundeep\_Singh](https://discourse.threejs.org/u/Gundeep_Singh)\
**Post date:** [June 11, 2022, 12:27pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/5 "2022-06-11T12:27:13Z")

</div>

But all the texture maps are already stored in a GLB file see below link

[example](https://discourse.threejs.org/t/mapping-roughness-metallic-ao-from-one-texture-file/12367)

I need this same but don’t wanna import any image just split texture map which is stored in a GLB file.

---

<div class="post-metadata">

**Author:** ![aswwwcom](https://avatars.discourse-cdn.com/v4/letter/a/7ba0ec/32.png) [@aswwwcom](https://discourse.threejs.org/u/aswwwcom)\
**Post date:** [June 11, 2022, 12:44pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/6 "2022-06-11T12:44:09Z")

</div>

I don’t get what is ‘split’ texture that you’ve been saying

I’m not expertise I think you have to divde image texture in each RGB channel with other web module.

and plus, if you change texture you have to type `material.needsUpdate = true`

---

<div class="post-metadata">

**Author:** ![Gundeep\_Singh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/gundeep_singh/32/25485_2.png) [@Gundeep\_Singh](https://discourse.threejs.org/u/Gundeep_Singh)\
**Post date:** [June 11, 2022, 12:50pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/7 "2022-06-11T12:50:13Z")

</div>

I tried this but didn’t work, main issue is I can’t able to understand how I divide texture into three channels like [donmccurdy](https://discourse.threejs.org/u/donmccurdy) sir did, just wanna know is it possible, if yes then how and one more article is there

> <https://github.com/KhronosGroup/glTF/issues/1682>
>
> Opening a new thread here, based on discussion around https://github.com/Khronos…Group/glTF/pull/1612.
> 
> Storing three independent data channels in compressed textures introduces significant artifacts with current approaches (see #1612). As a result, these two cases in the current glTF material specification require consideration:
> 
> \- occlusion/rough/metal (RGB) texture
> \- three-channel normal (RGB) texture
> 
> These could be solved with:
> 
> \- \*\*(1)\*\* occlusion (R) and rough/metal (RG) textures, and
> \- \*\*(2)\*\* two-channel normal (RG) texture
> 
> A general-purpose texture-swizzling extension would be an alternative to (1). Currently that is harder to support on the web, but it won't always be so, and might be worth considering today.
> 
> Assuming (1) and (2) are the correct solutions here, what are the right mechanisms to bring them into the format? A couple ideas:
> 
> \- \*\*(A)\*\* Introduce new extensions, e.g. KHR\_packing\_normal, KHR\_packing\_roughness\_metallic, analogous to \[MSFT\_packing\_normalRoughnessMetallic\](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Vendor/MSFT\_packing\_normalRoughnessMetallic/README.md).
> \- \*\*(B)\*\* Include them with the upcoming "PBR Next" material model's extensions; do not backport to existing metal/rough, spec/gloss, or unlit materials.
> \- \*\*(C)\*\* Include these changes, and perhaps other KTX2/Basis-related changes, in a glTF 2.1 release to simplify the perceived complexity, as compared to specifying multiple interdependent extensions.

in the above link they explain but I didn’t find any path.

---

<div class="post-metadata">

**Author:** ![Dannie226](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/dannie226/32/21794_2.png) [@Dannie226](https://discourse.threejs.org/u/Dannie226)\
**Post date:** [June 11, 2022, 1:43pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/8 "2022-06-11T13:43:28Z")

</div>

Where are you defining value in this? You are checking against value, but, as far as I can see, you didn’t define it anywhere.

---

<div class="post-metadata">

**Author:** ![Chaser\_Code](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/chaser_code/32/20199_2.png) [@Chaser\_Code](https://discourse.threejs.org/u/Chaser_Code)\
**Post date:** [June 11, 2022, 1:49pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/9 "2022-06-11T13:49:59Z")

</div>

Into console have some logs of exist map? `console.log('Normal map exist');`

---

<div class="post-metadata">

**Author:** ![Gundeep\_Singh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/gundeep_singh/32/25485_2.png) [@Gundeep\_Singh](https://discourse.threejs.org/u/Gundeep_Singh)\
**Post date:** [June 11, 2022, 1:50pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/10 "2022-06-11T13:50:16Z")

</div>

I create one drop drop down with dat.gui those values are I am comparing  
 ![4](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/1/6/16ebb36e5d553c2ee6d3d43e1dc12d893c922648.jpeg)

---

<div class="post-metadata">

**Author:** ![Gundeep\_Singh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/gundeep_singh/32/25485_2.png) [@Gundeep\_Singh](https://discourse.threejs.org/u/Gundeep_Singh)\
**Post date:** [June 11, 2022, 1:51pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/11 "2022-06-11T13:51:09Z")

</div>

yes it displays message works fine main issue in Roughness Map, Occlusion Map, and Metalic Map

---

<div class="post-metadata">

**Author:** ![Dannie226](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/dannie226/32/21794_2.png) [@Dannie226](https://discourse.threejs.org/u/Dannie226)\
**Post date:** [June 11, 2022, 1:55pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/12 "2022-06-11T13:55:46Z")

</div>

Ok… I am slightly confused… What effect are you trying to achieve here. Are you just trying to visualize the different textures, or what are you trying to get done. Because, from your code, it does seem as though you are just trying to visualize the textures.

---

<div class="post-metadata">

**Author:** ![Gundeep\_Singh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/gundeep_singh/32/25485_2.png) [@Gundeep\_Singh](https://discourse.threejs.org/u/Gundeep_Singh)\
**Post date:** [June 11, 2022, 1:57pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/13 "2022-06-11T13:57:19Z")

</div>

Yes, change textures of GLB at run time like sketchfab we can see normal map, base color and so on.

---

<div class="post-metadata">

**Author:** ![Dannie226](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/dannie226/32/21794_2.png) [@Dannie226](https://discourse.threejs.org/u/Dannie226)\
**Post date:** [June 11, 2022, 2:00pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/14 "2022-06-11T14:00:17Z")

</div>

are you able to create a fiddle of your entire code? Rather than just the traversal. That would be helpful, at least for me, if not for others as well.

---

<div class="post-metadata">

**Author:** ![Gundeep\_Singh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/gundeep_singh/32/25485_2.png) [@Gundeep\_Singh](https://discourse.threejs.org/u/Gundeep_Singh)\
**Post date:** [June 11, 2022, 2:02pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/15 "2022-06-11T14:02:03Z")

</div>

Sir, I can’t share whole code as per organization rule, you have any other way just need guidance.

---

<div class="post-metadata">

**Author:** ![Dannie226](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/dannie226/32/21794_2.png) [@Dannie226](https://discourse.threejs.org/u/Dannie226)\
**Post date:** [June 11, 2022, 2:10pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/16 "2022-06-11T14:10:49Z")

</div>

That’s fair.

You are getting the logs. Is it only on Roughness, occlusion, and metallic that you are getting the issue? And, if so, are you still getting the logs? I know gltf format does combine metalness/roughness map (blue channel is metalness, green is roughness), and I don’t know if it combines the alpha map as well (if so, it would be red channel). Umm… You could use the onBeforeCompile with the material to update the fragment shader a bit.  
Side note: You shouldn’t need to update the material. The only time you would need to do that is if you are changing whether or not the material has its own map property.  
Edit:  
Why not try logging the material, and checking all the roughness, metalness, and ao map to see if they are the same texture. Dunno if that would work, but it might be worth a try.

---

<div class="post-metadata">

**Author:** ![Gundeep\_Singh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/gundeep_singh/32/25485_2.png) [@Gundeep\_Singh](https://discourse.threejs.org/u/Gundeep_Singh)\
**Post date:** [June 11, 2022, 2:15pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/17 "2022-06-11T14:15:30Z")

</div>

yes, you are right in single texture image I have three channels RGB in image but I don’t know to pass single by single to three Metalness, Roughness and Occlusion. If I run my code it shows together with mixing of ORM values. I hope you understand my point and you have any resource related to onBeforeCompile and how we can override fragment shaders for this.

---

<div class="post-metadata">

**Author:** ![Dannie226](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/dannie226/32/21794_2.png) [@Dannie226](https://discourse.threejs.org/u/Dannie226)\
**Post date:** [June 11, 2022, 2:16pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/18 "2022-06-11T14:16:59Z")

</div>

Yes. I understand your issue now. I am quickly testing something, and will get back.

---

<div class="post-metadata">

**Author:** ![Gundeep\_Singh](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/gundeep_singh/32/25485_2.png) [@Gundeep\_Singh](https://discourse.threejs.org/u/Gundeep_Singh)\
**Post date:** [June 11, 2022, 2:17pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/19 "2022-06-11T14:17:21Z")

</div>

I already checked the log values all have same values and same uuid values by using

```javascript
child.material.roughnessMap 
child.material.aoMap 
child.material.metalnessMap 

```

---

<div class="post-metadata">

**Author:** ![Dannie226](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/dannie226/32/21794_2.png) [@Dannie226](https://discourse.threejs.org/u/Dannie226)\
**Post date:** [June 11, 2022, 2:33pm UTC](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162/20 "2022-06-11T14:33:21Z")

</div>

Ok… results of my testing. Using needsUpdate does recompile the material, but it doesn’t trigger the onBeforeCompile function.  
Best thought of mine, add a uniform to the shader, call it like, imageType. In the shader, add a conditional, and if imageType is one of 3 values, update gl\_FragColor with the correct texel.  
That would probably look something like this:

```javascript
//When loading the gltf (or before the first render frame) inside a traverse function
child.material.onBeforecompile = function(shader){
    //unprocessed fragment shader. Change this, change what gets plugged
    // into three.js You will need to figure out where to change the code
    // Putting it directly at the end might work.
    shader.fragmentShader;
    
    //add something similar to this code
    `if([uniform name] == [whatever number you are using to signify roughness map]){
         gl_FragColor.rgb = texture2D(roughnessMap, vUv).ggg;
     }else if([uniform name] == [metalness map number]){
         gl_FragColor.rgb = texture2D(metalnessMap, vUv).bbb;
     }else if([uniform name] == [ao map number]){
        gl_FragColor.rgb = texture2D(aoMap, vUv).rrr;
     }`;

    //putting this (or similar) at the beginning
    'uniform int [uniform name];';
    shader.uniforms.[uniform name] = {};
    Object.defineProperty(shader.uniforms.[uniform name], "value", {get:function(){
        return child.material.[uniform name];
    }
}

```

And then, in the traversal, you would just do

```javascript
child.material.[uniform name] = [number for whatever option was chosen];

```

And, that should work. No guarantees, and you will probably have to do a bit of debugging. But, fingers crossed, that should work.  
Edit:  
Also make sure to replace the stuff in brackets. I don’t know if i made that obvious, but, please do not just copy paste that code. Replace the things in brackets (and the brackets themselves) with what they mean. I have done dumber things, and dont want you to waste lots of time debugging that because of a misunderstanding.

[Next page](https://discourse.threejs.org/t/mapping-of-roughness-map-ao-map-metalness-map-into-rgb-channels/39162.md?page=2)
