zoukankan      html  css  js  c++  java
  • Shader实例:一台旧电视

    准备:
    1.一段小视频
    2.一张电视机贴图
    3.一张过滤图

    效果:
    让视频内容只在电视机屏幕区域显示

    Shader代码:有注释

    Shader "Joe/old_tv"
    {
        Properties
        {
            _MainTex("main tex", 2d) = ""{}//主贴图
            _TVTex("TV tex",2d) = ""{}//屏幕内容
            _TVMask("TV mask",2d) = ""{}//过滤贴图
        }
     
        SubShader
        {
            Tags
            {
                "Queue"  = "Transparent"
            }
     
            Blend SrcAlpha OneMinusSrcAlpha
     
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
     
                #include "UnityCG.cginc"
     
                struct v2f
                {
                    float4 vertex:POSITION;
                    float4 uv:TEXCOORD0;
                };
     
                sampler2D _MainTex;
                sampler2D _TVTex;//视频内容从脚本本中设置
                sampler2D _TVMask;
     
                v2f vert(appdata_base v)
                {
                    v2f o;
                    o.vertex = mul(UNITY_MATRIX_MVP,v.vertex);
                    o.uv.xy = v.texcoord.xy;
                    return o;
                }
     
                half4 frag(v2f i):COLOR
                {
                    //采样电视机贴图
                    half4 tv = tex2D(_MainTex,i.uv.xy);
     
                    //采样过滤贴图
                    half4 mask = tex2D(_TVMask,i.uv.xy);
     
                    //得到用过滤图的alpha值作为权重 影响过后的uv
                    half2 maskuv = i.uv.xy * mask.a;
     
                    //用该uv,采样屏幕内容,根据过滤图的alpha值,得到内容只在电视机屏幕区域显示的效果
                    half4 tvcontent = tex2D(_TVTex,maskuv);
                    tvcontent.a = mask.a;
     
                    //return tvcontent;
                    //return tv;
     
                    half4 result = tv;
                    //是屏幕上的区域
                    if(mask.a==1)
                    {
                        //和屏幕内容颜色混合
                        result = tv + tvcontent;
                        result.rgb=result.rgb/2;
                    }
                    else
                    {
                        //是电视机外壳区域,什么也不做,保持原来的颜色
                    }
                    return result;
                }            
     
                ENDCG
            }
        }
     
        FallBack "Diffuse"
    }

    C#脚本代码:就是把视频内容传递给shader代码里面的uniform sampler2D _TVTex

    using UnityEngine;
    using System.Collections;
     
    public class playTv : MonoBehaviour
    {
        public MovieTexture movie;
     
        void Start () 
        {
            this.GetComponent<Renderer>().material.SetTexture("_TVTex",movie);
            movie.loop = true;
            movie.Play();
        }
    }

    不足:
    以为这样就完美了吗?
    不是,既然是旧电视,必然有那种,吱~吱~吱~ 的闪烁。
    屏幕绘制不完美的断裂,从左到右的一个uv移动。

    Try it yourself!
    我是个怀旧之人,小时候爷爷房间里就有这样的一台电视机。
    你完全可以搞一张IMAX的图片,然后在上面播放好莱坞大片。

  • 相关阅读:
    Codeforces Round #644 (Div. 3) A~G
    西安邮电大学第五届ACM-ICPC校赛(同步赛) B(拓扑排序)
    Codeforces Round #642 (Div. 3)A~D
    Codeforces Round #641 (Div. 2)A~D
    Codeforces Round #634 (Div. 3)A~E
    Educational Codeforces Round 85 (Rated for Div. 2)ABCD
    Codeforces Round #631 (Div. 2) ABD
    Codeforces Round #629 (Div. 3) E
    Educational Codeforces Round 84 (Rated for Div. 2) E
    yp训练赛3/21
  • 原文地址:https://www.cnblogs.com/joeshifu/p/5489647.html
Copyright © 2011-2022 走看看