CommandBuffer使用 - 分屏
原理
先抓取整个屏幕画面到RenderTexture1上,然后把左边一半复制到RenderTexture2,右边一半复制到RenderTexture3
效果
c#代码
using UnityEngine; using UnityEngine.Rendering; [RequireComponent(typeof(Camera))] public class SplitScreen : MonoBehaviour { public RenderTexture m_SrcScreenRT; public RenderTexture m_SplitLeftRT; public RenderTexture m_SplitRightRT; public Shader m_Shader; public Material m_Material; private CommandBuffer m_Cmd; void OnEnable() { if (null == m_Cmd) { m_Cmd = new CommandBuffer(); m_Cmd.name = "My Render Cmd"; InitMaterial(); //抓取当前屏幕 var srcScreenRTId = new RenderTargetIdentifier(m_SrcScreenRT); m_Cmd.Blit(BuiltinRenderTextureType.CurrentActive, srcScreenRTId); //横向分成2个屏幕 var splitLeftRTId = new RenderTargetIdentifier(m_SplitLeftRT); m_Cmd.SetGlobalFloat("offset", 0); m_Cmd.Blit(srcScreenRTId, splitLeftRTId, m_Material); var splitRightRTId = new RenderTargetIdentifier(m_SplitRightRT); m_Cmd.SetGlobalFloat("offset", 0.5f); m_Cmd.Blit(srcScreenRTId, splitRightRTId, m_Material); } GetComponent<Camera>().AddCommandBuffer(CameraEvent.AfterForwardAlpha, m_Cmd); } private void InitMaterial() { if (false == SystemInfo.supportsImageEffects) { Debug.LogWarning("This platform does not support image effects or render textures."); this.enabled = false; return; } if (null == m_Material) { if (null != m_Shader && m_Shader.isSupported) { m_Material = new Material(m_Shader); m_Material.hideFlags = HideFlags.DontSave; } } else if (null != m_Shader && m_Material.shader != m_Shader) { if (m_Shader.isSupported) //优先shader { m_Material = new Material(m_Shader); m_Material.hideFlags = HideFlags.DontSave; } } } void OnDisable() { GetComponent<Camera>().RemoveCommandBuffer(CameraEvent.BeforeForwardAlpha, m_Cmd); } void OnDestroy() { m_Cmd.Clear(); //清空所有渲染指令 m_Cmd.Dispose(); m_Cmd = null; } }
shader
Shader "My/Cmd/Split2ScreenHorizontal" { Properties { _MainTex("Base (RGB)", 2D) = "" {} //主贴图 } CGINCLUDE #include "UnityCG.cginc" struct v2f //片元(段)着色器输入参数 { float4 pos : POSITION; //裁剪空间坐标值 float2 uv : TEXCOORD0; //贴图uv坐标 }; float offset; //外部参数 sampler2D _MainTex; v2f vert(appdata_img v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; o.uv.x = v.texcoord.x*0.5 + offset; //x方向将uv从[0, 1]缩放为[0, 0.5], 然后用offset参数在做调整 return o; } half4 frag(v2f i) : COLOR { half4 color = tex2D(_MainTex, i.uv); return color; } ENDCG Subshader { Pass { ZTest Always //深度测试 ZWrite Off //关闭写入深度buff Cull Off //剔除关闭 Fog { Mode off } //内置雾效 CGPROGRAM #pragma fragmentoption ARB_precision_hint_fastest #pragma vertex vert #pragma fragment frag ENDCG } } Fallback off }
参考
Unity中使用CommondBuffer完成分屏功能_unity 分屏-CSDN博客
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2023-03-28 Projector的一些参数设置
2022-03-28 红黑树-添加