Unity播放带Alpha通道的视频(unity play channel movie)

最近讨论在unity播放带alpha通道的视频,一开始一点效果也没有,然后搜索各种解决方案,总结出三种不太好的方案,有更好的方案的希望大家提出来。

方案重点两个方面:

        1.能否播放带alpha通道的视频

        2.播放的视频和三维场景的层级关系


1.剔除

使用一个剔除的shader,不渲染黑色部分
shader代码如下:
Shader "AlphaVideo/CullingVideo" 
{
	Properties
	{
		_MainTex("Base (RGB)", 2D) = "white" {}
		_AlphaOffsetX("alpha offset x", float) = 0.5
		_AlphaOffsetY("alpha offset y", float) = 0
		_Cutoff("Cutoff", Range(-1,0)) = -0.3
	}
		
	SubShader
	{
		//Lighting Off
		AlphaTest Less[_Cutoff]
		Tags{ "Queue" = "Transparent-20" "IgnoreProjector" = "True" "RenderType" = "Transparent" }

		LOD 300

		CGPROGRAM
		#pragma surface surf Lambert alphatest:_Cutoff

		sampler2D _MainTex;
		float _AlphaOffsetX;
		float _AlphaOffsetY;

		struct Input 
		{
			float2 uv_MainTex;
		};

		void surf(Input IN, inout SurfaceOutput o) 
		{
			half4 c = tex2D(_MainTex, IN.uv_MainTex);
			IN.uv_MainTex.x += _AlphaOffsetX;
			IN.uv_MainTex.y += _AlphaOffsetY;
			half4 d = tex2D(_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Alpha = ((d.r*-1) + 1)*-1;
		}

		ENDCG
	}
	
	// FallBack "Diffuse"
	FallBack "Transparent/Diffuse"
}
编写一个播放视频的C#脚本如下:
using UnityEngine;
using System.Collections;

public class MovieControl : MonoBehaviour
{

    public MovieTexture movie;
    public AudioClip movieSound;

    void Start()
    {
        Play();
    }

    public void Play()
    {
        if (movie != null)
        {
            MovieTexture temp = (MovieTexture)gameObject.GetComponent<MeshRenderer>().sharedMaterial.mainTexture;

            if (temp != null)
            {
                temp.Stop();
            }

            gameObject.GetComponent<MeshRenderer>().sharedMaterial.mainTexture = movie;
            movie.Play();
            if (movieSound != null)
            {
                GetComponent<AudioSource>().clip = movieSound;
                GetComponent<AudioSource>().Play();
            }
        }
    }

    public void Stop()
    {
        movie.Stop();
    }

}
在场景的面板前后简历两个小方块,测试视频与3d的顺序问题:
效果如图:
Unity播放带Alpha通道的视频(unity play channel movie)_第1张图片
第一种方案满足条件2,条件1的效果不好。

2.shader叠加遮罩

这种方案需要两个视频叠加,这里是重网上下载的测试视频,视频图和遮罩图如下:
Unity播放带Alpha通道的视频(unity play channel movie)_第2张图片  
使用的shader如下:
Shader "AlphaVideo/MaskVideo"
{
	Properties
	{
		_MainTex("MainTex", 2D) = "white" {}
		_Mask("Mask", 2D) = "white" {}
		_Transparency("Transparency", Range(0, 1)) = 0
		_Color("Color", Color) = (0.4485294,0.310013,0.310013,1)
		[HideInInspector]_Cutoff("Alpha cutoff", Range(0,1)) = 0.5
	}
		
	SubShader
	{
		Tags
		{
			"IgnoreProjector" = "True"
			"Queue" = "Transparent"
			"RenderType" = "Transparent"
		}

		Pass
		{
			Name "FORWARD"
			Tags {"LightMode" = "ForwardBase"}
			Blend SrcAlpha OneMinusSrcAlpha
			ZWrite Off

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#define UNITY_PASS_FORWARDBASE
			#include "UnityCG.cginc"
			#include "UnityPBSLighting.cginc"
			#include "UnityStandardBRDF.cginc"
			#pragma multi_compile_fwdbase
			#pragma exclude_renderers gles3 metal d3d11_9x xbox360 xboxone ps3 ps4 psp2 
			#pragma target 3.0
		
			uniform sampler2D _MainTex; uniform float4 _MainTex_ST;
			uniform sampler2D _Mask; uniform float4 _Mask_ST;
			uniform float _Transparency;
			uniform float4 _Color;

			struct VertexInput 
			{
				float4 vertex : POSITION;
				float2 texcoord0 : TEXCOORD0;
			};

			struct VertexOutput 
			{
				float4 pos : SV_POSITION;
				float2 uv0 : TEXCOORD0;
			};
	
			VertexOutput vert(VertexInput v) 
			{
				VertexOutput o = (VertexOutput)0;
				o.uv0 = v.texcoord0;
				o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
				return o;
			}
	
			float4 frag(VertexOutput i) : COLOR
			{
				float4 _MainTex_var = tex2D(_MainTex,TRANSFORM_TEX(i.uv0, _MainTex));
				float3 emissive = (_Color.rgb*_MainTex_var.rgb);
				float3 finalColor = emissive;
				float4 _Mask_var = tex2D(_Mask,TRANSFORM_TEX(i.uv0, _Mask));
				return fixed4(finalColor,((lerp(lerp(lerp(_Mask_var.b, _Mask_var.r, _Mask_var.rgb.r), _Mask_var.g, _Mask_var.rgb.g), _Mask_var.b, _Mask_var.rgb.b))*_Transparency));
			}
				
			ENDCG
		}

	}
		
	FallBack "Diffuse"
	CustomEditor "ShaderForgeMaterialInspector"
}

实现效果如图:

Unity播放带Alpha通道的视频(unity play channel movie)_第3张图片
这种效果能同时满足条件1和2,但是要两个视频,比较麻烦,不知道有没有大神知道其他方案,遮罩换成图片也行。

3.unity自带的shader

首先用untiy的FX/Flare的shader,两种视频的播放效果如图:
Unity播放带Alpha通道的视频(unity play channel movie)_第4张图片  
发现能满足条件1,不能满足条件2,然后发现太亮了

然后unity自带的shader Particles/Addtive
效果如图:
 
亮度可以降下来,失去了视频原来的颜色,这也是醉了,所以,各位朋友们有其它更好的方案的欢迎交流。

项目工程文件目录:MovieTextureAlpha


你可能感兴趣的:(视频,C#,unity3d,shader,虚拟现实)