I trying to make a material for a car model with three.js where the base color of the car can be changed dynamically. This was easy enough by changing the color attribute of
You will need a custom shader for that -- and a texture with an alpha channel (essentially, a DDS format). If you look in the three.js source, you'll see a bit of fragment-shader code called 'map_fragment' that looks like so:
"#ifdef USE_MAP",
"#ifdef GAMMA_INPUT",
"vec4 texelColor = texture2D( map, vUv );",
"texelColor.xyz *= texelColor.xyz;",
"gl_FragColor = gl_FragColor * texelColor;",
"#else",
"gl_FragColor = gl_FragColor * texture2D( map, vUv );",
"#endif",
"#endif"
As you can see it multiplies your texture map by the color (which at that point is in "gl_FragColor"). Instead, it sound like you want your map to overlay on top of the base color, only were you've painted it (say, chrome bumpers and headlights).
A simple way to do this might be to just alter the way 'phong' works before you instantiate any phong materials, by changing the value of that "map_fragment" string.
Instead of "gl_FragColor * (something)" -- try this as a re-assignment of THREE.ShaderChunk.map_fragment:
[
"#ifdef USE_MAP",
"vec4 texelColor = texture2D( map, vUv );",
"#ifdef GAMMA_INPUT",
"texelColor.xyz *= texelColor.xyz;",
"#endif",
"gl_FragColor = vec4(mix(gl_FragColor.rgb,texelColor.rgb,texelColor.a),(gl_FragColor.a*texelColor.a));",
"#endif"
].join('\n');
The hazard with overriding the stock method this way is that it will apply to ALL models in the scene -- the painted texture will overlay the material color. If that's okay, you're done. Otherwise you should create a new THREE.ShaderMaterial that's like "phong" except for the difference cited here.