unity shader入门精要_Unity后处理效果学习资源汇总

0737708396d330d6c26fae7fe6b286a9.png

分享一下近期学习的Unity后处理资源和一些待研究的文章。

大部分都是笔记,要学习的话建议看原文~

后处理(Post-Processing),在图形学和游戏开发等领域是提升最终画面呈现品质的重要渲染技术。后处理渲染技术的好坏,往往决定了游戏画面是否能够达到令人惊艳的级别。

《Unity Shader入门精要》中的后处理示例

相关源码都在Github项目里,详细原理和说明建议看书~

https://github.com/candycat1992/Unity_Shaders_Book

  • 调整屏幕亮度、饱和度、对比度 BrightnessSaturationAndContrast
  • 边缘检测 EdgeDetection
  • 高斯模糊 GaussianBlur
  • 全屏泛光 Bloom
  • 运动模糊(使用帧缓存) MotionBlur
  • 再谈运动模糊(深度图) MotionBlurWithDepthTexture
  • 全局雾效(深度图) FogWithDepthTexturee
  • 再谈边缘检测(深度法线图) EdgeDetectNormalAndDepth
  • 再谈全局雾效(使用噪声,动态) FogWithNoise

高品质后处理:十种图像模糊算法的总结与实现

源码见原文

毛星云:高品质后处理:十种图像模糊算法的总结与实现​zhuanlan.zhihu.com
847145b7f4f4b91c6157bc66717afaa1.png

高斯模糊(Gaussian Blur)

    • 也叫高斯平滑(Gaussian smoothing),最经典的模糊算法
    • 图像模糊的本质一个过滤高频信号,保留低频信号的过程。过滤高频的信号的一个常见可选方法是卷积滤波
    • 图像的高斯模糊过程即图像与正态分布做卷积
    • 高斯核(Gaussian Kernel)是一个正方形的像素阵列,例:5x5,1/256 1 4 6 4 1

方框模糊(Box Blur)

    • 常被称为盒式模糊,平均值模糊
    • box blur也有不少扩展与变体,比如Tent Blur(两次Box Blur)、Quadratic Blur(三次Box Blur)等

Kawase模糊(Kawase Blur)

    • Kawase Blur的思路是对距离当前像素越来越远的地方对四个角进行采样,且在两个大小相等的纹理之间进行乒乓式的blit。
    • 创新点在于,采用了随迭代次数移动的blur kernel,而不是类似高斯模糊,或box blur一样从头到尾固定的blur kernel。
    • 实践数据表明,在相似的模糊表现下,Kawase Blur比经过优化的高斯模糊的性能约快1.5倍到3倍。

双重模糊(Dual Blur)

    • Dual Kawase Blur,简称Dual Blur,是SIGGRAPH 2015上ARM团队提出的一种衍生自Kawase Blur的模糊算法。
    • Dual Kawase Blur的核心思路在于blit过程中进行降采样和升采样
    • Dual Kawase Blur具有最佳的性能表现。

散景模糊(Bokeh Blur)

    • 散景(Bokeh)亦称焦外成像,是一个摄影名词,一般表示在景深较浅的摄影成像中,落在景深以外的画面,会有逐渐产生松散模糊的效果
    • 在图形学领域模拟散景(Bokeh)的方法有很多,本文将以最标准的圆形散景为例,采用Golden angle(https://en.wikipedia.org/wiki/Golden_angle)的思路进行散景模糊(Bokeh Blur)算法的实现。
    • 算法思路是基于对大量离散螺旋型(spiral)分布的点的渲染,来模拟出圆形Bokeh的形状。

移轴模糊(Tilt Shift Blur)

    • 移轴模糊(Tilt Shift Blur),又称镜头模糊(Lens Blur) ,是源自摄影领域的一种模糊算法。
    • 在后处理渲染中进行移轴摄影的模拟,可以采用Grident uv算法控制画面区域模糊强度,配合全屏模糊算法的方式来实现。

光圈模糊(Iris Blur)

    • 光圈模糊(Iris Blur)是Photoshop CS6中新增的功能,用于模拟浅景深的效果。
    • 可以根据用户不同的输入参数,将普通照片模拟出景深以及散景的效果。(PS: Photoshop中也同样有Tilf-Shift Blur功能)

粒状模糊(Grainy Blur)

    • 粒状模糊(Grainy Blur)是一种低成本的模糊方法,
    • 在单pass下即可有合适的模糊表现,性能出色,且其模糊质感有点类似在画面上蒙了一层细碎的冰霜。

径向模糊(Radial Blur)

    • 径向模糊(Radial Blur)可以给画面带来很好的速度感,是各类游戏中后处理的常客,也常用于Sun Shaft等后处理特效中作为光线投射的模拟。
    • 径向模糊的原理比较直接,首先选取一个径向轴心(Radial Center),然后将每一个采样点的uv基于此径向轴心进行偏移(offset),并进行一定次数的迭代采样,最终将采样得到的RGB值累加,并除以迭代次数。

方向模糊(Directional Blur)

    • 方向模糊(Directional Blur)可以看做是径向模糊(Radial Blur)的一个变体。
    • 其主要思路是传入一个角度,然后在runtime层计算出对应的矢量方向
    • 在Shader层,将每一个采样点的uv基于此方向进行正负两次偏移(offset),接着进行一定次数的迭代采样,最终将采样得到的RGB值累加,并除以迭代次数

高品质后处理:十种故障艺术(Glitch Art)算法的总结与实现

源码见原文

毛星云:高品质后处理:十种故障艺术(Glitch Art)算法的总结与实现​zhuanlan.zhihu.com
fe86cb74b133d6128b6c6592c79c1715.png

RGB颜色分离故障(RGB Split Glitch)

    • RGB颜色分离故障(RGB Split Glitch),也称颜色偏移故障(Color Shift Glitch),是故障艺术中比较常见的表达形式之一。
    • 实现算法的主要要点在于红绿蓝三个通道采用不同的uv偏移值进行分别采样

错位图块故障(Image Block Glitch)

    • 错位图块故障(Image Block Glitch)的核心要点在于生成随机强度且横纵交错的图块,
    • 随后基于图块的强度,进行uv的抖动采样,并可以加上RGB Split等元素提升渲染表现。

错位线条故障(Line Block Glitch)

    • 错位线条故障(Line Block Glitch)具有较强的表现力,在Glitch系列特效中的出镜率也较高。
    • 实现思路在于随机宽度线条的生成
    • 接着,通过随机梯度的非等宽线条,去抖动uv采样生成源色调的blockLine Glitch

图块抖动故障(Tile Jitter Glitch)

    • 图块抖动故障 (Tile Jitter Glitch)模拟了屏幕信号的块状抖动故障。
    • 其核心算法思路在于基于uv的分层抖动。可以采用取余数的形式(fmod(x,y)方法可返回x/y的余数)来对uv进行分层,且对于层内的uv数值,进行三角函数形式的抖动。

扫描线抖动故障(Scan Line Jitter Glitch)

    • 扫描线抖动故障(Scan Line Jitter Glitch)算法较简单,但是得到的渲染表现却非常具有冲击力:
    • 一个比较直接的实现是直接对横向或者纵向UV进行基于noise的抖动

数字条纹故障(Digital Stripe Glitch)

    • 数字条纹故障(Digital Stripe Glitch)同样是出镜率较高的Glitch系后处理特效之一
    • 数字条纹故障(Digital Stripe Glitch)需在Runtime层完成noise Texture的生成,然后传入GPU中进行最终的运算和渲染呈现。
    • Runtime的核心思路为基于随机数进行随机颜色条纹贴图的生成
    • Shader层面的实现则分为两个主要部分,分别是uv偏移,以及可选的基于废弃帧的插值

模拟噪点故障(Analog Noise Glitch)

    • 模拟噪点故障(Analog Noise Glitch)的主要思路,在于用noise去扰动原先场景图的颜色值。
    • 另外,还可以加入greyScale灰度抖动,当某一刻的随机强度值大于亮度抖动阈值时,将原先的RGB颜色对应的luminance强度,呈现出黑白灰度的表现。
    • 最终,将noise扰动和随机灰度抖动两个特性相结合,得到Glitch Analog Noise最终的渲染表现

屏幕跳跃故障(Screen Jump Glitch)

    • 屏幕跳跃故障(Screen Jump Glitch)的算法原理在于取经过时间校正后的uv数值的小数部分,
    • 并于原始uv插值,得到均匀梯度式扰动屏幕空间uv,再用此uv进行采样即可得到跳动画面的表现

屏幕抖动故障(Screen Shake Glitch)

    • 类似上文的Screen Jump,Screen Shake屏幕抖动的算法原理也在于对屏幕空间uv的抖动,
    • 但不同的是,Screen Shake屏幕抖动需采用noise噪声函数来随机扰动uv,而不是均匀梯度式的形式。

波动抖动故障(Wave Jitter Glitch)

    • 波动抖动故障(Wave Jitter Glitch)相较于上述的9种Glitch算法而言,用到了更为复杂的噪声生成函数。
    • 噪声生成函数库 XNoiseLibrary
    • 波动抖动故障(Wave Jitter Glitch)后处理的核心思路是用双层的noise实现波浪形扭动uv
    • 而双层的noise波浪,表现力更强
    • 有了基于双层noise的Wave Jitter Glitch表现,还可以加上RGB Split算法,进一步提升表现力

总结:若要在屏幕空间实现故障艺术风格的渲染表现,关键在于以下几点:

    • 噪声函数的选择:噪声函数是生成各式的干扰信号的源头。
    • uv抖动方式的选择:将噪声函数作用于屏幕空间uv后,基于新的uv进行采样,以产生故障的抖动表现。
    • 采样通道的选择:对RGB分别采样,或者选取特定通道进行采样,以实现多种风格的故障表现。
    • 颜色空间的转换:善用YUV、CMY、HSV、YIQ、YCbCr 、YC1C2等空间与RGB空间之间的转换,以实现多种风格的故障表现。
    • 以及最最重要的——创意,算法只是基础,技术只是工具,最后能做出多惊艳有趣的效果就要看想象力和创造力了

浅墨的后处理库Github开源项目

https://github.com/QianMo/X-PostProcessing-Library

Catlike 系列教程

全屏泛光Bloom效果原理及实现

https://catlikecoding.com/unity/tutorials/advanced-rendering/bloom/

景深Depth of Field效果原理及实现

https://catlikecoding.com/unity/tutorials/advanced-rendering/bloom/

FXAA 抗锯齿原理及实现

https://catlikecoding.com/unity/tutorials/advanced-rendering/fxaa/

其他文章

Unity实现地图扫描效果(后处理、深度图转世界坐标)

joker:Unity实现地图扫描效果​zhuanlan.zhihu.com
d78754bb0a107193616d36ffc3058e4a.png

Unity后处理实现The World时停效果

陈泽日天:Unity后处理实现The World时停效果​zhuanlan.zhihu.com
a7d8d51eccceb8b6238a291cba2b2a2d.png

Unity实现只狼弹反后处理效果

joker:Unity实现只狼弹反后处理效果​zhuanlan.zhihu.com
a449da3e95712ebfc30f7b8c6071f842.png

《龙猫》与屏幕空间的雨幕和涟漪

天源:《龙猫》与屏幕空间的雨幕和涟漪​zhuanlan.zhihu.com
288bd1d5025f456b1218288a3a0e187b.png

Aniti-Aliasing抗锯齿知识总结 140

FrankZhou:Aniti-Aliasing抗锯齿知识总结​zhuanlan.zhihu.com
5c6210e38a4aaf81e86a41e42d7b615c.png

基于屏幕空间的描边实现(碎面特效) 39

雨诺寒雪:基于屏幕空间的描边实现​zhuanlan.zhihu.com
95322ce756e6d6e5bd07cc5bfc867470.png

Unity_StochasticSSR[1] 228 屏幕空间的反射 Screen Space Reflection

CGBull:Unity_StochasticSSR[1]​zhuanlan.zhihu.com
4c965218d9c63276776c0a5406eb9265.png

Unity_StochasticSSR[2] 67

CGBull:Unity_StochasticSSR[2]​zhuanlan.zhihu.com
4aa4cd1cd44ab315d9ae17627569c3e0.png

Unity_StochasticSSR[3] 40

CGBull:Unity_StochasticSSR[3]​zhuanlan.zhihu.com
5a5b60c35419e6660274789827047a00.png

Unity Shader-后处理:景深

Unity Shader-后处理:景深​blog.csdn.net
b75ac67856b55a77e39d17d232b331a3.png

利用Stencil来优化局部后处理特效 33

flashyiyi:利用Stencil来优化局部后处理特效​zhuanlan.zhihu.com
0bc9cb0f79e28084201b1e5c69ed7554.png

将来发现了其他优秀的后处理相关文章会不断更新~

也欢迎在评论区推荐优秀或者有趣的后处理文章~

以上。

Unity中,Shader是用来渲染场景的关键部分。在URP中,Shader的编写方式与传统的Shader编写方式略有不同,但其核心思想仍然是相同的。 在本文中,我们将从一个简单的Unlit Shader开始,介绍在URP中编写Shader的基本步骤。 1. 创建Shader 首先,我们需要创建一个新的Shader。在Project视图中右键点击Assets文件夹,选择Create > Shader > Unlit Shader。 2. 编写Shader 打开新创建的Shader文件,我们可以看到如下代码: ``` Shader "Unlit/MyUnlitShader" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG } } FallBack "Diffuse" } ``` 这个Shader使用了Unity默认的Unlit Shader模板,并添加了一个_MainTex属性,该属性用于接收贴图,并在渲染过程中使用。 3. 添加SubShader 在URP中,我们需要为Shader添加一个SubShader。在SubShader中,我们可以定义一系列Pass,每个Pass都是对场景中不同物体的渲染。 修改代码如下: ``` Shader "Unlit/MyUnlitShader" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG } } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); return o; } fixed4 frag () : SV_Target { fixed4 col = fixed4(1, 1, 1, 1); return col; } ENDCG } } FallBack "Diffuse" } ``` 在这个代码中,我们添加了一个新的SubShader,并为其添加了一个Pass。这个Pass是一个简单的颜色填充Pass,用于在没有贴图的情况下渲染物体。 4. 测试Shader 最后,我们需要将Shader应用到一个物体上并测试它的效果。在Scene视图中创建一个新的Cube,并将新创建的Shader应用到该Cube上。 现在,你应该能够看到在没有贴图的情况下,该Cube被渲染为白色。如果你将贴图赋给_MainTex属性,你应该能够看到该Cube被渲染为该贴图。 这就是从一个简单的Unlit Shader开始,在URP中编写Shader的基本步骤。通过深入学习Shader编写的过程,你将能够创建更高级、更复杂的Shader,并为你的游戏带来更加出色的视觉效果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值