Is it possible to make a 3D mesh material fade out over time without affecting all objects using the same material?

Godot Version

4.5

Question

I have a box object that, when destroyed, will spawn in a broken box scene. That scene contains rigidbody3D box pieces that I would like to slowly fade out over time and become completely transparent, then queue_free(). I tried creating an animationplayer for this that would control the alpha on the box material to slowly make it fade out over time, but I quickly realized making changes to the material on any one mesh would affect all meshes using the same material.

Is there a way to make this work? Is it possible to uniquely control the material alpha on a node by node basis? Does this require a shader? I’ve never worked on a shader before but I’ve seen some mention that it could be a solution to this, but I’m unsure how.

Set your material resource “Local to Scene”

1 Like

Thanks again for the help gertkeno! Unfortunately it doesn’t seem like this worked. I set Local to Scene to on in the material settings on one of the meshes

But each time I destroy a box and the fade animation plays it affects all of the destroyed box scenes, not just the most recently destroyed box.

The code is pretty straightforward. When added to the scene it applies some impulse to each piece for impact, then plays the fade animation and waits 10 seconds before queue_free().

extends Node3D

@onready var FadeAnimation = $AnimationPlayer

@export var Intensity := 2.0

func _ready() -> void:
	
	for pieces:Node in self.get_children():
		if pieces is RigidBody3D:
			pieces.apply_impulse(pieces.get_child(0).position * Intensity, self.global_position)
	
	FadeAnimation.play("Fade")
	
	await get_tree().create_timer(10).timeout
	queue_free()

The AnimationPlayer sets the material transparency to Alpha and slowly reduces the material color alpha to 0

Is the material on the mesh resource or on the mesh instance node? It needs to be on the node or you need to set mesh resource local to scene as well (which is wasteful)

I’m not sure. It’s found in the material under each cube cell mesh:

Then opening up that material I set it as Local to Scene:

Is that not on the mesh instance node? If that’s the case where should I be looking?

It’s on the resource. Even though the material duplication is enabled per instance (via local to scene mechanism) all scenes will share the same mesh that material is assigned to. So duplicating the material has no sense and the engine will skip it. All resources in the resource chain need to have the flag set. The first in the chain that doesn’t - breaks the further duplication.

As i said, either enable local to scene flag for the mesh resource too or assign the material to mesh instance’s material_override property. The former is not optimal if you create many instances as it will duplicate mesh vertex data for each instance.

2 Likes

Ahhh ok thanks for the explanation. I wasn’t aware that’s how it worked. I added the material as a material override and now it’s working perfectly.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.