How to make a 3D health bar using 3d objects

Godot Version

4.2

Question

So I dont how to search it up because all I ever see is just 2D health bars in 3D space which is not what I am looking for.

But in my game I want to have 3D model of a container and everytime the player gains or loses health the container fills up or drains the “water”/“blood”.

So far I dont know where to begin with this.

This topic might give you some ideas of where to start

Do you need this?

indicator

oh this is a start but not sure how to translate that to what I need, I guess Ill fiddle around with it and see what I can do

yeah this its just dont know how to get here

It ended up in one of my works completely by accident.

Run a 3 pass shader on your container mesh.

  • Pass 1 (liquid side): discard all pixels whose y coordinate is above the fill value supplied via an uniform.
  • Pass 2 (liquid top): same as pass 1 but cull the front faces and set the normal to always point upwards.
  • Pass 3 (glass): Displace vertices along normals to simulate glass thickness, adjust transparency, specularity, fresnel etc. You can also enable Godot’s refraction to make it look cooler.

There you go. Your basic shaders are as follows. Note that a lot more finesse can be added but this does the main trick.

Pass 1:

shader_type spatial;

uniform float fill = 0.0;
varying float vertex_world_y;

void vertex() {
	vertex_world_y = (MODEL_MATRIX * vec4(VERTEX, 1.0)).y - NODE_POSITION_WORLD.y;
}

void fragment() {
	if (vertex_world_y > fill){
		discard;
	}
}

Pass 2:

shader_type spatial;
render_mode cull_front;

uniform float fill = 0.0;
varying float vertex_world_y;

void vertex() {
	vertex_world_y = (MODEL_MATRIX * vec4(VERTEX, 1.0)).y - NODE_POSITION_WORLD.y;
	NORMAL = normalize(inverse(MODEL_NORMAL_MATRIX) * vec3(0.0, -1.0, 0.0));
}

void fragment() {
	if (vertex_world_y > fill){
		discard;
	}
}

Pass 3 can be a standard material.

oh wow I was about to say that I wasn’t a shader person so I wouldnt really know how to achieve that but now that I see the video I see that this is really cool and surprisingly a lot simpler than I thought.

You can’t really do it without shaders if the form is anything but a regular cylinder, which can simply be vertically scaled (as in @tomcat’s example).

Shaders are incredibly powerful. It’s worth learning about them.

So I have some question about this because I am currently fiddling around with this. But how do you change the colour or add texture? Because in your demonstration video its purple but for me I cant seem to change it from the basic white colour.

Assign the color to ALBEDO in the fragment() function. You can also declare an uniform and assign that to ALBEDO. That way you’ll be able to adjust it from the inspector.