Shader uniform float keep resetting to 1.0

Godot Version

4.5.dev

Question

Hello, I’m working on a dissolving shader for dying ennemies, to do so I created a value uniform float dying_t : hint_range(0.0, 2.0, 0.01) = 2.0;, but for some reason it’s value always seems to reset to 1.0, I looked at everything and couldn’t manage to find a solution :frowning: .

Here’s the gdshader code :

StandardMaterial3D.
shader_type spatial;
render_mode blend_mix, depth_draw_opaque, cull_back, diffuse_burley, specular_schlick_ggx;

uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color, filter_linear_mipmap, repeat_enable;
uniform ivec2 albedo_texture_size;
uniform float point_size : hint_range(0.1, 128.0, 0.1);

uniform float roughness : hint_range(0.0, 1.0);
uniform sampler2D texture_metallic : hint_default_white, filter_linear_mipmap, repeat_enable;
uniform vec4 metallic_texture_channel;
uniform sampler2D texture_roughness : hint_roughness_r, filter_linear_mipmap, repeat_enable;
uniform sampler2D noise_death;

uniform float specular : hint_range(0.0, 1.0, 0.01);
uniform float metallic : hint_range(0.0, 1.0, 0.01);
uniform float dying_t  : hint_range(0.0, 2.0, 0.01) = 2.0;

uniform vec3 uv1_scale;
uniform vec3 uv1_offset;
uniform vec3 uv2_scale;
uniform vec3 uv2_offset;

void vertex() {
	UV = (VERTEX.xy + vec2(1.0)) * 0.5; // map XYZ to UV range [0,1]
	//UV = UV * uv1_scale.xy + uv1_offset.xy;
}

void fragment() {
	vec2 base_uv = UV;

	vec4 albedo_tex = texture(texture_albedo, base_uv);
	ALBEDO = albedo.rgb * albedo_tex.rgb;

	float metallic_tex = dot(texture(texture_metallic, base_uv), metallic_texture_channel);
	METALLIC = metallic_tex * metallic;
	SPECULAR = specular;

	vec4 roughness_texture_channel = vec4(1.0, 0.0, 0.0, 0.0);
	float roughness_tex = dot(texture(texture_roughness, base_uv), roughness_texture_channel);
	ROUGHNESS = roughness_tex * roughness;
	vec4 alpha_tex = texture(noise_death, base_uv);
	ALPHA = round(dying_t - alpha_tex.x);//                <=====   used here
	if(ALPHA > 1.0)
	{
		ALPHA = 1.0;
	}
	if(ALPHA < 0.0)
	{
		ALPHA = 0.0;
	}
}

I created a dedicated enemy_shader.tres ShaderMaterial and applied it the dedicated enemy_shader.gdshader, and in the Shader Parameters I setup the Dying T variable to “2.0”.

Then, after doing this I applied it to my “Enemy.tscn”.

On side of that I also have those lines in this scene main script :

func _ready():
	var mat = $Body.mesh.surface_get_material(0).duplicate()
	$Body.mesh.set_material(mat)
	mat.set_shader_parameter("dying_t", 2.0)

I use this because my instances shared the same shader and when one was dying everyone would dissolves :sweat_smile:, there’s also a workaround for my current issue but my question goal is just to understand why such a thing would happen.

When I instanciate my “Enemy.tscn” I then launch the debug (and remove the above solution) and am met with this :

Thus showing that my Dying T variable is at 1.0 despite everything.

I also use this value in an animation player for death animation and it work well :


Would someone happen to know something about it ? I tried to look for this everywhere but never found an answer.

Sorry for the huge post, have a nice day :slightly_smiling_face:.

I don’t know what’s happening but you could try making the material Local to Scene. It’s the last property under the material. I think this would at least fix needing to duplicate materials, but not sure about the resetting value…

Use instance unifoms, you don’t have to duplicate the entire material!!

The reset to 1.0 is strange, something is causing it. You mentioned you set the variable in an AnimationPlayer - double check the RESET animation, maybe it’s accidentally set there?

1 Like

Hey !

Thank you so much ! This is something I was looking for, duplicating materials and shaders was the only solutions I found out of spite but this is way better.

Also I just tried it and for some reasons it seems to also have corrected the variable resetting, maybe because of it’s nature change.

For the record I didn’t use any RESET animation until now since the goal was to queue_free() the node just after.

I don’t know what’s happening but you could try making the material Local to Scene. It’s the last property under the material. I think this would at least fix needing to duplicate materials, but not sure about the resetting value…

I did not mention it but I already did that, I just checked the boxes off and everything seems to work correctly now :slight_smile: .

1 Like