Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Postprocessingstack/k upgrade #8064

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,19 @@ enum Pass
{
CoCCalculation,
CoCTemporalFilter,
downsampleInitialMaxCoC,
downsampleMaxCoC,
extendMaxCoC,
DownsampleAndPrefilter,
BokehSmallKernel,
BokehMediumKernel,
BokehLargeKernel,
BokehVeryLargeKernel,
BokehUnified,
BokehKernel1,
BokehKernel2,
BokehKernel3,
BokehKernel4,
PostFilter,
Combine,
DebugOverlay
Expand Down Expand Up @@ -135,17 +143,25 @@ RenderTextureFormat SelectFormat(RenderTextureFormat primary, RenderTextureForma
return RenderTextureFormat.Default;
}

float CalculateMaxCoCRadius(int screenHeight)
float CalculateMaxCoCRadius(int screenHeight, out int mipLevel)
{
// Estimate the allowable maximum radius of CoC from the kernel
// size (the equation below was empirically derived).
float radiusInPixels = (float)settings.kernelSize.value * 4f + 6f;

// Find the miplevel encasing the bokeh radius.
mipLevel = (int)(Mathf.Log(radiusInPixels * 2 - 1) / Mathf.Log(2));

// Applying a 5% limit to the CoC radius to keep the size of
// TileMax/NeighborMax small enough.
return Mathf.Min(0.05f, radiusInPixels / screenHeight);
}

void CalculateCoCKernelLimits(int screenHeight, out Vector4 cocKernelLimitsA, out Vector4 cocKernelLimitsB)
{
cocKernelLimitsA = new Vector4(2-0.5f, 6- 0.5f, 10- 0.5f, 14- 0.5f) / screenHeight;
cocKernelLimitsB = new Vector4(18, 22, 26, 30) / screenHeight;
}

RenderTexture CheckHistory(int eye, int id, PostProcessRenderContext context, RenderTextureFormat format)
{
var rt = m_CoCHistoryTextures[eye][id];
Expand All @@ -166,6 +182,9 @@ RenderTexture CheckHistory(int eye, int id, PostProcessRenderContext context, Re

public override void Render(PostProcessRenderContext context)
{
bool useUnified = true;// (Time.time % 2f) < 1f; // (kc)
bool useStaticTiles = false;

// The coc is stored in alpha so we need a 4 channels target. Note that using ARGB32
// will result in a very weak near-blur.
var colorFormat = context.camera.allowHDR ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32;
Expand All @@ -177,13 +196,35 @@ public override void Render(PostProcessRenderContext context)
var s1 = Mathf.Max(settings.focusDistance.value, f);
var aspect = (float)context.screenWidth / (float)context.screenHeight;
var coeff = f * f / (settings.aperture.value * (s1 - f) * scaledFilmHeight * 2f);
var maxCoC = CalculateMaxCoCRadius(context.screenHeight);
int maxCoCMipLevel;
var maxCoC = CalculateMaxCoCRadius(context.screenHeight, out maxCoCMipLevel);

// pad full-resolution screen so that the number of mips required by maxCoCMipLevel does not cause the downsampling chain to skip row or colums of pixels.
int tileSize = 1 << maxCoCMipLevel;
int paddedWidth = ((context.width + tileSize - 1) >> maxCoCMipLevel) << maxCoCMipLevel;
int paddedHeight = ((context.height + tileSize - 1) >> maxCoCMipLevel) << maxCoCMipLevel;

Vector4 cocKernelLimitsA;
Vector4 cocKernelLimitsB;
CalculateCoCKernelLimits(context.screenHeight, out cocKernelLimitsA, out cocKernelLimitsB);
cocKernelLimitsA /= maxCoC;
cocKernelLimitsB /= maxCoC;

var sheet = context.propertySheets.Get(context.resources.shaders.depthOfField);
sheet.properties.Clear();
sheet.properties.SetFloat(ShaderIDs.Distance, s1);
sheet.properties.SetFloat(ShaderIDs.LensCoeff, coeff);
sheet.properties.SetVector(ShaderIDs.CoCKernelLimitsA, cocKernelLimitsA);
sheet.properties.SetVector(ShaderIDs.CoCKernelLimitsB, cocKernelLimitsB);
sheet.properties.SetVector(ShaderIDs.MaxCoCTexUvScale, new Vector4(paddedWidth / (float)context.width, paddedHeight / (float)context.height, context.width / (float)paddedWidth, context.height / (float)paddedHeight));
sheet.properties.SetVector(ShaderIDs.KernelScale, new Vector4(maxCoC * (12f / 8f) / aspect, maxCoC * (12f / 8f), maxCoC * (12f / 8f), 0f)); // (kc) hardcoded for 4 rings
sheet.properties.SetVector(ShaderIDs.MarginFactors, new Vector4(2f / (context.height >> 1), (context.height >> 1) / 2f, 0f, 0f));
sheet.properties.SetFloat(ShaderIDs.MaxCoC, maxCoC);
sheet.properties.SetVector(ShaderIDs.CoCScreen, new Vector4(context.width, context.height, 1f / context.width, 1f / context.height));
sheet.properties.SetFloat(ShaderIDs.CoCTileXCount, paddedWidth >> maxCoCMipLevel);
sheet.properties.SetFloat(ShaderIDs.CoCTileYCount, paddedHeight >> maxCoCMipLevel);
sheet.properties.SetFloat(ShaderIDs.CoCTilePixelWidth, 1 << maxCoCMipLevel);
sheet.properties.SetFloat(ShaderIDs.CoCTilePixelHeight, 1 << maxCoCMipLevel);
sheet.properties.SetFloat(ShaderIDs.RcpMaxCoC, 1f / maxCoC);
sheet.properties.SetFloat(ShaderIDs.RcpAspect, 1f / aspect);

Expand Down Expand Up @@ -213,13 +254,55 @@ public override void Render(PostProcessRenderContext context)
cmd.SetGlobalTexture(ShaderIDs.CoCTex, historyWrite);
}

if (useUnified || useStaticTiles)
{
// Downsampling CoC
context.GetScreenSpaceTemporaryRT(cmd, ShaderIDs.MaxCoCMips[1], 0, cocFormat, RenderTextureReadWrite.Linear, FilterMode.Point, paddedWidth >> 1, paddedHeight >> 1);
cmd.BlitFullscreenTriangle(ShaderIDs.CoCTex, ShaderIDs.MaxCoCMips[1], sheet, (int)Pass.downsampleInitialMaxCoC);

for (int i = 2; i <= maxCoCMipLevel; ++i)
{
context.GetScreenSpaceTemporaryRT(cmd, ShaderIDs.MaxCoCMips[i], 0, cocFormat, RenderTextureReadWrite.Linear, FilterMode.Point, paddedWidth >> i, paddedHeight >> i);
cmd.BlitFullscreenTriangle(ShaderIDs.MaxCoCMips[i - 1], ShaderIDs.MaxCoCMips[i], sheet, (int)Pass.downsampleMaxCoC);
}

// Extend CoC
context.GetScreenSpaceTemporaryRT(cmd, ShaderIDs.MaxCoCTex, 0, cocFormat, RenderTextureReadWrite.Linear, FilterMode.Point, paddedWidth >> maxCoCMipLevel, paddedHeight >> maxCoCMipLevel);
cmd.BlitFullscreenTriangle(ShaderIDs.MaxCoCMips[maxCoCMipLevel], ShaderIDs.MaxCoCTex, sheet, (int)Pass.extendMaxCoC);
}

// Downsampling and prefiltering pass
context.GetScreenSpaceTemporaryRT(cmd, ShaderIDs.DepthOfFieldTex, 0, colorFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, context.width / 2, context.height / 2);
cmd.BlitFullscreenTriangle(context.source, ShaderIDs.DepthOfFieldTex, sheet, (int)Pass.DownsampleAndPrefilter);

// Bokeh simulation pass
context.GetScreenSpaceTemporaryRT(cmd, ShaderIDs.DepthOfFieldTemp, 0, colorFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, context.width / 2, context.height / 2);
cmd.BlitFullscreenTriangle(ShaderIDs.DepthOfFieldTex, ShaderIDs.DepthOfFieldTemp, sheet, (int)Pass.BokehSmallKernel + (int)settings.kernelSize.value);
if (useUnified)
{
/*
int tileXCount = paddedWidth >> maxCoCMipLevel;
int tileYCount = paddedHeight >> maxCoCMipLevel;
int tileCount = tileXCount * tileYCount;
cmd.SetGlobalFloat(ShaderIDs.CoCRingCount, 2.0f);
cmd.BlitProcedural(ShaderIDs.DepthOfFieldTex, ShaderIDs.DepthOfFieldTemp, sheet, (int)Pass.BokehUnified, 6, tileCount);
*/
cmd.BlitFullscreenTriangle(ShaderIDs.DepthOfFieldTex, ShaderIDs.DepthOfFieldTemp, sheet, (int)Pass.BokehUnified);
}
else if (useStaticTiles)
{
int tileXCount = paddedWidth >> maxCoCMipLevel;
int tileYCount = paddedHeight >> maxCoCMipLevel;
int tileCount = tileXCount * tileYCount;
for (int i = 0; i < 4; ++i)
{
cmd.SetGlobalFloat(ShaderIDs.CoCRingCount, i + 1);
cmd.BlitProcedural(ShaderIDs.DepthOfFieldTex, ShaderIDs.DepthOfFieldTemp, sheet, (int)Pass.BokehKernel1 + i, 6, tileCount);
}
}
else
{
cmd.BlitFullscreenTriangle(ShaderIDs.DepthOfFieldTex, ShaderIDs.DepthOfFieldTemp, sheet, (int)Pass.BokehSmallKernel + (int)settings.kernelSize.value);
}

// Postfilter pass
cmd.BlitFullscreenTriangle(ShaderIDs.DepthOfFieldTemp, ShaderIDs.DepthOfFieldTex, sheet, (int)Pass.PostFilter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,34 @@ public static void BlitFullscreenTriangle(this CommandBuffer cmd, RenderTargetId
#endif
}

/// <summary>
/// Blits procedural geometry using a given material.
/// </summary>
/// <param name="cmd">The command buffer to use</param>
/// <param name="source">The source render target</param>
/// <param name="destination">The destination render target</param>
/// <param name="propertySheet">The property sheet to use</param>
/// <param name="pass">The pass from the material to use</param>
/// <param name="instanceCount">The number of instances to render</param>
/// <param name="clear">Should the destination target be cleared?</param>
/// <param name="viewport">An optional viewport to consider for the blit</param>
/// <param name="preserveDepth">Should the depth buffer be preserved?</param>
public static void BlitProcedural(this CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, PropertySheet propertySheet, int pass, int vertexCount, int instanceCount, bool clear = false, Rect? viewport = null, bool preserveDepth = false)
{
cmd.SetGlobalTexture(ShaderIDs.MainTex, source);
var loadAction = viewport == null ? LoadAction.DontCare : LoadAction.Load;
cmd.SetRenderTargetWithLoadStoreAction(destination, loadAction, StoreAction.Store, preserveDepth ? LoadAction.Load : loadAction, StoreAction.Store);

if (viewport != null)
cmd.SetViewport(viewport.Value);

if (clear)
cmd.ClearRenderTarget(true, true, Color.clear);

// TODO: detect which platforms support quads
cmd.DrawProcedural(Matrix4x4.identity, propertySheet.material, pass, MeshTopology.Triangles, vertexCount, instanceCount, propertySheet.properties);
}

/// <summary>
/// Blits a fullscreen triangle from a double-wide source.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,25 @@ static class ShaderIDs

internal static readonly int DepthOfFieldTemp = Shader.PropertyToID("_DepthOfFieldTemp");
internal static readonly int DepthOfFieldTex = Shader.PropertyToID("_DepthOfFieldTex");
internal static readonly int[] MaxCoCMips = new int[] {
Shader.PropertyToID("_CoCMip0"), Shader.PropertyToID("_CoCMip1"), Shader.PropertyToID("_CoCMip2"), Shader.PropertyToID("_CoCMip3"),
Shader.PropertyToID("_CoCMip4"), Shader.PropertyToID("_CoCMip5"), Shader.PropertyToID("_CoCMip6"), Shader.PropertyToID("_CoCMip7"),
Shader.PropertyToID("_CoCMip8"), Shader.PropertyToID("_CoCMip9"), Shader.PropertyToID("_CoCMip10"), Shader.PropertyToID("_CoCMip11")
};
internal static readonly int MaxCoCTex = Shader.PropertyToID("_MaxCoCTex");
internal static readonly int Distance = Shader.PropertyToID("_Distance");
internal static readonly int LensCoeff = Shader.PropertyToID("_LensCoeff");
internal static readonly int CoCKernelLimitsA = Shader.PropertyToID("_CoCKernelLimitsA");
internal static readonly int CoCKernelLimitsB = Shader.PropertyToID("_CoCKernelLimitsB");
internal static readonly int MaxCoCTexUvScale = Shader.PropertyToID("_MaxCoCTexUvScale");
internal static readonly int CoCRingCount = Shader.PropertyToID("_CoCRingCount");
internal static readonly int CoCScreen = Shader.PropertyToID("_CoCScreen");
internal static readonly int CoCTileXCount = Shader.PropertyToID("_CoCTileXCount");
internal static readonly int CoCTileYCount = Shader.PropertyToID("_CoCTileYCount");
internal static readonly int CoCTilePixelWidth = Shader.PropertyToID("_CoCTilePixelWidth");
internal static readonly int CoCTilePixelHeight = Shader.PropertyToID("_CoCTilePixelHeight");
internal static readonly int KernelScale = Shader.PropertyToID("_KernelScale");
internal static readonly int MarginFactors = Shader.PropertyToID("_MarginFactors");
internal static readonly int MaxCoC = Shader.PropertyToID("_MaxCoC");
internal static readonly int RcpMaxCoC = Shader.PropertyToID("_RcpMaxCoC");
internal static readonly int RcpAspect = Shader.PropertyToID("_RcpAspect");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (1.0)
#define UNITY_GATHER_SUPPORTED (SHADER_TARGET >= 50)
#define UNITY_CAN_READ_POSITION_IN_FRAGMENT_PROGRAM 1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (1.0)
#define UNITY_GATHER_SUPPORTED (SHADER_TARGET >= 50)
#define UNITY_CAN_READ_POSITION_IN_FRAGMENT_PROGRAM 1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// ALso used for Direct3D 11 "feature level 9.x" target for Windows Store and Windows Phone
#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 0
#define UNITY_NEAR_CLIP_VALUE (0.0)
#define UNITY_GATHER_SUPPORTED 0
#define UNITY_CAN_READ_POSITION_IN_FRAGMENT_PROGRAM 1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (1.0)
#define UNITY_GATHER_SUPPORTED 0 // Currently broken on Metal for some reason (May 2017)
#define UNITY_CAN_READ_POSITION_IN_FRAGMENT_PROGRAM 1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// For now OpenGL is considered at GLES2 level
#define UNITY_UV_STARTS_AT_TOP 0
#define UNITY_REVERSED_Z 0
#define UNITY_NEAR_CLIP_VALUE (-1.0)
#define UNITY_GATHER_SUPPORTED 0
#define UNITY_CAN_READ_POSITION_IN_FRAGMENT_PROGRAM 1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 0
#define UNITY_NEAR_CLIP_VALUE (0.0)
#define UNITY_GATHER_SUPPORTED 0
#define UNITY_CAN_READ_POSITION_IN_FRAGMENT_PROGRAM 0

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (1.0)
#define UNITY_GATHER_SUPPORTED (SHADER_TARGET >= 50)
#define UNITY_CAN_READ_POSITION_IN_FRAGMENT_PROGRAM 1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (1.0)
#define UNITY_GATHER_SUPPORTED (SHADER_TARGET >= 50)

#define TEXTURE2D_SAMPLER2D(textureName, samplerName) Texture2D textureName; SamplerState samplerName
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (1.0)
#define UNITY_GATHER_SUPPORTED (SHADER_TARGET >= 50)
#define UNITY_CAN_READ_POSITION_IN_FRAGMENT_PROGRAM 1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (1.0)
#define UNITY_GATHER_SUPPORTED (SHADER_TARGET >= 50)
#define UNITY_CAN_READ_POSITION_IN_FRAGMENT_PROGRAM 1

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define UNITY_UV_STARTS_AT_TOP 1
#define UNITY_REVERSED_Z 1
#define UNITY_NEAR_CLIP_VALUE (1.0)
#define UNITY_GATHER_SUPPORTED (SHADER_TARGET >= 50)
#define UNITY_CAN_READ_POSITION_IN_FRAGMENT_PROGRAM 1

Expand Down
Loading
Loading