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

}

}

相关推荐
叶帆14 天前
【YFIOs】用C#开发硬件之设备上云
开发语言·unity·c#
久数君14 天前
AI三维建模工具“造形家”:地理场景三维化的高效解决方案
unity·glb·ai算法·ai三维建模工具·地图框选·造形家·城市建筑模型
会思考的猴子15 天前
Unity VFX 属性 Postion 和 TargetPostion
unity
hai31524754315 天前
九章编程法 · 猜数字游戏 (GW-BASIC 重构版) *
人工智能·microsoft·游戏引擎·游戏程序
心前阳光15 天前
Unity资源导入之自动化资源导入
unity·自动化·游戏引擎
心前阳光15 天前
Unity之2021.3.45f2c1发布安卓程序遇到的问题
android·unity·游戏引擎
纪纯15 天前
PicoVR Unity Integration SDK 3.4 常用交互API
unity·游戏引擎·vr·pico
龙智DevSecOps解决方案15 天前
3A 游戏优化技术栈:如何打通引擎级分析工具与 DevOps 持续集成管线?
unity·性能优化·游戏开发·技术美术·perforce·unrealengine
葛兰岱尔15 天前
从 SolidWorks 到 Three.js,从 Inventor 到 Unity——制造业CAD模型“几何-语义一体化“转换,不再是天方夜谭!
开发语言·javascript·unity
鼎艺创新科技15 天前
三维电子沙盘中OSGB倾斜摄影数据的加载与渲染
游戏引擎·cocos2d