unity绿幕抠图

先说实现的效果
在相机照画面中改变指定像素的透明度,实现抠图效果

跟着本文的节奏,5分钟之内实现效果(前提:电脑有摄像头)

1.打开设备相机

就这么开

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class MT_Camera : MonoBehaviour
{
    public GameObject raw_Image;//记住这个raw_Image
    RawImage cam_Video;
    //Toggle tog_togCamera;
    WebCamTexture camTexture;
    public int w_cam = 640;
    public int h_cam = 480;

    private void Awake()
    {
        //uiRoot = GameObject.Find("Canvas_UI").transform;
        //camRoot = GameObject.Find("Canvas_WebCam").transform;
    }
    private void OnEnable()
    {
        //cam_Video = raw_Image.GetComponent<RawImage>();
        //changeCam(false);
    }
    private void Start()
    {
        cam_Video = raw_Image.GetComponent<RawImage>();
        changeCam(false);


        //tog_togCamera = uiRoot.Find("tog_ChangeCam").GetComponent<Toggle>();
        //transform.GetComponent<CanvasScaler>().referenceResolution = new Vector2(Screen.width, Screen.height);
        //tog_togCamera.onValueChanged.AddListener(changeCam);
        //tog_togCamera.isOn = true;
        ///自适应屏幕分辨率显示摄像头数据
        //宽度不变,缩放高度自适应显示摄像头数据
        //cam_Video.rectTransform.sizeDelta = new Vector2(h_cam * Screen.height / w_cam, Screen.width);
        //宽度不变,缩放宽度自适应显示摄像头数据
        //cam_Video.rectTransform.sizeDelta = new Vector2(Screen.height, w_cam * Screen.width / h_cam);
    }
    void changeCam(bool isOn)
    {
        StartCoroutine(CallCamera(isOn));
    }
    IEnumerator CallCamera(bool isOn)
    {
        yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
        if (Application.HasUserAuthorization(UserAuthorization.WebCam))
        {
            if (camTexture != null)
                camTexture.Stop();
            WebCamDevice[] cameraDevices = WebCamTexture.devices;
            string deviceName = "";
            for (int i = 0; i < cameraDevices.Length; i++)
            {
                //如果是前置摄像机  
                if (WebCamTexture.devices[i].isFrontFacing && isOn)
                {
                    deviceName = WebCamTexture.devices[i].name;
                    TurnCam(isOn);
                    break;
                }
                //如果是后置摄像机  
                else if (!WebCamTexture.devices[i].isFrontFacing && !isOn)
                {
                    deviceName = WebCamTexture.devices[i].name;
                    TurnCam(isOn);
                    break;
                }
            }
            camTexture = new WebCamTexture(deviceName, w_cam, h_cam, 12);
            cam_Video.texture = camTexture;
            print("**********"+cam_Video.texture.width+ "**********" + cam_Video.texture.height);
            camTexture.Play();
        }
    }
    /// <summary>
    /// 翻转plane,正确显示摄像头数据
    /// </summary>
    /// <param name="isOn">If set to <c>true</c> is turn.</param>
    public void TurnCam(bool isOn)
    {
#if UNITY_IOS || UNITY_IPHONE
        if (!isOn)
            cam_Video.rectTransform.localEulerAngles = new Vector3(180, 0, 90);
        else cam_Video.rectTransform.localEulerAngles = new Vector3(0, 0, -90);
#elif UNITY_ANDROID
        if (!isOn)
            cam_Video.rectTransform.localEulerAngles = new Vector3(180, 180, 90);
        else cam_Video.rectTransform.localEulerAngles = new Vector3(0, 180, 90);
#endif
    }
}

2.在场景中创建raw_Image

把这个raw_Image拖放到上一个脚本组件上

3.把使用了下方shader的材质球放进raw_image中的这个位置

在这里插入图片描述
下面是一个shader
这个shader就是扣图的核心

Shader "Demo/SpriteShader"
 {  
     Properties
     {
 	   	[PerRendererData]_MainTex ("Sprite Texture", 2D) = "white" {}    //   当前的Sprite图(添加[PerRendererData]后在属性面板中不可见) 
        _Color ("Alpha Color Key", Color) = (0,0,0,1)                               // 用于比较的基色(想过滤掉什么颜色,这个颜色就设置为那种颜色)
        _Range("Range",Range (0, 1.01))=0.1          							// 决定抠图范围的域                                
        [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0                     // 在属性面板中以按钮形式显示(在此Shader中没用到)
     }
     SubShader
     {
       //Sprite图一般均为透明贴图,需要做以下处理
         Tags 
         { 
         	"Queue"="Transparent" 
         	"IgnoreProjector"="True" 
         	"RenderType"="Transparent" 
         	"PreviewType"="Plane"
         	"CanUseSpriteAtlas"="True"
         }
 
         Pass
         {
           //Sprite图一般均为透明贴图,需要做以下处理
         	Cull Off
     		Lighting Off
     		ZWrite Off
     		Fog { Mode Off } 
     		Blend SrcAlpha OneMinusSrcAlpha    //Sprite图一般均为透明贴图,需要做以下处理
 
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
 
             sampler2D _MainTex;
             float4 _Color;
             half _Range;
             struct Vertex
             {
                 float4 vertex : POSITION;
                 float2 uv_MainTex : TEXCOORD0;
                 float2 uv2 : TEXCOORD1;
             };
 
             struct Fragment
             {
                 float4 vertex : POSITION;
                 float2 uv_MainTex : TEXCOORD0;
             };
 
             Fragment vert(Vertex v)
             {
                 Fragment o;
 
                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                 o.uv_MainTex = v.uv_MainTex;
 
                 return o;
             }
 
             float4 frag(Fragment IN) : COLOR
             {
                 float4 o = float4(1, 1, 1, 1);
 
                 half4 c = tex2D (_MainTex, IN.uv_MainTex);
                 o.rgb = c.rgb;
                 //使用当前像素颜色与基色相减,然后与域相比较以决定是否将其显示出来
                 if(abs(c.r-_Color.r)<_Range && abs(c.g-_Color.g)<_Range && abs(c.b-_Color.b)<_Range)
                 {
                     o.a = 0;
                 }
                 else
                 {
                     o.a = 1;
                 }
 
                 return o;
             }
 
             ENDCG
         }
     }
 }

总结:1.打开设备相机
2.创建raw_Image用于显示设备相机看到的画面
3.把shader用在raw_Image上

运行程序吧

问题:怎么设置将要被剔除的颜色
答:调节材质球上的Alpha Color Key

感谢前辈们分享的资料
打开相机参考地址:https://blog.csdn.net/qq_16929759/article/details/80355510
抠图参考地址:https://blog.csdn.net/e295166319/article/details/80509979

posted @ 2022-06-22 18:05  哒哒哒~~~  阅读(654)  评论(0编辑  收藏  举报