How to change the texture of an object in real time ?

You can also use the video texture module, to replace the texture with an texture loaded from the disk.

I have, I have a solution :yes: - and this solution, as I said, using a shader:cool:.

I was looking for one thing, but I found this solution - KX_BlenderMaterial(PyObjectPlus)

import bge 

cont = bge.logic.getCurrentController()
own = cont.owner

SPACEBAR = cont.sensors['space_bar']

if SPACEBAR.positive:
    if own["mix_value"] == 0:
        own["mix_value"] = 1
        own["mix_value"] = 0

vertex_shader = """

void main(void)
   // simple projection of the vertex position to view space
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
   // coordinate of the 1st texture channel
   gl_TexCoord[0] = gl_MultiTexCoord0;
   // coordinate of the 2nd texture channel
   gl_TexCoord[1] = gl_MultiTexCoord1;

fragment_shader ="""

uniform sampler2D texture_0;
uniform sampler2D texture_1;
uniform float factor;

void main(void)
   vec4 color_0 = texture2D(texture_0, gl_TexCoord[0].st);
   vec4 color_1 = texture2D(texture_1, gl_TexCoord[1].st);
   gl_FragColor = mix(color_0, color_1, factor);

for mesh in own.meshes:
    for material in mesh.materials:
        shader = material.getShader()
        shader.setSource(vertex_shader, fragment_shader, True)
        shader.setSampler('texture_0', 0)
        shader.setSampler('texture_1', 1)
        shader.setUniform1f('factor', own["mix_value"])

example - change_texture01.blend (521 KB) - cool:D? (of course, this file is a free extended help on BGE :cool:)

In this method there is one drawback - the second texture is always loaded into RAM (if I’m not wrong).

Thank you for attention.

or so - change_texture02.blend (545 KB) - on this principle, you can probably make a change and 100 textures (of course, this file is a free extended help on BGE

1 Like

here I made more professional (more universal) - change_texture02.blend (571 KB) (of course, this file is a free extended help on BGE :cool:)

If anyone needs, here are the “source file” for the texture - (1.66 KB) - license - if you downloaded this file for yourself, then it is yours under any of your licenses, but my source file is mine, with my license - but that they are the identical, what difference does it make? :eyebrowlift2: (cool license?)

Noice job. Note that the texture change affects all users of the same material (same mesh or otherwise), hopefully that’s not a problem in OP’s case.

Here’s some trickery I cooked up shapeKey_example.blend (870 KB)
Just a wacky alternative for switching back and forth between materials and/or moving UVs around, no idea how resource intense it is though, so far I’ve only used it to get working sprite sheets.

1 Like

Thanks, guys, !

Many good suggestions here, but unfortunately too little time to try them all…

Personally I will step back and use the replace mesh approach, and since I am at it I will remodel the golden armor a bit so it looks more “upgraded”.

if you really want to change the texture you should do what HG1 said.
changing mesh is easy way out, but double the resources (2 meshes/textures/etc), unless you use replace mesh with libload, so that you libload the objects/meshes, but still changing the source of the texture is best.

Here think this could come in handy, tried a few things out and created a loop to change all the objects textures.

from bge import logic,texture

# All objects that you need to change needs to have an unique material with an unique texture
# Using the same material on multiple objects will change them all to/with the same texture

# 2 properties on each object
#   change_material -> boolean -> on/off
#   texture -> str-> new image/texture name

# 1 objects needs to run the script (doesn't matter wich object)
# always(true pulse not needed) ->python(module)->scriptname.start

#Run update_list() whenever you want to update it

def update_list(cont):
    own = cont.owner
    own['obj_list'] = [obj for obj in own.scene.objects if 'change_material' in obj and obj['change_material']]

def start(cont):
    own = cont.owner
    if not 'obj_list' in own:

    for obj in own['obj_list']:    
        new_texture = obj['texture']        
        change_texture(obj, new_texture)

def change_texture(obj, new_texture):

    imagePath = logic.expandPath('//' + new_texture)
    material = str(obj.meshes[0].materials[0])
    matID = texture.materialID(obj, material)

    obj['tex'] = texture.Texture(obj, matID)
    obj['tex'].source = texture.ImageFFmpeg(imagePath)

    obj["Texture_ImageFFmpeg"] = obj['tex']

1 Like

Cotaks thanks, great reference, this is what I needed (I prefer to do stuff with Pyhton if possible, it is more flexible to re-use stuff).
I will try it as soon as possible, thanks. Currently I am using replaceMesh() but in the long run it will not do. It needs be done your way.
But unfortunately I can not test it right now. But soon. Thanks again to all.

PS: By the way it should be available more “readily” by the BGE API or at least with a logic block. I think it is a reasonable
requirement for any game developer to be able to change the texture (or material) of an object with a few lines of code.
There are many cases that it will be required, for example when in a multiplayer you choose color and army, then all armies
must be able to presented with all colors. You can not possibly create all meshes with all colors, what if you have 20 armies and
20 colors to choose from ?


1 line.

also 1 line:

obj.meshes[0].materials[0].textures[0].diffuseFactor = 0

(might be diffuseIntensity you want? I forget.)

Hey! That Shape Key thing looks really useful. I want to make a box with countdown texture this way. Wanna assist?

You mean like a bomb going “4,3,2,1… BOOM!”?

1 Like

Sure thing.

You can exchange the texture image with LibLoad.

See Dynamic Texture 1.0 - easy to use VideoTexture .

But isn’t that for video files? And as far as I know, Blender is already capable to play FMVs with sound.

If there’s no way for materials or image textures, I sure could use video file instead.

Or did I just misunderstand something?

Ok. I checked that source file and realized that they were scaled in Edit mode. I could try that too.

please help me put all the textures, the maximum I can get is 7
how could I change it to add more than 7?

use a texture atlas, just add object color to UV

adjusting the object color will push the texture atlas around.

I don’t get it.

Combine all your textures you want to be able to swap to on 1 atlas texture, ensure you have 16 pixel padding for mipmap

We unwrap the actor, then in shader nodes add object Color to UV, plug into image texture.

This makes it so changing object color changes UV.

Say we use a 8x8

That is incriments of .125