1 MSAA
SRP中实现MSAA很简单。我们先在CustomRenderPipelienAsset
中添加对应的枚举,MSAA默认关闭:
public enum MSAAMode
{
Off = 1,
_2x = 2,
_4x = 4,
_8x = 8
}
[SerializeField]
MSAAMode MSAA = MSAAMode.Off;
在CameraRenderer
中,我们和后处理效果一块使用即可。在Setup
中,如果开启后处理模块,我们设置MSAA采样数,并将其应用到我们的渲染目标的声明,位于最后一个参数中:
void Setup(int MSAA)
{
...
if(postFXStack.IsActive)
{
int renderSamples = camera.allowMSAA ? MSAA : 1;
if (flags > CameraClearFlags.Color)
{
flags = CameraClearFlags.Color;
}
buffer.GetTemporaryRT(frameBufferId, bufferSize.x, bufferSize.y, 32,
FilterMode.Bilinear, useHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default,
RenderTextureReadWrite.Default, renderSamples);
buffer.SetRenderTarget(frameBufferId, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store);
}
默认采样数为1,如果设置了MSAA,那么使用对应的采样数。
关闭MSAA和4xMSAA:
目前的MSAA只处理了颜色缓冲,如果想应用于深度我们需要分开设置。
注意MSAA想得到较好的效果是比较耗能的,之后会尝试增加TAA之类的抗锯齿方法。
2 缩放渲染
缩放渲染可用于调整渲染的分辨率。在CustomRenderPipelienAsset
中添加相应的浮点变量:
[SerializeField]
float RenderScale = 1f;
在CameraRenderer
中,我们添加一个布尔变量来确定是否使用缩放渲染:
bool useScaledRendering;
Render
中确定是否使用缩放:
useScaledRendering = renderScale < 0.99f || renderScale > 1.01f;
注意在编辑器窗口中我们就不使用缩放了,以免耗能,在PrepareForSceneWindow
中将布尔值设为false:
partial void PrepareForSceneWindow()
{
if (camera.cameraType == CameraType.SceneView)
{
ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);
useScaledRendering = false;
}
}
如果设置缩放渲染的话,就使用缩放数值调整缓冲大小,否则使用原摄像机的视口大小即可:
if(useScaledRendering)
{
bufferSize.x = (int)(camera.pixelWidth * renderScale);
bufferSize.y = (int)(camera.pixelHeight * renderScale);
}
else
{
bufferSize.x = camera.pixelWidth;
bufferSize.y = camera.pixelHeight;
}
在Setup
中应用,调整渲染目标的缓冲大小:
buffer.GetTemporaryRT(frameBufferId, bufferSize.x, bufferSize.y, 32,
FilterMode.Bilinear, useHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default,
RenderTextureReadWrite.Default, renderSamples);
在Render
中,我们也将缓冲大小传入postFXStack.Setup
中。对于发光效果,我们可以设置一个布尔值来控制是否引用缩放,在PostFXSettings
中设置BloomSettings
结构体:
public bool ignoreRenderScale;
DoBloom
中,根据是否忽略缩放来调整缓冲大小:
int width, height;
if (bloom.ignoreRenderScale)
{
width = camera.pixelWidth / 2;
height = camera.pixelHeight / 2;
}
else
{
width = bufferSize.x / 2;
height = bufferSize.y / 2;
}
对应的地方应用即可。
对于后处理,我们额外添加一个缩放pass来进行渲染缩放:
Pass {
Name "Final Rescale"
HLSLPROGRAM
#pragma target 3.5
#pragma vertex DefaultPassVertex
#pragma fragment CopyPassFragment
ENDHLSL
}
一个很简单的复制pass。
在DoColorGradingAndToneMapping
的最后,根据缓冲大小的设置决定使用不同的pass:
if(bufferSize.x == camera.pixelWidth)
{
DrawFinal(sourceId, Pass.Final);
}
else
{
buffer.GetTemporaryRT(finalResultId, bufferSize.x, bufferSize.y, 0,
FilterMode.Bilinear, RenderTextureFormat.Default);
Draw(sourceId, finalResultId, Pass.Final);
DrawFinal(finalResultId, Pass.FinalRescale);
buffer.ReleaseTemporaryRT(finalResultId);
}
0.5和2:
网友评论