Render order of shader passes (Forward rendering)

I am in need of fine grained control over rendering order of several shaders with several passes. I have exhausted the documentation on shader queuing and found out a following undocumented rule:

If objects are in opaque queue, all of their first passes are rendered first, then other passes of each object are rendered in succession:
OpaqueObject 1 Pass 1
OpaqueObject 2 Pass 1
OpaqueObject 1 Pass 2
OpaqueObject 1 Pass 3
OpaqueObject 2 Pass 2
OpaqueObject 2 Pass 3

If objects are in transparent queue (2501+), all the passes on an object are rendered before rendering the next object.
TransparentObject 1 Pass 1
TransparentObject 1 Pass 2
TransparentObject 1 Pass 3
TransparentObject 2 Pass 1
TransparentObject 2 Pass 2
TransparentObject 2 Pass 3

I assume it’s because the beginning of opaque queue is all about rendering the base pass of the forward pipeline before moving on to additive passes (even without tagging the passes ForwardBase or ForwardAdditive). What about custom shaders that do not necessarily follow the base+additive formula? Is the first-pass-priority hard-coded and to be lived with?

(rendering order of passes always seemed a bit quasi-random until I ran the test :eyes:)

2 Likes

I have not thoroughly tested this but it seems that Unity also postpones any passes in between ForwardBase and ForwardAdd. So it renders #0, #2, #2, #2, #1 where 0 is base, 2 are additive and 1 is the extra pass in between them in shader code.

I either seem to have missed a big chunk of documentation or it is yet to be written.