### Godot version

v4.1.1.stable.official [bd6af8e0e]

### System information

Godot v4.1.1.stable - Fedora Linux 38 (Workstation Edition) - Vulkan (Compatibility) - AMD Radeon RX 560 Series (polaris11, LLVM 16.0.6, DRM 3.54, 6.5.5-200.fc38.x86_64) () - Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz (4 Threads)

### Issue description

Quick note first: It's possible that I've just been calculating world space normals wrong in spatial shaders. But, assuming I haven't, I would consider this to be a pretty significant bug or feature gap in any renderer mode.

Shader code, for reference:

```glsl
shader_type spatial;
render_mode unshaded, ensure_correct_normals;


void fragment() {
	// Edit: using vec4(NORMAL, 1.0) here causes some view-dependent results.
	// So, something is happening, and I may just be using it wrong. I dunno.
	// I'd leave matrix math up to utility functions if I could.
	// `get_world_normal()` and similar functions would be great.
	vec3 world_normal = (INV_VIEW_MATRIX * vec4(NORMAL, 0.0)).xyz;
	vec3 world_up = vec3(0.0, 1.0, 0.0);
	float alignment_alpha = dot(world_normal, world_up) * 0.5 + 0.5;
	ALBEDO = vec3(alignment_alpha);
}
```

Also, potentially related issues I found were for Godot 3.x rather than 4.x and involved negative scaling (which this issue does not).

#### Current behavior

The screenshot below was taken from the attached project, in Godot v4.1.1.stable.official [bd6af8e0e]. I have also opened the project in Godot v4.2.dev5.official [e3e2528ba] and found no difference. The project uses the Compatibility renderer. I have not tested the Forward+ or Mobile renderers, because I have not found either to run acceptably on my hardware/software combo.

In the project's included test scene, there are two sets of three instances of the built-in sphere mesh, with different scales. One set uses the `ensure_correct_normals` render mode. The other set does not.

Notice the following:

- Both sets look identical, despite one set using the `ensure_correct_normals` render mode in its shader.
- Contrast is focused onto the top-center of the squashed spheres, despite their top surfaces being relatively flat throughout in world space.
- Contrast is focused onto the center of the stretched spheres, despite their curvature being relatively smooth across their length in world space.

![Normals Scaling - Godot 4 1 1 stable - 1](https://github.com/godotengine/godot/assets/7255919/fd6042c1-2c9e-4a3c-9e3c-86ec4a643e50)

#### Expected behavior

The screenshot below was taken from a similar scene, made in Unity. Notice how brightness correlates to flatness. A shelf made from a flattened sphere is almost entirely flat throughout. Therefore, its visualized normals are also relatively flat throughout. Tops read as tops (white), and sides read as sides (grey)—even when the ratio of their surface area changes.

I would also expect this to be the default behavior (opt-out rather than opt-in), because it results in significantly improved direction alignment calculation accuracy in world space, where design takes place and quite a lot of arbitrary scaling of assets is done. During both level design and shader authoring, one expects a relatively flat surface to catch light like a relatively flat surface, regardless of how it became that way.

![Normals Scaling - Unity 2022 2 1f1 - 1](https://github.com/godotengine/godot/assets/7255919/0786e0a6-2fc2-4d92-9119-18690d254ef8)


### Steps to reproduce

1. Open the attached project.
2. Open the scene at `res://scenes/test_scene_1.tscn`
3. Observe that there are significant differences in color contrast (lightness gradient harshness) between different sizes of the same mesh instances in the scene.
4. Observe no perceivable differences between same-size pairs in the two sets of mesh instances, despite only one set additionally being assigned the `ensure_correct_normals` render mode.

### Minimal reproduction project

[Godot 4.1.1.stable - Normals Scaling.zip](https://github.com/godotengine/godot/files/12798514/Godot.4.1.1.stable.-.Normals.Scaling.zip)
}
			
			uint32_t count = 0;
			if (surf->lod_index > 0) {
				count = surf->index_count;
			} else {
				count = mesh_storage->mesh_surface_get_vertices_drawn_count(mesh_surface);
			}
			if constexpr (p_pass_mode != PASS_MODE_DEPTH) {
				
				if (p_render_data->render_info) {
					p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;
				}
			}
			if (inst->instance_count > 0) {
				
				
				GLuint instance_buffer = 0;
				uint32_t stride = 0;
				if (inst->flags_cache & INSTANCE_DATA_FLAG_PARTICLES) {
					instance_buffer = particles_storage->particles_get_gl_buffer(inst->data->base);
					stride = 16; 
				} else {
					instance_buffer = mesh_storage->multimesh_get_gl_buffer(inst->data->base);
					stride = mesh_storage->multimesh_get_stride(inst->data->base);
				}
				if (instance_buffer == 0) {
					
					break;
				}