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

2024-01-13 06:04

本文主要是介绍Unity中URP下实现能量罩(性能优化 和 BRP适配),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、性能优化
    • 1、尽可能减少纹理采样次数
    • 2、 尽量把 max函数 换成 saturate函数,可以减少一次GPU指令
    • 3、尽可能的把计算移到顶点着色器
    • 4、变体优化
    • 5、变量放入 常量缓冲区
  • 二、BuideIn Render Pipeline适配
    • 1、C#脚本开启摄像机深度图
    • 2、CG语言适配
  • 三、最终效果和代码


前言

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

  • Unity中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 OneZWrite OffName "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_ENDTEXTURE2D(_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 OneZWrite OffCGPROGRAM#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}}
}

这篇关于Unity中URP下实现能量罩(性能优化 和 BRP适配)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/600466

相关文章

Java根据IP地址实现归属地获取

《Java根据IP地址实现归属地获取》Ip2region是一个离线IP地址定位库和IP定位数据管理框架,这篇文章主要为大家详细介绍了Java如何使用Ip2region实现根据IP地址获取归属地,感兴趣... 目录一、使用Ip2region离线获取1、Ip2region简介2、导包3、下编程载xdb文件4、J

PyQt5+Python-docx实现一键生成测试报告

《PyQt5+Python-docx实现一键生成测试报告》作为一名测试工程师,你是否经历过手动填写测试报告的痛苦,本文将用Python的PyQt5和python-docx库,打造一款测试报告一键生成工... 目录引言工具功能亮点工具设计思路1. 界面设计:PyQt5实现数据输入2. 文档生成:python-

Android实现一键录屏功能(附源码)

《Android实现一键录屏功能(附源码)》在Android5.0及以上版本,系统提供了MediaProjectionAPI,允许应用在用户授权下录制屏幕内容并输出到视频文件,所以本文将基于此实现一个... 目录一、项目介绍二、相关技术与原理三、系统权限与用户授权四、项目架构与流程五、环境配置与依赖六、完整

浅析如何使用xstream实现javaBean与xml互转

《浅析如何使用xstream实现javaBean与xml互转》XStream是一个用于将Java对象与XML之间进行转换的库,它非常简单易用,下面将详细介绍如何使用XStream实现JavaBean与... 目录1. 引入依赖2. 定义 JavaBean3. JavaBean 转 XML4. XML 转 J

Flutter实现文字镂空效果的详细步骤

《Flutter实现文字镂空效果的详细步骤》:本文主要介绍如何使用Flutter实现文字镂空效果,包括创建基础应用结构、实现自定义绘制器、构建UI界面以及实现颜色选择按钮等步骤,并详细解析了混合模... 目录引言实现原理开始实现步骤1:创建基础应用结构步骤2:创建主屏幕步骤3:实现自定义绘制器步骤4:构建U

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句