Change/mutate colors in a texture before being added to the scene

Is it possible to change some pixels colors of a texture before this is being added to the scene?

const texture = new THREE.TextureLoader().load('./tiles.png')
// Making some pixel mutations here...
const material = new THREE.SpriteMaterial({
    map: texture
})
// ...or here...
scene.add(new THREE.Sprite(material))

Hi!
There is .onBeforeCompile() for materials. Use it to add features you want :slight_smile:

1 Like

One way is to draw the image to a canvas and apply other modifications to the same canvas, and then use the canvas as texture.

2 Likes

How performant is to use a new canvas as texture for each sprite?

I don’t know. I guess it consumes more memory, at least. @prisoner849’s suggestion of using a shader (modification) may apply, depending on what kind of modifications are needed. If it is some kind of transform that is applied to all pixels, a shader is probably suitable. We would need to know more about the context.

Imagine a spritesheet that have some pixels in blue color, the blue represent the team. I want to change this blue programatically to red to use the same spritesheet.

Would it be an option to swap R and B channels completely in the fragment shader? :rofl:

But seriously, it is possible to replace pure colors in the shader. But what if you have antialiasing gradients between the pure colors? Hm.

Is “segmentation textures” a thing? Where you have one texture that defines by integers which “tissue” (skin, hair, clothes, armor etc.) each pixel represents, and supply a color pallette array that the texture indexes into? (Still only for pure colors, though.)

I would prepare the spritesheets to have pure blue pixels. So I just need to find those pixels and change them for red.

Then I guess checking the texture read in the shader and modifying the value if it is pure blue may be the easiest(?) and fastest(?) solution.

What do you mean by that? Any example I can look at?

After reading some basic tutorials on shaders, including those that involve textures, you will probably understand this:

vec4 texel = texture2D(uMap, vUV);
if (texel.xyz == vec3(0.,0.,1.)) {
    texel.xyz = vec3(1.,0.,0.);
}
1 Like

Or texel.xyz = texel.zyx;

Not an easy solution for an easy task I’m afraid.

@Enzo Why so? Just a couple of additional lines in a shader.

I don’t even know how to read all the color pixels of the texture.

Pass a texture in a uniform, then via UV coordinates you’ll get a texel and then change/swap r and b channels, if it’s in a condition. That’s what Elias provided.
Or I can’t get the problem :slight_smile:

Shader - Shadertoy BETA just an example with swapping (you need to uncomment the line for effect)