参考:https://github.com/Unity-Technologies/PostProcessing/wiki/(v2)-Quickstart
1. v1版本直接将postProcessBehaviour脚本拖到摄像机上,而v2中,将postProcessLayer拖到摄像机上,如图
好处:专用的layer放屏幕后处理效果以获取较好的性能。
注意:layer不要用everything或default,否则多个屏幕后期混合开销会较大
上图中,layer包含postProcess、default层,那么包含如下对象
和default层对象
2. 包含volume的游戏对象的创建:新建一个空GameObject,在右侧,点击Add Component按钮,在下拉列表中选取postProcessVolume,新创建的volume组件什么profile都没有,可以手动拖入已有的profile,也可以点击New新建一个profile。
public static void Blit(Texture source, RenderTexture dest, Material
mat, [Internal.DefaultValue("-1")] int pass);
而是用
cmd.DrawMesh(fullscreenTriangle, Matrix4x4.identity, propertySheet.material, 0, pass, propertySheet.properties);
v2用MaterialPropertyBlock存储shader的属性,将创建material的代码封装到PropertySheet里,判断某个特效对应的propertySheet是否存在,不存在才会新建对象。
v1各个component的prepare函数里首先判断该shader的material在不在,不在则通过shader创建material,再改变material的shader属性,然后用commandBuffer的blit函数:
public static void Blit(Texture source, RenderTexture dest, Material
mat, [Internal.DefaultValue("-1")] int pass);
v2中,用propertySheet封装material和materialBlock,后者存储shader的属性
`var sheet = context.propertySheets.Get(context.resources.shaders.bloom);
get函数代码如下
public PropertySheet Get(Shader shader)
{
PropertySheet sheet;
if (m_Sheets.TryGetValue(shader, out sheet))
return sheet;
if (shader == null)
throw new ArgumentException(string.Format("Invalid shader ({0})", shader));
var shaderName = shader.name;
var material = new Material(shader)
{
name = string.Format("PostProcess - {0}", shaderName.Substring(shaderName.LastIndexOf('/') + 1)),
hideFlags = HideFlags.DontSave
};
sheet = new PropertySheet(material);
m_Sheets.Add(shader, sheet);
return sheet;
}`
shader属性放到materialPropertyBLock中,如下:
// Apply auto exposure adjustment in the prefiltering pass
sheet.properties.SetTexture(ShaderIDs.AutoExposureTex, context.autoExposureTexture);
“`
public void DrawMesh(Mesh mesh, Matrix4x4 matrix, Material material, [DefaultValue(“0”)] int submeshIndex, [DefaultValue(“-1”)] int shaderPass, [DefaultValue(“null”)] MaterialPropertyBlock properties);
猜想由于几个原因:material和materialPropertyBlock分开,是否创建销毁material的频率降低提高性能,而且改变material的shader的属性更方便,另外用DrawMesh,输入为屏幕空间的顶点,在vertex shader中不再需要转换矩阵,提高性能:
struct VaryingsDefault
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
float2 texcoordStereo : TEXCOORD1;
};
VaryingsDefault VertDefault(AttributesDefault v)
{
VaryingsDefault o;
o.vertex = float4(v.vertex.xy, 0.0, 1.0);
o.texcoord = TransformTriangleVertexToUV(v.vertex.xy);
#if UNITY_UV_STARTS_AT_TOP
o.texcoord = o.texcoord * float2(1.0, -1.0) + float2(0.0, 1.0);
#endif
o.texcoordStereo = TransformStereoScreenSpaceTex(o.texcoord, 1.0);
return o;
}
2. shader的每个pass在脚本里用枚举类型表示,更清晰易读。
v1里:
`Graphics.Blit(last, m_BlurBuffer2[level], material, 3);`
v2里:
`enum Pass
{
Prefilter13,
Prefilter4,
Downsample13,
Downsample4,
UpsampleTent,
UpsampleBox,
DebugOverlayThreshold,
DebugOverlayTent,
DebugOverlayBox
}
(int)Pass.Downsample13 + qualityOffset;
context.GetScreenSpaceTemporaryRT(cmd, mipDown, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw, th);
context.GetScreenSpaceTemporaryRT(cmd, mipUp, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw, th);
cmd.BlitFullscreenTriangle(lastDown, mipDown, sheet, pass);`
3. 增加了对每个屏幕效果的profile功能
`var cmd = context.command;
cmd.BeginSample("BloomPyramid");
cmd.EndSample("BloomPyramid");
`
4. 一些shader依赖的vertex函数、内置函数、变量和结构的声明等不再放在cginc文件中,而是放在hlsl文件中。同时,shader里包含函数改为
`Pass
{
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment FragDebugOverlayTent
ENDHLSL
}`
5. vertex shader里坐标v1要转换到屏幕坐标系,现在没有转换。应该就直接是屏幕坐标(去掉矩阵乘法的开销)。
6. uv坐标直接由顶点坐标转换得到,平台uv转换的时候不再判断纹素的y坐标,直接将uv的y坐标转换。
7. bloom shader原来有4个pass,现在有8个pass,主要改动:去掉了变体如抗闪烁、色彩空间,降采样算法修改,uv修改增加了对立体渲染的支持,去掉了每个片元shader里的hdr编码和解码操作,增加了debug的pass包括调试阈值,box箱式滤波器和帐篷式滤波器。
bloom原来有4个pass:0提取较亮区域,1和2降采样,3升采样并进行颜色叠加。
pass 0,1:提取亮度,pass0的降采样13taps,pass1的降采样是4taps;
pass 2,3:降采样,pass2降采样是13taps,pass3降采样是4taps;
pass 4, 5:升采样和颜色叠加,pass4升采样用的是帐篷式滤波器,pass5使用的是4x4箱式滤波器;
pass 6:调试threshold
pass 7:调试tent滤波器
pass 8:调试箱式滤波器
(1) bloom的降采样算法不再有抗闪烁还是不抗闪烁的选项,之前的4x4箱式滤波器降采样算法还存在,4x4箱式滤波器+抗闪烁的不再有了,多了个13箱式采样(比4x4箱式滤波器采样效果更精确),同时uv增加了立体渲染的支持。
(2) 升采样算法去掉了函数内部的宏,拆分为两个函数来写,9个和4个的,uv增加对立体渲染的支持。
(3)去掉了每个fragment shader里的先DecodeHdr,再EncodeHdr两个操作。
8. bloom属性:
diffusion(1, 10)相当于radius
anamorphic(-1,1)在计算rt大小时用到;
fast mode:勾选上,则质量高,用质量高的pass
9. profile界面去掉了雾,shader还有,改了名字Fog.shader改成DeferredFog.shader。内容没变基本上。
10. AA算法增加一种 SMAA
11. color grading改变:
可以在ps等软件中编辑3d lut然后导入到unity中,这需要支持Texture3D和compute shader。
增加3d lut。
另外界面也有所改变:
![这里写图片描述](https://img-blog.csdn.net/20180115101927042?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMTgyMjkzODE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
参考:https://github.com/Unity-Technologies/PostProcessing/wiki/(v2)-External-LUT-authoring
12. TAA,从cameraMotionVectorsTexture中采样得到vector从frag shader挪到顶点着色器。优化clipToAABB函数。
13. 增加computer shader
参考:https://docs.unity3d.com/Manual/ComputeShaders.html
14. 屏幕空间反射,ui改变较大
![这里写图片描述](https://img-blog.csdn.net/20180115102801893?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMTgyMjkzODE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
15. 更多改变参考:https://github.com/Unity-Technologies/PostProcessing/commits/v2/PostProcessing
## 一些git提交记录
1. 16.10.11更精确的检查5.6中是否支持metal和compute
shader中target改成4.5,脚本中改成systemInfo.supportsComputeShaders;
17.12.21 openGLcore和compute shader有问题,增加判断
SystemInfo.graphicsDeviceType != GraphicsDeviceType.OpenGLCore;
1. 17.12.21
显示将“手机优化”改成“fast mode”多个地方,比如bloom等
1. 17.12.21
color grading的trackball增加判断unity2018以后的贴图格式设为sRgb。
#if UNITY_2018_1_OR_NEWER
const RenderTextureReadWrite kReadWrite = RenderTextureReadWrite.sRGB;
#else
const RenderTextureReadWrite kReadWrite = RenderTextureReadWrite.Linear;
#endif
“`