Multipass Surface Shader (or equivalent)?

Hi all.

I’m trying to create a real two-side shader. For that, I need to render two passes: one with front faces, one with back faces and flipped normals. The problem, is that I can’t define a CGPROGRAM which does surface shading in a Pass. It seems CGPROGRAM’s in passes can only do vertex/fragment shading. So how would I do this? I can’t think of a way to combine the two passes into one, and I also can’t figure out a way to do two surface shader passes. Any help would be highly appreciated.

You can’t explicitly define passes for surface shaders; Unity creates them automatically. But that doesn’t mean you can’t have multipass surface shaders - you just list the appropriate surface shader code one after another and, in the compiled output, Unity will create the corresponding passes, one after another.

For example, a material using the following surface shader renders green front faces and red back faces:

Shader "Custom/DoubleSided" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200

            // Render back faces first
		Cull Front
		CGPROGRAM
		#pragma surface surf Lambert vertex:vert

		sampler2D _MainTex;

		struct Input {
			float2 uv_MainTex;
		};

		// Flip normal for back faces
		void vert (inout appdata_full v) {
        	v.normal *= -1;
      	}

            // Red back faces
		void surf (Input IN, inout SurfaceOutput o) {
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = fixed3(1,0,0);
			o.Alpha = c.a;
		}
		ENDCG
		
		// Now render front faces
		Cull Back
		CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _MainTex;

		struct Input {
			float2 uv_MainTex;
		};

            // Green front faces
		void surf (Input IN, inout SurfaceOutput o) {
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = fixed3(0,1,0);
			o.Alpha = c.a;
		}
		ENDCG
		
		
	} 
	FallBack "Diffuse"
}

Applied to a cylinder mesh with the top face removed gives:

20312-doublesided.jpg

You can’t. You need to use either a vertex shader or two separate shaders, and give the object two materials. I have a package on the asset store that does exactly this using the second of those methods: Unity Asset Store - The Best Assets for Game Making