unity-shader之截图(抓屏)功能、常用的cginc、multi_complie多条件、移动平台的基本优化

本文深入探讨Unity Shader的高级应用,包括抓屏通道、Pass复用、multi_compile多版本编译技巧,以及针对移动平台的优化策略。通过具体代码示例,详细解析如何在Unity中实现屏幕捕获、纹理采样、Pass通道共享和多版本Shader的条件编译,为开发者提供实用的Shader编程指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GrabPass

使用抓屏通道
GrabPass[]或者GrabPass{“纹理名称”};
如果不指定纹理名称,将会默认的将纹理生成到_GrabTexture中,后面的Pass通道使用这个变量来获得抓屏纹理
场景:
在这里插入图片描述
代码

Shader "Custom/Grab_Shader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue" = "OverLay"}//OverLay是保证这个通道是最后被绘制这个时候再去截屏就能将整个屏幕都截取
        LOD 100

		GrabPass{
	//如果在这里定义一个纹理的名称,那么在下面就要同样声明一下,截屏的纹理就储存到了这个变量里面
	}//截屏通道,如果在这里不指定名字就会默认使用_GrabTexture进行保存
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
			sampler2D _GrabTexture;//所以截屏的纹理保存到这里
			float4 _GrabTexture_ST;
			v2f vert (appdata v)
            {
                v2f o;
                o.vertex = mul(UNITY_MATRIX_MVP,v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _GrabTexture);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_GrabTexture, i.uv);
                return col;
            }
            ENDCG
        }
    }
}

使用shader后的场景
在这里插入图片描述
由于接受截屏的物体尺寸大小与场景截屏尺寸不一样所以场景中的物体会被拉伸,角度与摄像机的角度有关。

常用的cginc

Cginc文件:定义宏,帮助函数等,放在CGIncludes下面,开发人员可以开发自己的成功include文件
常用的cginc文件:
HLSL.Support.cginc协助多平台开发的一些宏等,系统自动包含
UnityShaderVarirables.cginc全局变量自动包含
UnityCG.cginc常用的帮助函数
AutoLight.cginc 光照和阴影功能
Lighting.cginc 表面着色器的关照模型
TerrainEngine.cginc 地形制备的光照着色函数

UnityCG.gcinc常用函数

在这里插入图片描述

通道复用

1.编写过的Pass可以重复使用,借助UsePass"ShaderPath/PASS_NAME"
2.PASS名字要大写
3.Pass{
name “ONE”
}
4.UsePass"Custom/ShaderName/One"

...
name "ONE"// 没有等号并且不能卸载CGPROGRAM里面
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
...

使用的时候通过上面4.语句使用

multi_compile 编译多版本的shader

shader代码

Shader "Custom/Mulit_shader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
			//定义一个两个条件编译的开关告诉又两个版本的shader
			#pragma multi_compile MY_multi_1 MY_multi_2
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
				float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				fixed4 col;
                // sample the texture
                //fixed4 col = tex2D(_MainTex, i.uv);
				#ifdef MY_multi_1
				col = fixed4(1.0,0.0,0.0,1.0);
				#endif
				#ifdef MY_multi_2
				col = fixed4(0.0,0.0,1.0,1.0);
				#endif
			return col;
            }
            ENDCG
        }
    }
}

c#控制代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Multi_Script : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()//在代码里面控制使用哪一个开关不适用那一个开关
    {
        Shader.EnableKeyword("MY_multi_1");//打开条件二
        Shader.DisableKeyword("MY_multi_2");//关闭条件1
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

移动平台的基本优化

移动平台的优化
一. 代码优化

  1. 预先计算好对应的值
  2. 放心的使用限量相关操作,基本都是硬件实现很高效
  3. 尽量较少函数调用减少开销
    二.尽可能的将计算放在顶点着色器中顶点着色器的调用频率远低于片元着色器
    三.集合复杂度考量,在ios平台视口内的顶点数不要超过100k个ios默认的缓冲区就那个大,超过这个数字,底层会做一些操作消耗更多的资源
    四.纹理大小为2^n次方大小
    五.使用适当的数据类型 float<half<fixed fixed是最高效的
    六.尽量慎用同名效果,透明效果GPU要逐像素渲染,耗费资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值