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

}

}

相关推荐
半夏知半秋4 小时前
unity中的Horizontal和Vertical介绍
笔记·学习·unity·c#·游戏引擎
Thomas_YXQ4 小时前
Unity3D ngui和ugui区别与优缺点详解
服务器·游戏·unity·unity3d·游戏开发
suzh1qian4 小时前
Unity类银河战士恶魔城学习总结(P143 Save Inventory System 保存仓库中的物品)
学习·unity·c#·游戏引擎·bug
程序员正茂6 小时前
Unity着色器Shader根据到某点的距离显示不同颜色
unity·shader·着色器
suzh1qian13 小时前
Unity类银河战士恶魔城学习总结(P146 Delete Save file-P147 Encryption of save data删除数据和加密数据)
学习·unity·c#·游戏引擎
ChoSeitaku1 天前
No.1 杀戮尖塔Godot复刻|项目概述|场景设置
游戏引擎·godot
Peter_hust1 天前
Airsim安装问题:This project was made with a different version of the Unreal Engine.
游戏引擎·虚幻
Cici_ovo1 天前
godot游戏引擎_瓦片集和瓦片地图介绍
游戏引擎·godot
Unity_RAIN1 天前
Unity Lua方向的面试真题详解
unity·面试·lua