I am looking into rendering a model with two materials, and using a mask to specify which material should render where, basically like a soccer ball with a black & white hexagonal pattern etc, where I want to be able to change the colour tint of only one of the materials (for example, the white) in runtime, but I have no idea where to start or how to go about this.
I have previously done some texture swapping on a model with multiple mesh instances before; simply meshInstances[this.meshNumber].material = this.textureActive.resource;, but I’m not sure if this is similarly applicable, as I want to be able to control the tint of the material and not make all the possible textures by hand.
To give a bit more insight on the kind of project I’m working on, it’s essentially a customization tool where I want the user to be able to customize footballs / soccer balls by selecting base shapes, and changing colour tints of these shapes, but in this case leaving the black hexagonal pattern in-tact.
There’s unfortunately not a project or much material where I can show what I would like to achieve.
In summary, is it possible to have 1 model, 2 materials, specify which material to render where via mask, and change colour tint on 1 of 2 materials.
Edit1:
I don’t want to apply different material id’s on polygons, but I want to be able to paint specific patterns on a per-model basis
Yes that’s possible using the detail texture channel available on the pc.StandardMaterial. It’s not exposed in editor yet (I think it’s coming very soon), so you will have to enable it in code.
Check the docs on which material channels provide a second detail map channel for use:
Seems I was wrong in specifically having two different materials.
I currently have the mask setup as a diffuseDetail;
I have 2 separate Textures, the Diffuse and the “mask” that I want to use as a detailmap;
only now the trick is to be able to change the colour of the diffuse without affecting the colour of the areas in the diffuseDetailMap.
Since I have basically no shader knowledge, I’ve been looking a bit through the Planet Earth tutorial on Shader Chunks as you mentioned, but I don’t really know where to actually start.
Would my shader have to be something like this, in very simple terms;
uniform sampler2D texture_diffuseMap;
vec3 getDiffuse() {
return "a product resulting from diffuseMap - diffuseDetailMap"
}
and then change the colour of the diffuse in code, rather than in editor?
So, for something like that you would override the diffuse (albedo) shader chunk. You could pass these custom uniforms to the material:
texture_mask
texture_diffuseSecondMap
And then here is some code that I think can work in your case, not tested but you can work from this I think:
uniform vec3 material_diffuse;
uniform sampler2D texture_diffuseMap;
// --- custom uniforms
uniform sampler2D texture_mask;
uniform sampler2D texture_diffuseSecondMap;
void getAlbedo() {
vec4 mask = texture2D(texture_mask, $UV);
vec3 texel0 = texture2D(texture_diffuseMap, vUv0).rgb;
vec3 texel1 = texture2D(texture_diffuseSecondMap, vUv0).rgb;
// --- we use the mask channels to find the final color for this pixel
// --- in this example the RED channel of the mask is used to map the diffuseMap texture + the diffuse color as assigned in editor
// --- the GREEN channel is used to paint the custom texture uniform diffuseSecondMap that isn't affected by the diffuse color
dAlbedo = gammaCorrectInput(
addAlbedoDetail(mask.r * texel0 * material_diffuse.rgb + mask.g * texel1)
);
}
Hmm, I’ve added the shaderchunk but I don’t seem to be getting the desired result.
Is it okay if I add you to the private project? if I invite you on that project, it shouldn’t add you to the organization, right?
I think I might’ve been a bit unclear with what I meant when I had 2 textures.
Here’s a layout of the file structure.
I have 1 diffuse and 1 mask, and I’m currently setting the Colour on the material directly;
In the end-product, a separate application where we use playcanvas as the engine, I won’t have access to the editor itself and would have to load these scripts in separately.