花式分屏,顧名思義,可以實現各種不規則幾何邊界的分屏,是無法直接通過調整相機視口能達到效果的(只能實現矩形的分屏),例如斜對角分屏,幾何圖形分屏:
假設我們有兩個相機,需要上面的斜對角分屏畫面,和鏡子效果(假如我們想通過分屏的方式實現)。
方式1:兩個相機分別添加兩個RenderTexture,繪制在兩張Image上,上層的Image可以通過遮罩實現剔除。
缺點:RenderTexture占內存高,遮罩也比較耗性能。
方式2:一個主相機渲染畫面,一個輔助相機生成RenderTexture。實現一個shader,在Fragment Shader時,通過UV坐標區域判定(比如斜對角分割,分割線UV坐標必然是y = x)選擇性將輔助相機的像素替換主相機的像素。
Shader "Custom/Shader" { Properties{ _MainTex("Base (RGB) Trans (A)", 2D) = "white" {}//主相機的紋理 _OtherTex("Other Tex", 2D) = "white" {}//輔助相機的紋理 } SubShader{ Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" } LOD 100 Cull Off Blend Off//關閉混合 Pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata_t { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; half2 texcoord : TEXCOORD0; }; sampler2D _MainTex; sampler2D _OtherTex; float4 _MainTex_ST; v2f vert(appdata_t v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } fixed4 frag(v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.texcoord)*ceil( i.texcoord.x - i.texcoord.y) + tex2D(_OtherTex, i.texcoord)*ceil( -i.texcoord.x + i.texcoord.y); return col; } ENDCG } } FallBack "Diffuse" }
實例化自定義shader的材質球,給主相機添加OnRenderImage回調方法,傳入輔助相機的紋理,並重新通過材質渲染:
void OnRenderImage(RenderTexture src, RenderTexture dest) { if (cam) { if (cam.targetTexture == null) { cam.targetTexture = new RenderTexture(cam.pixelWidth, cam.pixelHeight, 0); //根據主相機的寬高創建一個同樣寬高的紋理,記錄輔助相機的圖像 } mat.SetTexture("_OtherTex", cam.targetTexture);//傳入輔助相機的紋理 } Graphics.Blit(src, dest, mat); }
效果圖:
缺點: 還是有一個RenderTexture。
方式3:添加一個主相機,一個副相機,主相機設置更高的深度。副相機的CullingMask去掉TransparentFX層。
然后添加自定義shader,不需要顯示紋理,RenderQueue指定為BackGround,並添加對應的材質球。
Shader "Mask/SplitScreen" { //Simple depthmask shader SubShader { Tags {Queue = Background} Pass {ColorMask 0} } }
接下來在主相機下添加一個Plane,設置Layer為TransparentFx,指定剛才的材質球,調整合適位置和角度,就實現了特殊的分屏效果。