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

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo