Shader Alpha Can't Be Set During Runtime

I’ve been working on a force field that I want to fade out as it gets bigger. I have culling disabled since the player will be inside. I set the alpha through:

extends MeshInstance3D
@export var shader : ShaderMaterial
func _process(_delta: float) -> void:
	scale = lerp(scale, Vector3.ONE * 36, 0.09)
	shader.set_shader_parameter('alpha', 0.2)# lerp(shader.get_shader_parameter("alpha"), 0.0, 0.2))
	if scale >= Vector3.ONE * 35:
		queue_free()

I’m going to eventually use lerp but I have the 0.2 for testing purposes
The shader being used is:

shader_type spatial;
render_mode alpha_to_coverage, diffuse_burley, cull_disabled;
uniform vec3 albedo : source_color;
uniform sampler2D normal_map : hint_normal;
uniform float uv_scale = 0.4;
uniform vec2 movement_direction = vec2(1, 0);
uniform float movement_strength = 0.5;
uniform float alpha = 0.4;
void fresnel() {
	
	
}
void vertex() {
	// Called for every vertex the material is visible on.
}

void fragment() {
	vec2 uv = UV * uv_scale;
	vec2 uv_movement = movement_direction * TIME * movement_strength;
	vec3 normalmap = texture(normal_map, uv + uv_movement).rgb;
	ALBEDO = albedo;
	ALPHA = alpha;
	NORMAL_MAP = normalmap;
}

//void light() {
//	// Called for every pixel for every light affecting the material.
//	// Uncomment to replace the default light processing function with this one.
//}

It doesn’t move, I just copied this code from a different part of the project and never got around to removing it.

The main issue is it goes with the inspector assigned alpha of 1 when set parameter changes the alpha. I can confirm that alpha is being changed since when I get the parameter it starts at the same value as the inspector assigned value. it changes as I lerp it to 0. That said it still is completely opaque.

Your explanation of the problem is not clear. Does the alpha of the mesh visibly change when you change the shader parameter value in the inspector?

In the inspector I can edit the alpha and it works nicely, I just can’t change it through code in game.

Edit:
Upon further inspection, It prints the correct value and shows up correctly in the editor but when the game is actually running it is always opaque whether the alpha is 0, 60, or -1

What happens if you try to change albedo via script?

I set albedo through shader.set_shader_parameter('alpha', whatever) It does nothing, it is completely opaque and printing shader.get_shader_parameter('alpha') returns whatever it was set to

This looks like your shader variable is not properly assigned. Why are you not accessing the material through mesh instance’s properties?

Tbh, I had no idea how.

How did you assign the shader material to the mesh instance?

I made the Shader Material an export variable then dragged and dropped the shader material through the inspector

That does not assign the material to the mesh.

:0 Is there a better way to do that then?

There are several ways to assign a material to a mesh.
If you only want to assign it to the mesh instance, then try assigning it to node’s material_override property.

Oh, I misunderstood the original question. I get the shader material through the inspector. To assign the material to the mesh I created a mesh instance, made it a sphere mesh, then in the material part I created a shader material and attached the shader to it. Is that what you were wondering or you were wondering about the shader variable (or something else entirely)?

So what’s the point of the exported shader variable then? Access the material through the property you’ve assigned it to.

?
The shader variable is to get the shader material since I didn’t know how to get it from a script. Are you saying I can directly get alpha without going through get_shader_parameter or that there’s no point in calling shader.get_shader_parameter, I can just call get_shader_parameter?

The problem is likely that the material assigned to your shader property is not the material that’s actually assigned to the mesh. Although dragging it in the inspector should have created a reference to the same material object, you probably did something to break that reference.

To be safe, access the mesh’s material directly. If you initially assigned the material to mesh’s material property then you can access is from a script attached to mesh instance via mesh.material. Then call set_shader_parameter() on that.

Yeah, that did it. I originally tried mesh.material but when it didn’t come up in auto complete I was concerend and didn’t try it. Thanks!

It didn’t appear in auto-complete because the type of the mesh property is Mesh. This is a base class for all other mesh types and it doesn’t have material property defined. The base type is used so that various types of inherited meshes can be assigned here. In your case it was one of PrimitiveMesh types.

In most typical cases, it’s better to assign the material to mesh instance’s material_override property, for reasons I won’t go into here.

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