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的图片,然后在上面播放好莱坞大片。

  • 相关阅读:
    重构之美之一改造面向过程式设计(转)
    arcgis_server for java的问题
    Using Javascript to display RSS
    JavaScript开发规范要求(转载)
    恭贺今天开张大吉!
    今天为打乙肝疫苗抽血。
    人类登上月球
    c++读写文件流
    检索Repeater中的checkbox
    Z:如何轻松做好网站外链的十大技巧
  • 原文地址:https://www.cnblogs.com/joeshifu/p/5489647.html
Copyright © 2011-2022 走看看