How can I combine my Vertex Shader with a StandardMaterial Shader?

Godot Version

4.6

Question

Im trying to make a basic mockup of an ocean by applying a really simple vertex shader to a subdivided plane mesh. Here is my code for that:

shader_type spatial;
uniform float last_time = 0.0;
float wave(vec2 vertex){
	return cos(vertex.x + TIME) * sin(vertex.y + TIME) * 0.3;
}


void vertex() {
	float height =  wave(VERTEX.xz);
	VERTEX.y += height;
	vec2 e = vec2(0.01, 0.0);
	vec3 normal = normalize(vec3(wave(VERTEX.xz - e) - wave(VERTEX.xz + e), 2.0 * e.x, wave(VERTEX.xz - e.yx) - wave(VERTEX.xz + e.yx)));
	NORMAL = normal;
}

void fragment() {
	ALBEDO = COLOR.xyz;
}

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

Now obviously id like to give the plane a simple material. A deep blue would be enough. I would like to basically take the Vertex manipulation of my shader and then be able to set the rest of the material properties in a StandardMaterial.

I tried adding a second pass with a standard material but that causes the plane to be rendered twice instead of the shaders being “combined”.

Basically I would like to either be able to override the vertex shader of a standard material with my own, input my vertex data into a standard shader or somehow overlay them in another way.

My main reasoning for this is that I would like to play with some of the standard effects like transparency and glossyness without having to essentially reimplement those effects in my own shader. And having a neat UI for it would be great as well. I really just want to add this wavy pattern to a normal StandardMaterial Plane. Thats all.

Is this possible?

Enable all material features you need in a standard material, convert it to a shader material and replace the vertex function in its code with your own function.

1 Like

But this way I will lose the modularity and the UI of the standard material, making tweaking stuff more of a matter of either adding a script and setting uniforms, or manually hardcoding them in the script.

Is there no way to combine two shaders in the gui directly?

Most of the stuff you enable in the material with automatically transfer to the shader as uniforms which you can tweak in the inspector.

For modularity you can use shader includes.

You can’t separate vertex and shader functions into different materials.