Unity中URP下实现能量罩(性能优化 和 BRP适配)

文章目录


前言

在之前的文章中,我们实现了URP下的能量罩效果。

我们在这篇文章中,对其进行性能优化 和 BRP下的适配。


一、性能优化

1、尽可能减少纹理采样次数

  • 我们这里把 能量罩花纹纹理 和 抓屏扭曲纹理 合并成同一个来使用,在效果上没多大变化。但是,可以少使用一次纹理采样。

2、 尽量把 max函数 换成 saturate函数,可以减少一次GPU指令

3、尽可能的把计算移到顶点着色器

  • 在片元着色器中计算,需要对片元中的每一个像素进行计算,消耗性能较大

4、变体优化

5、变量放入 常量缓冲区


二、BuideIn Render Pipeline适配

1、C#脚本开启摄像机深度图

Camera.main.depthTextureMode = DepthTextureMode.Depth;

2、CG语言适配

  • 抓屏纹理

GrabPass{"_GrabPass"}

  • 引入库修改

#include "UnityCG.cginc"

  • 纹理申明

sampler2D _MainTex;

float4 _MainTex_ST;

sampler2D _CameraDepthTexture;

sampler2D _GrabPass;

  • 顶点着色器中,顶点坐标系变换需要修改为BRP的方法

v2f vert(appdata v)

{

v2f o = (v2f)0;

o.positionWS = mul(unity_ObjectToWorld,v.positionOS);

o.positionVS = UnityObjectToViewPos(v.positionOS);

o.positionCS = UnityObjectToClipPos(v.positionOS);

o.normalWS = UnityObjectToWorldNormal(v.normalOS);

o.uv.xy = v.uv;

o.uv.zw = TRANSFORM_TEX(v.uv,_MainTex);

return o;

}

  • 纹理采样使用 tex2D

三、最终效果和代码

复制代码
//流光扭曲花纹
Shader "MyShader/URP/P4_3_7"
{
    Properties
    {
        [Header(MainTex)]
        _MainTex("MainTex",2D) = "white"{}
        [Header(HighLight)]
        _HighLightColor("HighLightColor",Color) = (0,0,0,0)
        _HighLightFade("HighLightFade",Float) = 1.0
        [Header(Fresnel)]
        [PowerSlider(3)]_FresnelIntensity("FresnelIntensity",Range(0,15)) = 1.0
        _FresnelColor("FresnelColor",Color) = (0,0,0,0)
        [Header(Distort)]
        _Tilling("Distort Tilling",Float)=0
        _Distort("Distort",Range(0,1)) = 0.3
    }
    SubShader
    {
        Tags
        {
            //告诉引擎,该Shader只用于 URP 渲染管线
            "RenderPipeline"="UniversalPipeline"
            //渲染类型
            "RenderType"="Transparent"
            //渲染队列
            "Queue"="Transparent"
        }

        Pass
        {
            Blend One One
            ZWrite Off
            Name "Unlit"

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // Pragmas
            #pragma target 2.0

            // Includes
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"

            CBUFFER_START(UnityPerMaterial)
                half4 _HighLightColor;
                half _HighLightFade;
                half _FresnelIntensity;
                half4 _FresnelColor;
                half _Tilling;
                half _Distort;
                float4 _MainTex_ST;
            CBUFFER_END

            TEXTURE2D(_MainTex);
            SAMPLER(sampler_MainTex);
            TEXTURE2D(_CameraDepthTexture);
            SAMPLER(sampler_CameraDepthTexture);
            TEXTURE2D(_CameraOpaqueTexture);
            SAMPLER(sampler_CameraOpaqueTexture);
            //struct appdata
            //顶点着色器的输入
            struct Attributes
            {
                float3 positionOS : POSITION;
                float2 uv : TEXCOORD0;
                half3 normalOS : NORMAL;
            };

            //struct v2f
            //片元着色器的输入
            struct Varyings
            {
                float4 positionCS : SV_POSITION;
                float4 uv : TEXCOORD0;
                float4 screenPos : TEXCOORD1;
                float3 positionWS : TEXCOORD2;
                float3 positionVS : TEXCOORD3;
                half3 normalWS : TEXCOORD4;
            };

            //v2f vert(Attributes v)
            //顶点着色器
            Varyings vert(Attributes v)
            {
                Varyings o = (Varyings)0;
                o.positionWS = TransformObjectToWorld(v.positionOS);
                o.positionVS = TransformWorldToView(o.positionWS);
                o.positionCS = TransformWViewToHClip(o.positionVS);
                o.screenPos = ComputeScreenPos(o.positionCS);
                o.normalWS = TransformObjectToWorldNormal(v.normalOS);
                o.uv.xy = v.uv;
                o.uv.zw = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            //fixed4 frag(v2f i) : SV_TARGET
            //片元着色器
            half4 frag(Varyings i) : SV_TARGET
            {
                half4 col = 0;
                //深度图
                //float2 uv = i.screenPos.xy / i.screenPos.w;
                float2 uv = i.positionCS.xy / _ScreenParams.xy;
                half4 cameraDepthTex = SAMPLE_TEXTURE2D(_CameraDepthTexture, sampler_CameraDepthTexture, uv);
                half depthTex = LinearEyeDepth(cameraDepthTex.r, _ZBufferParams);
                half4 highLight = depthTex + i.positionVS.z;
                highLight = pow(saturate(highLight), _HighLightFade);
                highLight = 1 - highLight;
                highLight *= _HighLightColor;
                col += saturate(highLight);

                //fresnel外发光
                //pow(max(0,dot(N,V)),Intensity)
                half3 N = i.normalWS;
                half3 V = normalize(_WorldSpaceCameraPos - i.positionWS);
                half NdotV = dot(N, V);
                half4 fresnel = pow(abs(1 - saturate(NdotV)), _FresnelIntensity);
                fresnel *= _FresnelColor;
                col += fresnel;
                //能量罩花纹
                float4 mainTex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv.zw + float2(0,_Time.x));
                col += mainTex * 0.1;

                //流光
                half flowMask = frac(i.uv.y * _Tilling + _Time.y);
                col *= flowMask;

                //抓屏流光扭曲
                float2 distortUV = lerp(uv, mainTex.rr, _Distort);
                half4 opaqueTex = SAMPLE_TEXTURE2D(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, distortUV);

                half4 distort = opaqueTex;

                col *= distort;
                return col;
            }
            ENDHLSL
        }
    }

    SubShader
    {
        Tags
        {
            //渲染类型
            "RenderType"="Transparent"
            //渲染队列
            "Queue"="Transparent"
        }

        GrabPass
        {
            "_GrabPass"
        }

        Pass
        {
            Blend One One
            ZWrite Off


            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // Pragmas
            #pragma target 2.0

            // Includes
            #include "UnityCG.cginc"

            half4 _HighLightColor;
            half _HighLightFade;
            half _FresnelIntensity;
            half4 _FresnelColor;
            half _Tilling;
            half _Distort;

            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _CameraDepthTexture;
            sampler2D _GrabPass;


            struct appdata
            {
                float3 positionOS : POSITION;
                float2 uv : TEXCOORD0;
                half3 normalOS : NORMAL;
            };

            //struct v2f
            //片元着色器的输入
            struct v2f
            {
                float4 positionCS : SV_POSITION;
                float4 uv : TEXCOORD0;
                float3 positionWS : TEXCOORD2;
                float3 positionVS : TEXCOORD3;
                half3 normalWS : TEXCOORD4;
            };

            //v2f vert(appdata v)
            //顶点着色器
            v2f vert(appdata v)
            {
                v2f o = (v2f)0;
                o.positionWS = mul(unity_ObjectToWorld, v.positionOS);
                o.positionVS = UnityObjectToViewPos(v.positionOS);
                o.positionCS = UnityObjectToClipPos(v.positionOS);
                o.normalWS = UnityObjectToWorldNormal(v.normalOS);
                o.uv.xy = v.uv;
                o.uv.zw = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            //fixed4 frag(v2f i) : SV_TARGET
            //片元着色器
            half4 frag(v2f i) : SV_TARGET
            {
                half4 col = 0;
                //深度图
                //float2 uv = i.screenPos.xy / i.screenPos.w;
                float2 uv = i.positionCS.xy / _ScreenParams.xy;
                half4 cameraDepthTex = tex2D(_CameraDepthTexture, uv);
                half depthTex = LinearEyeDepth(cameraDepthTex);
                half4 highLight = depthTex + i.positionVS.z;
                highLight = pow(saturate(highLight), _HighLightFade);
                highLight = 1 - highLight;
                highLight *= _HighLightColor;
                col += saturate(highLight);

                //fresnel外发光
                //pow(max(0,dot(N,V)),Intensity)
                half3 N = i.normalWS;
                half3 V = normalize(_WorldSpaceCameraPos - i.positionWS);
                half NdotV = dot(N, V);
                half4 fresnel = pow(abs(1 - saturate(NdotV)), _FresnelIntensity);
                fresnel *= _FresnelColor;
                col += fresnel;
                //能量罩花纹
                float4 mainTex = tex2D(_MainTex, i.uv.zw + float2(0, _Time.x));
                col += mainTex * 0.1;

                //流光
                half flowMask = frac(i.uv.y * _Tilling + _Time.y);
                col *= flowMask;

                //抓屏流光扭曲
                float2 distortUV = lerp(uv, mainTex.rr, _Distort);
                half4 opaqueTex = tex2D(_GrabPass, distortUV);

                half4 distort = opaqueTex;

                col *= distort;
                return col;
            }
            ENDCG
        }
    }
}
相关推荐
90后小陈老师8 小时前
Unity教学 项目2 2D闯关游戏
游戏·unity·游戏引擎
Curvatureflight9 小时前
前端性能优化实战:从3秒到300ms的加载速度提升
前端·人工智能·性能优化
噗噗夹的TA之旅9 小时前
Unity Shader 学习20:URP LitForwardPass PBR 解析
学习·unity·游戏引擎·图形渲染·技术美术
nnsix9 小时前
Unity ReferenceFinder插件 多选资源查找bug解决
unity·游戏引擎·bug
gzroy10 小时前
Unity Shader Graph实现全息瞄准器
unity·游戏引擎
你别追我跑不动13 小时前
基于代码扫描的 Icon 优化实践
前端·性能优化
90后小陈老师13 小时前
Unity教学 基础介绍
unity·游戏引擎
90后小陈老师14 小时前
Unity教学 项目3 3D坦克大战
3d·unity·游戏引擎
2501_9240641114 小时前
优测工具如何测试接口最大并发量及实践方法
性能优化·接口测试·最大并发量·优测工具·压测方案
国科安芯15 小时前
如何利用AS32系列MCU芯片使用简洁单线模式操作QSPI FLASH?
单片机·嵌入式硬件·性能优化·安全性测试