• Unity中Shader的屏幕抓取 GrabPass



    前言

    Unity中Shader的屏幕抓取 GrabPass


    一、抓取

    1、抓取指令

    屏幕的抓取需要使用一个Pass

    GrabPass{}

    GrabPass{“NAME”}

    2、在使用抓取的屏幕前,需要像使用属性一样定义一下,_GrabTexture这个名字是Unity定义好的

    sampler2D _GrabTexture;

    测试代码:

    Shader "MyShader/P0_10_3"
    {
        SubShader
        {
            Tags{"Queue" = "Transparent"}
            //屏幕抓取需要单独使用一个Pass —— GrabPass{} 里面什么都不写
            GrabPass{}
            
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                
                struct v2f
                {
                    float2 uv : TEXCOORD0;
                };
    
                //在使用抓取的屏幕前,需要像使用属性一样定义一下,_GrabTexture这个名字是Unity定义好的
                sampler2D _GrabTexture;
                //在顶点着色器的输入处,不用appdata,直接使用用到的参数,防止 SV_POSITION 重复定义
                v2f vert (
                    float4 vertex : POSITION,
                    out float4 pos : SV_POSITION
                )
                {
                    v2f o;
                    pos = UnityObjectToClipPos(vertex);
                    return o;
                }
    
                fixed4 frag (v2f i,UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target
                {
                    
                    fixed2 screenUV = screenPos.xy / _ScreenParams.xy;
                    //对抓取的屏幕进行采样
                    fixed4 grabTex = tex2D(_GrabTexture,screenUV);
                    return grabTex;
                }
                ENDCG
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    效果:
    在这里插入图片描述

    为了优化节省性能:一次抓取就存储下来渲染完,再进行下次抓取

    使用:GrabPass{“NAME”}

    使用这个抓取后,对应的定义名也要换成 NAME

    修改后代码:

    Shader "MyShader/P0_10_3"
    {
        SubShader
        {
            Tags{"Queue" = "Transparent"}
            //屏幕抓取需要单独使用一个Pass —— GrabPass{} 里面什么都不写,或者GrabPass{"_GrabTex"}
            GrabPass{"_GrabTex"}
            
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                
                struct v2f
                {
                    float2 uv : TEXCOORD0;
                };
    
                //在使用抓取的屏幕前,需要像使用属性一样定义一下,_GrabTexture这个名字是Unity定义好的
                sampler2D _GrabTex;
                //在顶点着色器的输入处,不用appdata,直接使用用到的参数,防止 SV_POSITION 重复定义
                v2f vert (
                    float4 vertex : POSITION,
                    out float4 pos : SV_POSITION
                )
                {
                    v2f o;
                    pos = UnityObjectToClipPos(vertex);
                    return o;
                }
    
                fixed4 frag (v2f i,UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target
                {
                    
                    fixed2 screenUV = screenPos.xy / _ScreenParams.xy;
                    //对抓取的屏幕进行采样
                    fixed4 grabTex = tex2D(_GrabTex,screenUV);
                    return grabTex;
                }
                ENDCG
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    注意:该操作对手机性能比较消耗,一般在中配或高配时才开启

  • 相关阅读:
    【webrtc】PhysicalSocket::Bind返回-1 ,10013错误
    Web3时代:探索DAO的未来之路
    成集云 | 多维表自动查询快递100信息 | 解决方案
    Android 11.0 禁止二次展开QuickQSPanel设置下拉QSPanel高度
    Mongodb语法使用说明(含详细示例)
    富文本编辑器的实现与回显
    【C语言】栈的实现
    【访谈】Eotalk Vol.02:从极客到 CEO,开发者应该如何提升技术领导力?
    Windows和Linux环境中安装Zookeeper具体操作
    抽象类和接口
  • 原文地址:https://blog.csdn.net/qq_51603875/article/details/132765217