- Home /
Is 6-pass skybox shader with different geometry per pass a special case?
The default skybox shader (RenderFX/Skybox) takes 6 cube face textures and specifies 6 passes (1 for each cube face). In each pass it renders a different side of the skybox cube.
I thought that each pass of a shader would redraw the exact same geometry per pass. Is rendering unique geometry in each pass a special case for the skybox, or something that can generally be done with any shader and/or mesh?
$$anonymous$$ore info on this: If you have 6 passes defined, each cube face is rendered in its own pass. But if you have less than 6 defined, all cube faces will be drawn in each pass. So there must be something special about the skybox setup.
I would guess they are not rendering pieces of the mesh/geo, but rather rendering the whole mesh with just a piece that has texture. There's many ways you can combine them post-render, but the easiest to me would be adding all the images together, and assuring that the untextured area is black.
But since it's a cube, it could indeed be 6 planes I suppose... Though normally, no, you cannot render pieces of a single mesh from a shader. You'd have to separate them into different meshes.
Does this help at all?
I'm fairly certain this is always 6 pieces of geometry (1 per face). $$anonymous$$y main question was just about how it knows to do only 1 unique pass for each face ins$$anonymous$$d of doing all passes for each face.
Because if I only have 5 passes defined in the shader, it does all 5 passes for each face. You can tell by making the blendmode additive and see the multiple passes adding on top of each other. But this doesn't happen if you have 6 passes defined.
Unless I hear different, I'll just assume this is some special skybox code done behind the scenes that isn't generally usable.
If that's the case, then it is 6 different meshes, at least if it adheres to how the rest of Unity works...
Perhaps it uses $$anonymous$$aterial.SetPass to individually set the pass on the material before perfor$$anonymous$$g a render call? That way it could set the pass and visibility for each plane and call render.
You may be correct though, it is black-boxed so it may be a special case. No way to know without asking Unity devs directly I'd guess...
Hope this helped.
Ah, didn't know about $$anonymous$$aterial.SetPass. That could definitely be what the skybox is using. Thanks for the info.
Answer by sirbrialliance · May 05, 2017 at 07:55 PM
Empirically, yes.
Test case: I grabbed the default procedural skybox shader and added a number of these "empty" passes to the end of it:
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct appdata_t { float4 vertex : POSITION; };
struct v2f { float4 vertex : SV_POSITION; };
v2f vert(appdata_t v) {v2f o;o.vertex = UnityObjectToClipPos(v.vertex);return o;}
half4 frag(v2f i) : COLOR { discard; return (float4)0;}
ENDCG
}
If I add exactly 5 (for a total of 6 passes) the shader stops rendering correctly: it only renders one side of a cube. If I add 1-4 copies, or 6+ copies it continues to work correctly.
Additionally, normally Unity (5.6.0) renders the skybox with a spherical mesh that has 5040 verts (check the frame debugger or look at it under NSight). If I have exactly 6 passes, it switches from rendering that mesh to a 6-vert (2 tri) quad - one quad per side of a cube.
Your answer

Follow this Question
Related Questions
Errors with ENDCG in shaders 1 Answer
Is it possible to get back data for a specific vertex from a shader ? 0 Answers
Skybox blending 2 Answers
Unity 5 Skybox not Rotating 3 Answers
Represent Land 3D Area End 0 Answers