This is my understanding of how this all works and Martin may correct me in areas
The cameras render to a render target which is usually the backbuffer or a texture which is set on per camera basis.
The layers listed on camera are rendered to the render target in the order that listed in rendering settings of the project
If multiple cameras are rendering to the same render target, then the cameras rendering order is on a per camera basis via the priority on the camera.
ie Camera A with priority 0 would render all it’s listed layers onto the render target first, then Camera B with priority 1 would render all it’s listed layers onto the render target on top of the result from Camera A
This is also known as Camera Stacking.
In terms of render order of the layers, they render in the order that are listed in the settings as shown above. There are a number of things to keep in mind here.
Each layer is split between an opaque and transparent sublayer which is usually dependent on the material that is used. ie. if it uses opacity, it will be on the transparent sublayer.
Meshes are rendered per sublayer in the order that layer sorting logic as seen in the settings
The general recommend practice for order is to have all the opaque sublayers together and then have all the transparent sublayers.
This because before rendering the pixels to the render target, it will test on a per pixel basis whether it should render a mesh to that pixel by testing against the Z/depth buffer (unless depth testing is disabled on the mesh/material).
The depth buffer represents the closest distance to the camera that something has rendered to that pixel. (Learn more about Z/depth buffer here on this crash course: 3D Graphics: Crash Course Computer Science #27 - YouTube)
With transparent meshes, you want to ‘see’ through them to show what is behind them, the objects behind HAVE to be rendered first. If the transparent mesh is rendered first and that is closest to the camera, then any mesh behind won’t render because when it tests against the depth buffer on those pixels, it sees that something closer has already been rendered and therefore, doesn’t render that mesh to the render target for those pixels.
And you get the following effect:
Instead of the correct ordering and rendering:
This is why it’s so hard to get rendering order correct with complex transparent meshes. It’s VERY difficult to get the order correct for every angle, especially if they interlink and recommend to break down the mesh so that it’s easier to sort and potentially ‘fix’ via layers.
The also added gotcha is that a layer can clear the depth buffer which has to be set in code. The exception to this is the UI layer where it clears the depth buffer because it renders the screen space UI elements on top of everything that has been rendered before.
The gotcha here is that any layer AFTER the UI sublayer will render on top of what has already been rendered.
The recommended practice to have any layers that render in 3D space to be BEFORE the UI sublayer.
There was mention of changing/modifying clip values on the camera.
Bear in mind that the depth buffer only has a certain number of bits of precision (see how float numbers are represented for precision). The bigger the range between near and far clips, the lower the precision you get for the distance from the camera which can lead to Z fighting (Z-fighting - Wikipedia) if two or more polys are close together in world space.
The recommend practise is to keep the range as small as possible for the clip values and also take into consideration the distance between polys and meshes in the scene.
Example of having too large a clip range:
And example of having a suitable range: