Shader like Monument Valley

Godot Version

Godot 4.4.1

Question

` I want to make an isomoetric game and the style similar to monument valley. If I understand correctly the shader is called triplanar? Is that correct? Is there a good one somewhere? For the 3d models. There is also some kind of fog fading in the bottom. I post a link to unity assetstore and hope it is ok what I mean

Monument Valley Style Multi-Sided Stylized Shader | VFX Shaders | Unity Asset Store `

Isometric will be a camera projection setting and rotation. The shader included seems to be a flat shader with only directional lighting in the scene. I’m sure it can be achieve with a StandardMaterial3D, though I don’t believe triplanar will help you.

Triplanar is also known as auto-uv since it textures a object based on the face’s normal, this can be useful for natural objects like rocks and trees which have complex geometry and traditional UV maps would result in a seam if the texture isn’t custom made for the object. But this shader seems to work on flat colors, not textures.

Thanks, when I tried similar shader in unity a couple of years ago it was isometric view. There where 3 slots in the shader where you basically just picked a color for top, left and right facing surfaces. Looked really simple but effective. I like the idea to just drag and drop primitive shapes and let the shader do the “coloring”.

The thing is I made a game some years ago and compiled an apk. But I accidentally deleted the project :smiley: So I want to recreate the project but in godot in the future.

Ah for picking colors/textures per side then you may want a triplanar shader

Here’s a basic one that will pick a color for each axis

I use abs on the world normal to simplify the conditions, otherwise you could pick a color for negative sides, ie. left or right, rather than a single color for left and right.

shader_type spatial;

uniform vec3 x: source_color = vec3(1.f);
uniform vec3 y: source_color = vec3(1.f);
uniform vec3 z: source_color = vec3(1.f);

varying vec3 world_normal;
void vertex() {
	// get model normals
	world_normal = abs(MODEL_NORMAL_MATRIX * NORMAL);
}

void fragment() {
	// apply color for highest normal
	if (world_normal.x > max(world_normal.y, world_normal.z)) {
		ALBEDO = x;
	} else if (world_normal.y > max(world_normal.x, world_normal.z)) {
		ALBEDO = y;
	} else if (world_normal.z > max(world_normal.y, world_normal.x)) { // or use else
		ALBEDO = z;
	}
}
1 Like

wow, thanks. Will check this code coming days when I have time to test my project. Appreciated!