unity 绿幕抠图

1.硬件:Insta360 Link 2C摄像机

2.引用shader

Shader "Demo/ChromaKey"

{

Properties

{

_MainTex("Texture", 2D) = "white" {}

_KeyColor("KeyColor", Color) = (0,1,0,0)

_TintColor("TintColor", Color) = (1,1,1,1)

_ColorCutoff("Cutoff", Range(0, 1)) = 0.2

_ColorFeathering("ColorFeathering", Range(0, 1)) = 0.33

_MaskFeathering("MaskFeathering", Range(0, 1)) = 1

_Sharpening("Sharpening", Range(0, 1)) = 0.5

_Despill("DespillStrength", Range(0, 1)) = 1

_DespillLuminanceAdd("DespillLuminanceAdd", Range(0, 1)) = 0.2

}

SubShader

{

Tags

{

// "RenderPipeline"="HDRenderPipeline"

// "RenderType"="HDUnlitShader"

"Queue" = "Transparent+1"

}

Blend SrcAlpha OneMinusSrcAlpha

ZWrite Off

cull off

Pass

{

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

struct appdata

{

float4 vertex : POSITION;

float2 uv : TEXCOORD0;

};

struct v2f

{

float2 uv : TEXCOORD0;

float4 vertex : SV_POSITION;

};

sampler2D _MainTex;

float4 _MainTex_TexelSize;

float4 _MainTex_ST;

float4 _KeyColor;

float4 _TintColor;

float _ColorCutoff;

float _ColorFeathering;

float _MaskFeathering;

float _Sharpening;

float _Despill;

float _DespillLuminanceAdd;

// Utility functions -----------

float rgb2y(float3 c)

{

return (0.299 * c.r + 0.587 * c.g + 0.114 * c.b);

}

float rgb2cb(float3 c)

{

return (0.5 + -0.168736 * c.r - 0.331264 * c.g + 0.5 * c.b);

}

float rgb2cr(float3 c)

{

return (0.5 + 0.5 * c.r - 0.418688 * c.g - 0.081312 * c.b);

}

float colorclose(float Cb_p, float Cr_p, float Cb_key, float Cr_key, float tola, float tolb)

{

float temp = (Cb_key - Cb_p) * (Cb_key - Cb_p) + (Cr_key - Cr_p) * (Cr_key - Cr_p);

float tola2 = tola * tola;

float tolb2 = tolb * tolb;

if (temp < tola2) return (0);

if (temp < tolb2) return (temp - tola2) / (tolb2 - tola2);

return (1);

}

float maskedTex2D(sampler2D tex, float2 uv)

{

float4 color = tex2D(tex, uv);

// Chroma key to CYK conversion

float key_cb = rgb2cb(_KeyColor.rgb);

float key_cr = rgb2cr(_KeyColor.rgb);

float pix_cb = rgb2cb(color.rgb);

float pix_cr = rgb2cr(color.rgb);

return colorclose(pix_cb, pix_cr, key_cb, key_cr, _ColorCutoff, _ColorFeathering);

}

//-------------------------

v2f vert(appdata v)

{

v2f o;

o.vertex = UnityObjectToClipPos(v.vertex);

o.uv = TRANSFORM_TEX(v.uv, _MainTex);

return o;

}

float4 frag(v2f i) : SV_Target

{

// Get pixel width

float2 pixelWidth = float2(1.0 / _MainTex_TexelSize.z, 0);

float2 pixelHeight = float2(0, 1.0 / _MainTex_TexelSize.w);

// Unmodified MainTex

float4 color = tex2D(_MainTex, i.uv);

// Unfeathered mask

float mask = maskedTex2D(_MainTex, i.uv);

// Feathering & smoothing

float c = mask;

float r = maskedTex2D(_MainTex, i.uv + pixelWidth);

float l = maskedTex2D(_MainTex, i.uv - pixelWidth);

float d = maskedTex2D(_MainTex, i.uv + pixelHeight);

float u = maskedTex2D(_MainTex, i.uv - pixelHeight);

float rd = maskedTex2D(_MainTex, i.uv + pixelWidth + pixelHeight) * .707;

float dl = maskedTex2D(_MainTex, i.uv - pixelWidth + pixelHeight) * .707;

float lu = maskedTex2D(_MainTex, i.uv - pixelHeight - pixelWidth) * .707;

float ur = maskedTex2D(_MainTex, i.uv + pixelWidth - pixelHeight) * .707;

float blurContribution = (r + l + d + u + rd + dl + lu + ur + c) * 0.12774655;

float smoothedMask = smoothstep(_Sharpening, 1, lerp(c, blurContribution, _MaskFeathering));

float4 result = color * smoothedMask;

// Despill

float v = (2 * result.b + result.r) / 4;

if (result.g > v) result.g = lerp(result.g, v, _Despill);

float4 dif = (color - result);

float desaturatedDif = rgb2y(dif.xyz);

result += lerp(0, desaturatedDif, _DespillLuminanceAdd);

return float4(result.xyz, smoothedMask) * _TintColor;

}

ENDCG

}

}

}

3.代码

public RawImage rawImage;//相机渲染的UI

private string WebCamName = @"Insta360 Virtual Camera";

private WebCamTexture webCamTexture;

void Start()

{

ToOpenCamera();

}

/// <summary>

/// 打开摄像机

/// </summary>

public void ToOpenCamera()

{

StartCoroutine("OpenCamera");

}

public IEnumerator OpenCamera()

{

int maxl = Screen.width;

if (Screen.height > Screen.width)

{

maxl = Screen.height;

}

// 申请摄像头权限

yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);

if (Application.HasUserAuthorization(UserAuthorization.WebCam))

{

if (webCamTexture != null)

{

webCamTexture.Stop();

}

// 监控第一次授权,是否获得到设备(因为很可能第一次授权了,但是获得不到设备,这里这样避免)

// 多次 都没有获得设备,可能就是真没有摄像头,结束获取 camera

int i = 0;

while (WebCamTexture.devices.Length <= 0 && 1 < 300)

{

yield return new WaitForEndOfFrame();

i++;

}

if (WebCamTexture.devices.Length <= 0)

{

Debug.LogError("没有摄像头设备,请检查");

}

else

{

webCamTexture = new WebCamTexture(WebCamName, maxl == Screen.height ? Screen.width : Screen.height, maxl, 30)

{

//使纹理平铺

wrapMode = TextureWrapMode.Repeat

};

// 渲染到 UI 或者 游戏物体上

if (rawImage != null)

{

rawImage.texture = webCamTexture;

}

webCamTexture.Play();

}

}

else

{

Debug.LogError("未获得读取摄像头权限");

}

}

private void OnApplicationPause(bool pause)

{

// 应用暂停的时候暂停camera,继续的时候继续使用

if (webCamTexture != null)

{

if (pause)

{

webCamTexture.Pause();

}

else

{

webCamTexture.Play();

}

}

}

private void OnDestroy()

{

if (webCamTexture != null)

{

webCamTexture.Stop();

}

}

相关推荐
墨笺染尘缘8 小时前
Unity——鼠标是否在某个圆形Image范围内
unity·c#·游戏引擎
Thomas_YXQ9 小时前
Unity3D项目开发中的资源加密详解
游戏·3d·unity·unity3d·游戏开发
qq_4286396113 小时前
虚幻基础-1:cpu挑选(14600kf)
游戏引擎·虚幻
杀死一只知更鸟debug15 小时前
Unity自学之旅05
unity·游戏引擎
qq_59821175716 小时前
Unity编辑拓展显示自定义类型
unity·游戏引擎
你疯了抱抱我17 小时前
【VRChat · 改模】Unity2019、2022的版本选择哪个如何决策,功能有何区别;
unity·vr·vrchat
东方猫17 小时前
UE虚幻引擎No Google Play Store Key:No OBB found报错如何处理?
游戏引擎·虚幻
Thomas_YXQ19 小时前
Unity3D 动态骨骼性能优化详解
开发语言·网络·游戏·unity·性能优化·unity3d
Yungoal1 天前
Unity入门1
unity·游戏引擎
qq_428639611 天前
虚幻基础1:hello world
游戏引擎·虚幻