经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 游戏设计 » 查看文章
单相机做分屏混合
来源:cnblogs  作者:tiancaiKG  时间:2019/10/8 9:06:12  对本文有异议

  做了一个单相机实现分屏混合的功能, 需求大概就是在同一视角下, 相机通过不同的CullingMask获取不同的渲染图片RenderTexture之后, 通过某种方式一起显示在界面的功能. 其实核心逻辑就是怎样用一个相机渲染不同的图片罢了, 直接上代码:

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. [ExecuteInEditMode]
  5. public class BlendRenderTexture : MonoBehaviour
  6. {
  7. public enum BlendDirection
  8. {
  9. Horizontal = 0,
  10. Vertical = 1
  11. }
  12. [SerializeField]
  13. [Range(0, 1)]
  14. public float blend = 0.5f;
  15. [SerializeField]
  16. public BlendDirection blendDirection = BlendDirection.Horizontal;
  17. [SerializeField]
  18. public LayerMask tagLayerMask;
  19. [SerializeField]
  20. public RenderingTools.BlendRenderTextureTarget blendRenderTextureTarget;
  21. private bool m_grabbing = false;
  22. private void OnEnable()
  23. {
  24. if(blendRenderTextureTarget == null)
  25. {
  26. blendRenderTextureTarget = new RenderingTools.BlendRenderTextureTarget("Unlit/BlendRenderTexture");
  27. }
  28. }
  29. private void OnDisable()
  30. {
  31. if(blendRenderTextureTarget != null)
  32. {
  33. blendRenderTextureTarget.Release();
  34. }
  35. }
  36. void OnRenderImage(RenderTexture src, RenderTexture dest)
  37. {
  38. if(m_grabbing)
  39. {
  40. m_grabbing = false;
  41. Graphics.Blit(src, dest);
  42. return;
  43. }
  44. if(blendRenderTextureTarget.renderTexture && blendRenderTextureTarget.material)
  45. {
  46. blendRenderTextureTarget.material.SetTexture("_Left", src);
  47. blendRenderTextureTarget.material.SetTexture("_Right", blendRenderTextureTarget.renderTexture);
  48. blendRenderTextureTarget.material.SetFloat("_Blend", Mathf.Clamp01(blend));
  49. blendRenderTextureTarget.material.SetInt("_Direction", (int)blendDirection);
  50. Graphics.Blit(src, dest, blendRenderTextureTarget.material);
  51. }
  52. else
  53. {
  54. Graphics.Blit(src, dest);
  55. }
  56. }
  57. private void LateUpdate()
  58. {
  59. RenderTargetTexture();
  60. }
  61. public void RenderTargetTexture()
  62. {
  63. var material = blendRenderTextureTarget.GetMaterial();
  64. if (m_grabbing = material)
  65. {
  66. var lastMask = Camera.main.cullingMask;
  67. var lastTex = Camera.main.targetTexture;
  68. Camera.main.cullingMask = tagLayerMask;
  69. Camera.main.targetTexture = blendRenderTextureTarget.GetRenderTexture();
  70. Camera.main.Render();
  71. Camera.main.cullingMask = lastMask;
  72. Camera.main.targetTexture = lastTex;
  73. }
  74. }
  75. }

  在LateUpdate中请求目标图片渲染, 标记了m_grabbing之后, 调用到OnRenderImage, 直接就把目标渲染图片输出到我们的临时RenderTexture上了, 然后再通过正常渲染时调用OnRenderImage之后, 就会通过Material进行混合了.

  1. BlendRenderTextureTarget 只是一个资源的封装:
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public static class RenderingTools
  5. {
  6. [System.Serializable]
  7. public class BlendRenderTextureTarget
  8. {
  9. [SerializeField]
  10. public Material material = null;
  11. [SerializeField]
  12. public string shaderName = string.Empty;
  13. public RenderTexture renderTexture { get; set; }
  14. public BlendRenderTextureTarget(string shaderName)
  15. {
  16. this.shaderName = shaderName;
  17. }
  18. public Material GetMaterial()
  19. {
  20. if(material == false)
  21. {
  22. var shader = Shader.Find(shaderName);
  23. if(shader)
  24. {
  25. material = new Material(shader);
  26. material.hideFlags = HideFlags.DontSave;
  27. }
  28. }
  29. return material;
  30. }
  31. public RenderTexture GetRenderTexture()
  32. {
  33. if(renderTexture)
  34. {
  35. if(renderTexture.width != Screen.width || renderTexture.height != Screen.height)
  36. {
  37. RenderTexture.ReleaseTemporary(renderTexture);
  38. renderTexture = null;
  39. }
  40. }
  41. if(renderTexture == false)
  42. {
  43. renderTexture = RenderTexture.GetTemporary(Screen.width, Screen.height, 24, RenderTextureFormat.ARGB32);
  44. renderTexture.hideFlags = HideFlags.DontSave;
  45. }
  46. return renderTexture;
  47. }
  48. public void Release()
  49. {
  50. if(renderTexture)
  51. {
  52. RenderTexture.ReleaseTemporary(renderTexture);
  53. renderTexture = null;
  54. }
  55. if(material)
  56. {
  57. material = null;
  58. }
  59. }
  60. }
  61. }

 

  混用用到的Shader也很简单:

  1. Shader "Unlit/BlendRenderTexture"
  2. {
  3. Properties
  4. {
  5. _MainTex("Texture", 2D) = "white" {}
  6. _Left("Texture", 2D) = "white" {}
  7. _Right("Texture", 2D) = "white" {}
  8. _Blend("Blend", Range(0,1)) = 0.5
  9. [Enum(Horizontal,0,Vertical,1)] _Direction("Blend Direction", Float) = 0
  10. }
  11. SubShader
  12. {
  13. Tags { "RenderType"="Opaque" }
  14. LOD 100
  15. Pass
  16. {
  17. CGPROGRAM
  18. #pragma vertex vert
  19. #pragma fragment frag
  20. // make fog work
  21. #pragma multi_compile_fog
  22. #include "UnityCG.cginc"
  23.  
  24. struct appdata
  25. {
  26. float4 vertex : POSITION;
  27. float2 uv : TEXCOORD0;
  28. };
  29. struct v2f
  30. {
  31. float2 uv : TEXCOORD0;
  32. UNITY_FOG_COORDS(1)
  33. float4 vertex : SV_POSITION;
  34. };
  35. sampler2D _MainTex;
  36. float4 _MainTex_ST;
  37. sampler2D _Left;
  38. sampler2D _Right;
  39. float _Blend;
  40. float _Direction;
  41. v2f vert (appdata v)
  42. {
  43. v2f o;
  44. o.vertex = UnityObjectToClipPos(v.vertex);
  45. o.uv = TRANSFORM_TEX(v.uv, _MainTex);
  46. UNITY_TRANSFER_FOG(o,o.vertex);
  47. return o;
  48. }
  49. fixed4 frag (v2f i) : SV_Target
  50. {
  51. fixed4 col = 1;
  52. // sample the texture
  53. bool blend_left = (_Direction == 0) ? (i.uv.x <= _Blend) : (i.uv.y <= _Blend);
  54. if (blend_left)
  55. {
  56. col = tex2D(_Left, i.uv);
  57. }
  58. else
  59. {
  60. col = tex2D(_Right, i.uv);
  61. }
  62. // apply fog
  63. UNITY_APPLY_FOG(i.fogCoord, col);
  64. return col;
  65. }
  66. ENDCG
  67. }
  68. }
  69. }

  

原文链接:http://www.cnblogs.com/tiancaiwrk/p/11611578.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号