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();

}

}

相关推荐
90后小陈老师10 小时前
Unity教学 项目2 2D闯关游戏
游戏·unity·游戏引擎
噗噗夹的TA之旅11 小时前
Unity Shader 学习20:URP LitForwardPass PBR 解析
学习·unity·游戏引擎·图形渲染·技术美术
nnsix11 小时前
Unity ReferenceFinder插件 多选资源查找bug解决
unity·游戏引擎·bug
gzroy12 小时前
Unity Shader Graph实现全息瞄准器
unity·游戏引擎
90后小陈老师15 小时前
Unity教学 基础介绍
unity·游戏引擎
90后小陈老师15 小时前
Unity教学 项目3 3D坦克大战
3d·unity·游戏引擎
秦奈17 小时前
Unity复习学习随笔(五):Unity基础
学习·unity·游戏引擎
nnsix18 小时前
Unity ReferenceFinder插件 窗口中选择资源时 同步选择Assets下的资源
java·unity·游戏引擎
麷飞花19 小时前
unity3d scene窗口选中物体, 在 hierarchy高光显示
unity·editor·unity3d·u3d·hierarchy
ۓ明哲ڪ20 小时前
Unity功能——关闭脚本自动编译(Unity2021.3)
unity·游戏引擎