您的位置:首页 > 移动开发 > Unity3D

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

2016-03-29 13:45 696 查看
最近讨论在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的顺序问题:
效果如图:



第一种方案满足条件2,条件1的效果不好。

2.shader叠加遮罩

这种方案需要两个视频叠加,这里是重网上下载的测试视频,视频图和遮罩图如下:


 



使用的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"
}


实现效果如图:



这种效果能同时满足条件1和2,但是要两个视频,比较麻烦,不知道有没有大神知道其他方案,遮罩换成图片也行。

3.unity自带的shader

首先用untiy的FX/Flare的shader,两种视频的播放效果如图:


 



发现能满足条件1,不能满足条件2,然后发现太亮了

然后unity自带的shader Particles/Addtive
效果如图:


 



亮度可以降下来,失去了视频原来的颜色,这也是醉了,所以,各位朋友们有其它更好的方案的欢迎交流。

项目工程文件目录:MovieTextureAlpha


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: