无法在 Unity 中屏蔽 MovieTexture

Unable to mask a MovieTexture in Unity

我目前正在 Unity 中使用 MovieTexture 播放电影并应用自定义着色器以允许使用 alpha 通道。问题是我需要屏蔽视频的上半部分,但似乎没有任何效果。我相信这是阻止它的着色器(如果我错了请纠正我)。

我尝试了 3 种不同的遮蔽技术:

不幸的是,

None 阻止了任何视频。

(这是我正在使用的 alpha 着色器:https://github.com/keijiro/AotsMovieTexture

这也是着色器的代码:

Shader "Custom/Aots Movie Texture" {
    Properties
    {
        _MainTex("Base Texture", 2D) = "" {}
        _ColorTint("Color Tint", Color) = (0.5, 0.5, 0.5, 1)
    }

    CGINCLUDE

#include "UnityCG.cginc"

sampler2D _MainTex;
half4 _ColorTint;

struct v2f
{
    float4 position : SV_POSITION;
    float2 texcoord : TEXCOORD0;
};

v2f vert(appdata_base v)
{
    v2f o;
    o.position = mul(UNITY_MATRIX_MVP, v.vertex);
    o.texcoord = v.texcoord;
    return o;
}

float4 frag(v2f i) : SV_Target 
{
    float2 uv1 = i.texcoord;
    float2 uv2 = i.texcoord;

    uv1.x *= 0.5f;
    uv2.x *= 0.5f;
    uv2.x += 0.5f;

    half4 color = tex2D(_MainTex, uv1);
    half4 mask = tex2D(_MainTex, uv2);

    color.rgb *= _ColorTint.rgb * 2;
    color.a = mask.r * _ColorTint.a;

    return color;
}

    ENDCG

    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        Pass
        {
            ZTest Always Cull Off ZWrite Off
            Fog { Mode off }
            Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            ENDCG
        }
    } 
}

编辑:

请更详细地解释我想要做什么,我们有一个 4K 视频被分成四部分。顶部的两个四边形将是独立视频,底部两个将用于 alpha 视频。我只需要隐藏顶部的两个四边形(4k 视频的上半部分),因此当视频像我链接到的着色器一样在顶部分层时,您只能看到 alpha 通道。

因此,着色器将如下所示:

Shader "Whosebug/splitVideo"{
    Properties
    {
        _MainTex("Base Texture", 2D) = "" {}
        _ColorTint("Color Tint", Color) = (0.5, 0.5, 0.5, 1)
        [MaterialToggle]ShowLeft("Show Only Left", Float) = 0 
        [MaterialToggle]ShowRight("Show Only Right", Float) = 0
    }

    CGINCLUDE

    #include "UnityCG.cginc"
    #pragma multi_compile _ SHOWLEFT_ON
    #pragma multi_compile _ SHOWRIGHT_ON
    sampler2D _MainTex;
    half4 _ColorTint;

    struct v2f
    {
        float4 position : SV_POSITION;
        float2 texcoord : TEXCOORD0;
    };

    v2f vert(appdata_base v)
    {
        v2f o;
        o.position = UnityObjectToClipPos(v.vertex);
        o.texcoord = v.texcoord;
        return o;
    }

    float4 frag(v2f i) : SV_Target
    {
        float2 uv1 = i.texcoord;
        float2 uv2 = i.texcoord;

#ifdef SHOWLEFT_ON   
        uv1.x *= 0.5;
        uv2.x *= 0.5;
#else
#ifdef SHOWRIGHT_ON
        uv1.x *= 0.5;
        uv2.x *= 0.5;
        uv2.x += 0.5;
        uv1.x += 0.5;
#endif  
#endif          
        uv1.y *= 0.5; // line 1
        uv1.y += 0.5; // line 2
        uv2.y *= 0.5;

        half4 color = tex2D(_MainTex, uv1);
        half4 mask = tex2D(_MainTex, uv2);

        color.rgb *= _ColorTint.rgb * 2;
        color.a = mask.b *_ColorTint.a;

        return color;
    }

    ENDCG

    SubShader
    {
        Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" }
        Pass
        {
            ZTest Always Cull Off ZWrite Off
            Fog{ Mode off }
            Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            ENDCG
        }
    }
}

关于顶点和片段着色器,您可以阅读 here

让我们解释一下,这是怎么回事! (偏移量)

我们希望看到被 alpha 蒙版剪切的视频! (不是吗?)

我使用那个纹理(或视频。没关系):

默认情况下,您的 Fragment 将如下所示:

 float4 frag(v2f i) : SV_Target
 {
     half4 color = tex2D(_MainTex, i.texcoord);
     return color;
 }

第一步,让我们尝试在没有遮罩的四边形上绘制两个视频!

为此,我们将默认纹理坐标保存在临时变量 float2 uv1 = i.texcoord; 中。并将 uv1.y 乘以 0.5;我们会看到什么,为什么要这样做?

我们似乎将纹理垂直拉伸了两次,而着色器只绘制了纹理的下半部分。因为 uv.y 四边形之外的上半部分坐标。是的,这很好,但我们想要视频!因此,让我们将纹理垂直移动一半的纹理坐标 uv1.y +=0.5。我们有什么?

是的!我们的视频是最好的! (仅绘制视频的示例)

 float4 frag(v2f i) : SV_Target
 {
     float2 uv1 = i.texcoord;
     uv1.y *= 0.5;
     uv1.y += 0.5;
     half4 color = tex2D(_MainTex, uv1);
     return color;
 }

第二步。 要使用掩码,我们需要两个变量来使用它!我们的纹理是单一的,但我们必须像使用两个不同的纹理一样使用它。 (视频和面具)! 声明一个新变量

float2 uv2 = i.texcoord;

并剪切上半部分视频 uv2.y *= 0.5;。与 uv1 相同的故事,但没有移动纹理。第二个变量将是

half4 mask = tex2D(_MainTex, uv2);

动物是我们的朋友!我们看不见他们,他们却看见了我们!

由于我们使用黑色进行剪切,因此我们可以从蒙版的当前颜色分配视频的 Alpha 通道。

color.a = mask.r;

没有任何设置的简单着色器将如下所示:

float4 frag(v2f i) : SV_Target
{
    float2 uv1 = i.texcoord;
    float2 uv2 = i.texcoord;      
    uv1.y *= 0.5;
    uv1.y += 0.5;
    uv2.y *= 0.5;
    half4 color = tex2D(_MainTex, uv1);
    half4 mask = tex2D(_MainTex, uv2);
    color.a = mask.r;
    return color;
}

要控制视频的透明度和当前颜色,让我们添加 _ColorTint:

//...
half4 mask = tex2D(_MainTex, uv2);
color.rgb *= _ColorTint.rgb * 2;
color.a = mask.r *_ColorTint.a;
return color;
//...

所以,你可以问我,-"why you are using mask.r?", -"r 是红色的吗?", -"why not g or b?"

答案:黑色为(0,0,0),白色为(1,1,1)。如果我使用其他渠道(gb),它不会改变任何东西。当你将 "color.a" 乘以 0 时,它将是透明的。

就这些了。

抱歉我的英语不好!