ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

使用Unity实现实时视频通话且对接收到的视频画面进行抠像显示

2021-01-12 17:59:27  阅读:174  来源: 互联网

标签:视频 MainTex 画面 rgb YCbCr 通话 Unity DChromaT fixed


使用Unity进行音视频通话相信大家可以在网上搜到各家的解决方案,且对摄像头画面进行实时抠像也是有成熟的插件支持,基本上五分钟就可以实现,但是在实现两者结合的过程中,还是有各种问题,需要实现这种功能的小伙伴可以借鉴一下本篇博客。
1.使用webrtc实现音视频通话功能。在github上找一个webrtc的库即可,可自行测试是否支持音频视频传输。在我们的客户端上,可以看到有一个本地画面渲染和远程画面渲染,我们需要在远程画面渲染上做手脚,至于为什么呢,我的理解是视频在webrtc传输过程中,有他设定好的编解码格式,如果我们进行抠像,再传输,会造成远程客户端识别不到我们的视频信息,从而无法视频通话。
2.在本地客户端的远程渲染物体上复制一份,我们在webrtc的视频导出到rawimage上显示的过程中,将这个画面在我们复制的画面上再赋值一次,这样就可以把两个远程的渲染画面保持一致。接下来,我们需要做的就是在我们复制的这个画面上加上我们的抠像操作,这部分使用了ChromaKey插件的一个shader,下面会贴出来,我们把这个shader制作一个材质球,将材质球拖给我们复制的rawimage组件的material属性,本地微调,将绿幕的东西扣掉成透明即可。

Shader "MSK/ChromaKey/ChromaKey_Alpha_General" {
	Properties{
		_MainTex("MainTex", 2D) = "white" {}
		_KeyColor("KeyColor", Color) = (1,1,1,1)
		_DChroma("D Chroma", range(0.0, 1.0)) = 0.5
		_DChromaT("D ChromaT", range(0.0, 1.0)) = 0.05
		_DLuma("D Luma", range(0.0, 1.0)) = 0.5
		_DLumaT("D LumaT", range(0.0, 1.0)) = 0.05
	}
	CGINCLUDE
	#include "UnityCG.cginc"
	struct VS_OUT {
		half4 position:POSITION;
		fixed2 texcoord0:TEXCOORD0;
	};

	sampler2D _MainTex;
	fixed4 _MainTex_ST;
	
	fixed4 _KeyColor;
	fixed _DChroma;
	fixed _DLuma;
	
	fixed _DLumaT;
	fixed _DChromaT;

	VS_OUT vert(appdata_base input) {
		VS_OUT o;
		o.position = UnityObjectToClipPos(input.vertex);
		o.texcoord0 = TRANSFORM_TEX(input.texcoord, _MainTex);
		return o;
	}

	fixed3 RGB_To_YCbCr(fixed3 rgb) {
		fixed Y = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b;
		fixed Cb = 0.564 * (rgb.b - Y);
		fixed Cr = 0.713 * (rgb.r - Y);
		return fixed3(Cb, Cr, Y);
	}

	fixed4 frag(VS_OUT input) : SV_Target {
		fixed4 c = tex2D(_MainTex, input.texcoord0);
		
		if (c.a > 0) {
			fixed3 src_YCbCr = RGB_To_YCbCr(c.rgb);
			fixed3 key_YCbCr = RGB_To_YCbCr(_KeyColor);

			fixed dChroma = distance(src_YCbCr.xy, key_YCbCr.xy);
			fixed dLuma = distance(src_YCbCr.z, key_YCbCr.z);

			if (dLuma < _DLuma && dChroma < _DChroma) {
				fixed a = 0;
				if (dChroma > _DChroma - _DChromaT) {
					a = (dChroma -_DChroma + _DChromaT) / _DChromaT;
				}
				if (dLuma > _DLuma - _DLumaT) {
					a = max(a, (dLuma - _DLuma + _DLumaT) / _DLumaT);
				}
				if(c.a > a) {
					c.a = a;
				}
			}
		}
		return c;
	}
	ENDCG
	
	SubShader {
		Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True" }
		Lighting Off
		ZWrite Off
		AlphaTest Off
		Blend SrcAlpha OneMinusSrcAlpha

		Pass {
			CGPROGRAM
			  #pragma vertex vert
			  #pragma fragment frag
			ENDCG
		}
	}
	Fallback Off
}

有遇到问题的,欢迎大家留言评论。

标签:视频,MainTex,画面,rgb,YCbCr,通话,Unity,DChromaT,fixed
来源: https://blog.csdn.net/qq_42419143/article/details/112540285

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有