最终效果
文章目录
- 最终效果
- 前言
- 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 // v8private ScriptableRenderer renderer;
#endifpublic 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 // v8this.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 insteadvar 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 TemporaryRTif (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_NEWERif (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!");}
#endifif (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 requiredif (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 CameraColorif (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 = "";}}
#endifblitPass.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
一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~