分享

Unity制作深度相机

 雪柳花明 2016-11-07
这里需要3个脚本

1.脚本部分


后处理脚本主要做的是两件事,第一件是获取需要的shader,生成材质,第二件是通过OnRenderImage使用材质处理屏幕效果。第一步具有一些普遍性,不管是什么后处理效果,都要有这一步相同的操作,所以我们将该步骤抽离出来,创建一个后处理效果的基类PostEffectBase,代码如下
1.
[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. //非运行时也触发效果  
  5. [ExecuteInEditMode]  
  6. //屏幕后处理特效一般都需要绑定在摄像机上  
  7. [RequireComponent(typeof(Camera))]  
  8. //提供一个后处理的基类,主要功能在于直接通过Inspector面板拖入shader,生成shader对应的材质  
  9. public class PostEffectBase : MonoBehaviour {  
  10.   
  11.     //Inspector面板上直接拖入  
  12.     public Shader shader = null;  
  13.     private Material _material = null;  
  14.     public Material _Material  
  15.     {  
  16.         get  
  17.         {  
  18.             if (_material == null)  
  19.                 _material = GenerateMaterial(shader);  
  20.             return _material;  
  21.         }  
  22.     }  
  23.   
  24.     //根据shader创建用于屏幕特效的材质  
  25.     protected Material GenerateMaterial(Shader shader)  
  26.     {  
  27.         if (shader == null)  
  28.             return null;  
  29.         //需要判断shader是否支持  
  30.         if (shader.isSupported == false)  
  31.             return null;  
  32.         Material material = new Material(shader);  
  33.         material.hideFlags = HideFlags.DontSave;  
  34.         if (material)  
  35.             return material;  
  36.         return null;  
  37.     }  
  38.        
  39. }  



C#脚本
[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. [ExecuteInEditMode]  
  5. public class DepthTextureTest : PostEffectBase  
  6. {  
  7.     void OnEnable()  
  8.     {  
  9.         GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;  
  10.     }  
  11.   
  12.     void OnDisable()  
  13.     {  
  14.         GetComponent<Camera>().depthTextureMode &= ~DepthTextureMode.Depth;  
  15.     }  
  16.   
  17.     void OnRenderImage(RenderTexture source, RenderTexture destination)  
  18.     {  
  19.         if (_Material)  
  20.         {  
  21.             Graphics.Blit(source, destination, _Material);  
  22.         }  
  23.     }  
  24. }  
shader部分:
[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. Shader "Custom/DepthTest" {  
  2.   
  3.     CGINCLUDE  
  4.     #include "UnityCG.cginc"  
  5.   
  6.     //仍然要声明一下_CameraDepthTexture这个变量,虽然Unity这个变量是unity内部赋值  
  7.     sampler2D _CameraDepthTexture;  
  8.     sampler2D _MainTex;  
  9.     float4    _MainTex_TexelSize;  
  10.   
  11.     struct v2f  
  12.     {  
  13.         float4 pos : SV_POSITION;  
  14.         float2 uv  : TEXCOORD0;  
  15.     };  
  16.   
  17.     v2f vert(appdata_img v)  
  18.     {  
  19.         v2f o;  
  20.         o.pos = mul(UNITY_MATRIX_MVP, v.vertex);  
  21.         o.uv.x=1-v.texcoord.x;//x轴对称
  22. o.uv.y=v.texcoord.y;
  23.   
  24.         return o;  
  25.     }  
  26.   
  27.     fixed4 frag(v2f i) : SV_Target  
  28.     {  
  29.         //直接根据UV坐标取该点的深度值  
  30.         float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, 1 - i.uv);  
  31.         //将深度值变为线性01空间  
  32. //靠近摄像机的白,远离的黑
  33.         depth = 1-Linear01Depth(depth);  
  34.         return float4(depth, depth, depth, 1);  
  35.     }  
  36.   
  37.     ENDCG  
  38.   
  39.     SubShader  
  40.     {  
  41.         Pass  
  42.         {  
  43.   
  44.             ZTest Off  
  45.             Cull Off  
  46.             ZWrite Off  
  47.             Fog{ Mode Off }  
  48.   
  49.             CGPROGRAM  
  50.             #pragma vertex vert  
  51.             #pragma fragment frag  
  52.             ENDCG  
  53.         }  
  54.   
  55.     }  
  56. }  

 找一个场景,将该脚本挂在摄像机并赋予材质。(注:PostEffectBase类为后处理基类,在之前的文章中有详细实现,此处不予贴出),找到一个场景,我们测试一下:


这张图中,我把摄像机的远裁剪面调整到了50这一比较小的距离,这样,图中的远近信息显示得更加明显




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多