【实现100个unity特效之16】unity2022之前或者之后版本实现全屏shader graph的不同方式 —— 适用于人物受伤红屏或者一些其他状态效果

news2024/11/25 1:25:05

最终效果

在这里插入图片描述

文章目录

  • 最终效果
  • 前言
  • unity2022版本 Fullscreen shader graph
    • 首先,请注意你的Inity版本,是不是2022.2以上,并且项目是URP项且
    • 基本配置
  • 修改shader graph
    • 边缘效果
    • 动起来
    • 优化
    • 科幻风
    • 制作一些变量
    • 最终效果
    • 最终节点图
    • 代码控制
  • 2022之前版本
    • 下载 Blit Render Feature 脚本
  • 不使用shader graph
  • 参考
  • 完结

前言

今天和大家一起来学习一下unity2022版本新出的全屏shader graph,如果在2022之前想要实现全屏shader,可能还需要自己写脚本,但是在2022.2的版本之后,unity将它纳入了进来。

unity2022版本 Fullscreen shader graph

首先,请注意你的Inity版本,是不是2022.2以上,并且项目是URP项且

基本配置

紧接着我们创建一个Fullscreen shader graph
在这里插入图片描述
下面我们就要使用它了,修改URP配置,添加Full Screen Pass Renderer Feature
在这里插入图片描述
将我们shader相关的全屏材质给到Pass Material
在这里插入图片描述
这时你会发现Game视图变成了灰色
在这里插入图片描述

修改shader graph

创建极坐标节点,分离他的输出,输出的R就是中间黑四周白的渐变,然后将它通过乘幂函数进行调整,让黑色区域更大
在这里插入图片描述
我们需要将shader的Blend Mode设置为Alpha,不然看不到效果
在这里插入图片描述
效果
在这里插入图片描述

边缘效果

现在我们来创建一个泰森多边形,也叫沃洛诺伊图,将它和我们的透明度遮罩相乘,得到一个新的遮罩,然后再连接给最终的透明度通道
在这里插入图片描述

效果
在这里插入图片描述

动起来

然后我们让他动起来,这无疑用到了移动套装,时间节点乘以一个速度,然后进行偏移,之后连接给Angle offset,这样泰森多边形就动起来了
在这里插入图片描述
效果
在这里插入图片描述

优化

我们将最终的输出用Clamp节点限制一下范围0到1,避免不必要的显示错误
在这里插入图片描述

黑白过渡这里太明显了,我们先乘以一个较小的值处理
这里我乘以0.8然后Power指数改为5,感觉这样还不错
在这里插入图片描述
效果
在这里插入图片描述

科幻风

有趣的是,如果我们将泰森多边形的Cells作为输出,那么我们就会得到一个科幻风的效果
在这里插入图片描述
效果
在这里插入图片描述

制作一些变量

你可以根据自己的喜好调整这些参数,但为了更加方便的进行控制,下面我们将制作一些变量,跟着我做

颜色
在这里插入图片描述
接下来是指数部分,他影响遮罩的范围,所以定义一个float类型的变量,就叫range,默认值5
乘幂之前的这个相乘的数值,控制透明的力度,就叫他strength
在这里插入图片描述
泰森多边形的大小也做一个变量,就叫他Size
在这里插入图片描述
移动速度做一个变量,叫Speed
在这里插入图片描述
接下来是泰森多边形的输出,我们需要一个Branch分支节点来控制不同的输出,这样,控制Predicate是否为True,就可以控制输出了。我们也个他做成一个布尔类型的变量,就叫Cells
在这里插入图片描述

最终效果

在这里插入图片描述

最终节点图

在这里插入图片描述

代码控制

在这里插入图片描述
挂载
在这里插入图片描述

2022之前版本

正如前面所说,2022之前版本需要自己写脚本,好在github上已经有大佬帮我们写好了,我们不用关心怎么做的,只要会用就行。

下载 Blit Render Feature 脚本

github地址:https://github.com/Cyanilux/URP_BlitRenderFeature

复制Blit.cs脚本到我们本地
在这里插入图片描述
打不开或者嫌麻烦的,复制我下面的代码就行了,我已经复制过来了

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

/*
 * Blit Renderer Feature                                                https://github.com/Cyanilux/URP_BlitRenderFeature
 * ------------------------------------------------------------------------------------------------------------------------
 * Based on the Blit from the UniversalRenderingExamples
 * https://github.com/Unity-Technologies/UniversalRenderingExamples/tree/master/Assets/Scripts/Runtime/RenderPasses
 * 
 * Extended to allow for :
 * - Specific access to selecting a source and destination (via current camera's color / texture id / render texture object
 * - (Pre-2021.2/v12) Automatic switching to using _AfterPostProcessTexture for After Rendering event, in order to correctly handle the blit after post processing is applied
 * - Setting a _InverseView matrix (cameraToWorldMatrix), for shaders that might need it to handle calculations from screen space to world.
 * 		e.g. Reconstruct world pos from depth : https://www.cyanilux.com/tutorials/depth/#blit-perspective 
 * - (2020.2/v10 +) Enabling generation of DepthNormals (_CameraNormalsTexture)
 * 		This will only include shaders who have a DepthNormals pass (mostly Lit Shaders / Graphs)
 		(workaround for Unlit Shaders / Graphs: https://gist.github.com/Cyanilux/be5a796cf6ddb20f20a586b94be93f2b)
 * ------------------------------------------------------------------------------------------------------------------------
 * @Cyanilux
*/

namespace Cyan {
/*
CreateAssetMenu here allows creating the ScriptableObject without being attached to a Renderer Asset
Can then Enqueue the pass manually via https://gist.github.com/Cyanilux/8fb3353529887e4184159841b8cad208
as a workaround for 2D Renderer not supporting features (prior to 2021.2). Uncomment if needed.
*/
//	[CreateAssetMenu(menuName = "Cyan/Blit")] 
	public class Blit : ScriptableRendererFeature {

		public class BlitPass : ScriptableRenderPass {

			public Material blitMaterial = null;
			public FilterMode filterMode { get; set; }

			private BlitSettings settings;

			private RenderTargetIdentifier source { get; set; }
			private RenderTargetIdentifier destination { get; set; }

			RenderTargetHandle m_TemporaryColorTexture;
			RenderTargetHandle m_DestinationTexture;
			string m_ProfilerTag;

#if !UNITY_2020_2_OR_NEWER // v8
			private ScriptableRenderer renderer;
#endif

			public BlitPass(RenderPassEvent renderPassEvent, BlitSettings settings, string tag) {
				this.renderPassEvent = renderPassEvent;
				this.settings = settings;
				blitMaterial = settings.blitMaterial;
				m_ProfilerTag = tag;
				m_TemporaryColorTexture.Init("_TemporaryColorTexture");
				if (settings.dstType == Target.TextureID) {
					m_DestinationTexture.Init(settings.dstTextureId);
				}
			}

			public void Setup(ScriptableRenderer renderer) {
#if UNITY_2020_2_OR_NEWER // v10+
				if (settings.requireDepthNormals)
					ConfigureInput(ScriptableRenderPassInput.Normal);
#else // v8
				this.renderer = renderer;
#endif
			}

			public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) {
				CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag);
				RenderTextureDescriptor opaqueDesc = renderingData.cameraData.cameraTargetDescriptor;
				opaqueDesc.depthBufferBits = 0;

				// Set Source / Destination
#if UNITY_2020_2_OR_NEWER // v10+
				var renderer = renderingData.cameraData.renderer;
#else // v8
				// For older versions, cameraData.renderer is internal so can't be accessed. Will pass it through from AddRenderPasses instead
				var renderer = this.renderer;
#endif

				// note : Seems this has to be done in here rather than in AddRenderPasses to work correctly in 2021.2+
				if (settings.srcType == Target.CameraColor) {
					source = renderer.cameraColorTarget;
				} else if (settings.srcType == Target.TextureID) {
					source = new RenderTargetIdentifier(settings.srcTextureId);
				} else if (settings.srcType == Target.RenderTextureObject) {
					source = new RenderTargetIdentifier(settings.srcTextureObject);
				}

				if (settings.dstType == Target.CameraColor) {
					destination = renderer.cameraColorTarget;
				} else if (settings.dstType == Target.TextureID) {
					destination = new RenderTargetIdentifier(settings.dstTextureId);
				} else if (settings.dstType == Target.RenderTextureObject) {
					destination = new RenderTargetIdentifier(settings.dstTextureObject);
				}

				if (settings.setInverseViewMatrix) {
					Shader.SetGlobalMatrix("_InverseView", renderingData.cameraData.camera.cameraToWorldMatrix);
				}

				if (settings.dstType == Target.TextureID) {
					if (settings.overrideGraphicsFormat) {
						opaqueDesc.graphicsFormat = settings.graphicsFormat;
					}
					cmd.GetTemporaryRT(m_DestinationTexture.id, opaqueDesc, filterMode);
				}

				//Debug.Log($"src = {source},     dst = {destination} ");
				// Can't read and write to same color target, use a TemporaryRT
				if (source == destination || (settings.srcType == settings.dstType && settings.srcType == Target.CameraColor)) {
					cmd.GetTemporaryRT(m_TemporaryColorTexture.id, opaqueDesc, filterMode);
					Blit(cmd, source, m_TemporaryColorTexture.Identifier(), blitMaterial, settings.blitMaterialPassIndex);
					Blit(cmd, m_TemporaryColorTexture.Identifier(), destination);
				} else {
					Blit(cmd, source, destination, blitMaterial, settings.blitMaterialPassIndex);
				}

				context.ExecuteCommandBuffer(cmd);
				CommandBufferPool.Release(cmd);
			}

			public override void FrameCleanup(CommandBuffer cmd) {
				if (settings.dstType == Target.TextureID) {
					cmd.ReleaseTemporaryRT(m_DestinationTexture.id);
				}
				if (source == destination || (settings.srcType == settings.dstType && settings.srcType == Target.CameraColor)) {
					cmd.ReleaseTemporaryRT(m_TemporaryColorTexture.id);
				}
			}
		}

		[System.Serializable]
		public class BlitSettings {
			public RenderPassEvent Event = RenderPassEvent.AfterRenderingOpaques;

			public Material blitMaterial = null;
			public int blitMaterialPassIndex = 0;
			public bool setInverseViewMatrix = false;
			public bool requireDepthNormals = false;

			public Target srcType = Target.CameraColor;
			public string srcTextureId = "_CameraColorTexture";
			public RenderTexture srcTextureObject;

			public Target dstType = Target.CameraColor;
			public string dstTextureId = "_BlitPassTexture";
			public RenderTexture dstTextureObject;

			public bool overrideGraphicsFormat = false;
			public UnityEngine.Experimental.Rendering.GraphicsFormat graphicsFormat;

			public bool canShowInSceneView = true;
		}

		public enum Target {
			CameraColor,
			TextureID,
			RenderTextureObject
		}

		public BlitSettings settings = new BlitSettings();
		public BlitPass blitPass;

		public override void Create() {
			var passIndex = settings.blitMaterial != null ? settings.blitMaterial.passCount - 1 : 1;
			settings.blitMaterialPassIndex = Mathf.Clamp(settings.blitMaterialPassIndex, -1, passIndex);
			blitPass = new BlitPass(settings.Event, settings, name);

#if !UNITY_2021_2_OR_NEWER
		if (settings.Event == RenderPassEvent.AfterRenderingPostProcessing) {
			Debug.LogWarning("Note that the \"After Rendering Post Processing\"'s Color target doesn't seem to work? (or might work, but doesn't contain the post processing) :( -- Use \"After Rendering\" instead!");
		}
#endif

			if (settings.graphicsFormat == UnityEngine.Experimental.Rendering.GraphicsFormat.None) {
				settings.graphicsFormat = SystemInfo.GetGraphicsFormat(UnityEngine.Experimental.Rendering.DefaultFormat.LDR);
			}
		}

		public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) {
			if (renderingData.cameraData.isPreviewCamera) return;
			if (!settings.canShowInSceneView && renderingData.cameraData.isSceneViewCamera) return;

			if (settings.blitMaterial == null) {
				Debug.LogWarningFormat("Missing Blit Material. {0} blit pass will not execute. Check for missing reference in the assigned renderer.", GetType().Name);
				return;
			}

#if !UNITY_2021_2_OR_NEWER
		// AfterRenderingPostProcessing event is fixed in 2021.2+ so this workaround is no longer required

		if (settings.Event == RenderPassEvent.AfterRenderingPostProcessing) {
		} else if (settings.Event == RenderPassEvent.AfterRendering && renderingData.postProcessingEnabled) {
			// If event is AfterRendering, and src/dst is using CameraColor, switch to _AfterPostProcessTexture instead.
			if (settings.srcType == Target.CameraColor) {
				settings.srcType = Target.TextureID;
				settings.srcTextureId = "_AfterPostProcessTexture";
			}
			if (settings.dstType == Target.CameraColor) {
				settings.dstType = Target.TextureID;
				settings.dstTextureId = "_AfterPostProcessTexture";
			}
		} else {
			// If src/dst is using _AfterPostProcessTexture, switch back to CameraColor
			if (settings.srcType == Target.TextureID && settings.srcTextureId == "_AfterPostProcessTexture") {
				settings.srcType = Target.CameraColor;
				settings.srcTextureId = "";
			}
			if (settings.dstType == Target.TextureID && settings.dstTextureId == "_AfterPostProcessTexture") {
				settings.dstType = Target.CameraColor;
				settings.dstTextureId = "";
			}
		}
#endif

			blitPass.Setup(renderer);
			renderer.EnqueuePass(blitPass);
		}
	}
}

新增或空白阴影图Blank Shader Graph或者lit Shader Graph其实都可以
在这里插入图片描述
其实这一步跟前面类似,不过这里只是添加我们自己定义了URP配置脚本
在这里插入图片描述
配置材质
在这里插入图片描述
如果我们想要全屏效果,不希望它受处理效果的影响,您可以选择After Rendering Transparents(在渲染后处理效果后) ,但我们这里选择After Rendering Opaques (渲染不透明后),因为我希望它受到后处理效果影响
在这里插入图片描述

修改配置shader graph
在这里插入图片描述
连线参考和前面一样即可

不使用shader graph

当然如果你不想使用shader graph实现全屏效果也是可以的,可以参考我之前的文章:
【unity小技巧】受伤屏幕闪红、死亡动画、死亡黑屏效果

参考

https://www.bilibili.com/video/BV1gX4y1q72t/
https://www.youtube.com/watch?v=mCpRxFP2J1c
https://www.youtube.com/watch?v=hqz4TnvC3fQ

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1995267.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙(API 12 Beta3版)【音频解码】

开发者可以调用本模块的Native API接口,完成音频解码,即将媒体数据解码为PCM码流。 当前支持的解码能力如下: 容器规格音频解码类型mp4AAC、MPEG(MP3)、Flac、Vorbis、AudioViVid11m4aAACflacFlacoggVorbis、opusaacAACmp3MPEG(MP3)amrAMR(amrnb、amrw…

Journyx soap_cgi.pyc接口XML外部实体注入漏洞复现 [附POC]

文章目录 Journyx soap_cgi.pyc接口XML外部实体注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现Journyx soap_cgi.pyc接口XML外部实体注入漏洞复现 [附POC] 0x01 前言 免责声明:请勿利用文章内的相关技术…

线程池原理(一)线程池核心概述

更好的阅读体验 \huge{\color{red}{更好的阅读体验}} 更好的阅读体验 线程回顾 创建线程的方式 继承 Thread 类实现 Runnable 接口 创建后的线程有如下状态: NEW:新建的线程,无任何操作 public static void main(String[] args) {Thread…

嵌入式初学-C语言-十八

#接嵌入式初学-C语言-十七# 变量的生命周期 1. 概念:变量在程序运行中存在的时间 2. 根据变量存在的时间不同,变量可分为静态存储和动态存储 3. 变量的存储类型 变量的完整定义格式:[存储类型] 数据类型 变量列表; 4. 存储类型 auto&…

yolov8人脸识别案例

GitHub - wangWEI201901/YOLOv8-Detection-Project: 🛣️基于YOLOv8的智慧校园人脸识别和公路汽车检测

ITSM垂类下,企业如何逐步搭建一个好的AI Agent

随着企业数字化转型的不断深入,智能服务管理(ITSM)逐渐成为提升企业运营效率和服务质量的关键。企业纷纷探索如何将AI技术融入到IT服务管理中,以提升效率、降低成本并增强用户体验。成功实施AI并非易事,它要求企业在战…

探索全光网技术 | 全光网络技术方案选型建议五 (大厅场景)

目录 一、场景设计需求二、大厅场景拓扑三、部署方式四、产品相关规格说明五、方案优势与特点 注:本文章参考资料为:华三官方资料 - “新华三全光网络3.0解决方案(教育)”与 锐捷官方资料 - “【锐捷】高校极简以太全光3.X方案设计…

web基础与http协议与配置

目录 一、web基础 1.1 DNS与域名(详解看前面章节) 1.2 网页的概念(HTTP/HTTPS) 1.2.1 基本概念 1.2.2 HTML文档结构(了解) 1.2.3 web相关重点 1.2.4 静态资源和动态资源 二、http协议 2.1 概述 2.2 cookie和session&…

【HarmonyOS NEXT星河版开发学习】小型测试案例10-计数器案例

个人主页→VON 收录专栏→鸿蒙开发小型案例总结​​​​​ 基础语法部分会发布于github 和 gitee上面(暂未发布) 前言 鸿蒙开发中的点击事件是一个基础且重要的功能,它使得应用能够响应用户的各种触摸操作。通过对点击事件及其相关参数的深入…

扎克伯格说AI会让推荐系统变得更强大?一文读懂什么是智能推荐系统

导语:我认为很少有人意识到,推荐系统是世界上构想过的最大的计算系统之一。——Jensen Huang 前言 扎克伯格在 2024 年 7 月说,我们在组建 Reality Labs 之前就成立了 FAIR——人工智能研究中心,主要产品线有 Facebook 和 Insta…

006集—— 修饰符(public、private 、internal等)——C#学习笔记

封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中"。在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。 抽象和封装是面向对象程序设计的相关特性。抽象允许相关信息可视化,封装则使开发者实现所需级别的抽象。 C…

Python面试宝典第30题:找出第K大元素

题目 给定一个整数数组nums&#xff0c;请找出数组中第K大的数&#xff0c;保证答案存在。其中&#xff0c;1 < K < nums数组长度。 示例 1&#xff1a; 输入&#xff1a;nums [3, 2, 1, 5, 6, 4], K 2 输出&#xff1a;5 示例 2&#xff1a; 输入&#xff1a;nums …

python如何判断文件有多少行

如何统计读取的一个txt文本的行数呢&#xff1f; 最简单的办法是把文件读入一个大的列表中&#xff0c;然后统计列表的长度。如果文件的路径是以参数的形式filepath传递的&#xff0c;那么只用一行代码就可以完成我们的需求了&#xff1a; count len(open(filepath,rU).readl…

数字样机:惯性导航系统控制单元仿真

01.简介 惯性导航系统 (INS&#xff0c;Inertial Navigation System) 基于惯性原理建立&#xff0c;而惯性是物体自身的固有属性&#xff0c;因此其工作时既不依赖于外部信息&#xff0c;也不向外部辐射能量&#xff0c;优于卫星导航与无线电导航&#xff0c;是一种具备隐蔽性…

KEYSIGHT E5063A-006 无线功率传输分析

KEYSIGHT是德 E5063A-006 无线功率传输分析 E5063A-006 无线功率传输分析选件能够以任意负载阻抗设置&#xff0c;实时测量线圈或谐振器之间的无线功率传输效率&#xff08;WPT&#xff09;。基于测量结果进行的 2D/3D 分析&#xff0c;能够帮助用户更轻松地了解对负载阻抗的…

Selenium + Python 自动化测试07(滑块的操作方法)

我们的目标是&#xff1a;按照这一套资料学习下来&#xff0c;大家可以独立完成自动化测试的任务。 本篇文章主要讲述如何操作滑块。 目前很多系统登录或者注册的页面都有滑块相关的验证&#xff0c;selenium 中对滑块的基本操作采用了元素的拖曳的方式。需要用到Actiochains模…

市场惊人逆转:西格尔改口称降息紧迫性已减

最近&#xff0c;市场发生了惊人的逆转&#xff0c;让很多分析师和投资者感到意外。沃顿商学院教授**杰里米西格尔&#xff08;Jeremy Siegel&#xff09;**在短短三天内就改变了他对美联储政策的看法。此前&#xff0c;他曾呼吁美联储迅速降息&#xff0c;但现在他认为这种紧急…

五,搭建环境:辅助功能

五&#xff0c;搭建环境&#xff1a;辅助功能 文章目录 五&#xff0c;搭建环境&#xff1a;辅助功能编写登录失败异常编写常量类MD5 工具 (加密工具类)日志配置文件 编写登录失败异常 我们在 demo-module04-util 模块下&#xff0c;创建一个名为&#xff1a;com.rainbowsea.i…

10、MySQL-索引

目录 1、索引概述 2、索引结构 2.1 BTree 2.2 BTree 2.3 Hash 3、索引分类 4、索引语法 4.1 创建索引 4.2 查看索引 4.3 删除索引 5、SQL性能分析 5.1 SQL执行频率 5.2 慢查询日志 5.3 profile详情 5.4 explain执行计划 6、索引使用 6.1 验证索引效率 6.2 最左…

浪潮云服务器(Inspur)硬件监控指标解读

随着企业业务的快速发展&#xff0c;服务器的稳定运行变得愈发重要。浪潮云服务器以其高性能和稳定性&#xff0c;在数据中心中扮演着关键角色。为了确保服务器的稳定运行&#xff0c;监控易作为一款专业的IT基础设施监控软件&#xff0c;为浪潮云服务器提供了全面的硬件监控解…