You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

194 lines
8.3 KiB

using UnityEngine.Assertions;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
namespace UnityEngine.Rendering.HighDefinition
{
/// <summary>
/// A bank of pre-generated blue noise textures.
/// </summary>
public sealed class BlueNoise
{
/// <summary>
/// Single channel (luminance only) 16x16 textures.
/// </summary>
public Texture2D[] textures16L { get { return m_Textures16L; } }
/// <summary>
/// Multi-channel (red, gree, blue) 16x16 textures.
/// </summary>
public Texture2D[] textures16RGB { get { return m_Textures16RGB; } }
/// <summary>
/// A TextureArray containing all the single channel (luminance only) 16x16 textures.
/// </summary>
public Texture2DArray textureArray16L { get { return m_TextureArray16L; } }
/// <summary>
/// A TextureArray containing all the multi-channel (red, green, blue) 16x16 textures.
/// </summary>
public Texture2DArray textureArray16RGB { get { return m_TextureArray16RGB; } }
readonly Texture2D[] m_Textures16L;
readonly Texture2D[] m_Textures16RGB;
Texture2DArray m_TextureArray16L;
Texture2DArray m_TextureArray16RGB;
static readonly System.Random m_Random = new System.Random();
DitheredTextureSet m_DitheredTextureSet1SPP;
DitheredTextureSet m_DitheredTextureSet8SPP;
DitheredTextureSet m_DitheredTextureSet256SPP;
/// <summary>
/// Creates a new instance of the blue noise texture bank.
/// </summary>
/// <param name="resources">A reference to the render pipeline resources asset.</param>
internal BlueNoise(HDRenderPipeline renderPipeline)
{
var textures = renderPipeline.runtimeTextures;
InitTextures(16, TextureFormat.Alpha8, textures.blueNoise16LTex, out m_Textures16L, out m_TextureArray16L);
InitTextures(16, TextureFormat.RGB24, textures.blueNoise16RGBTex, out m_Textures16RGB, out m_TextureArray16RGB);
m_DitheredTextureSet1SPP = new DitheredTextureSet
{
owenScrambled256Tex = RTHandles.Alloc(textures.owenScrambled256Tex),
scramblingTile = RTHandles.Alloc(textures.scramblingTile1SPP),
rankingTile = RTHandles.Alloc(textures.rankingTile1SPP),
scramblingTex = RTHandles.Alloc(textures.scramblingTex)
};
m_DitheredTextureSet8SPP = new DitheredTextureSet
{
owenScrambled256Tex = RTHandles.Alloc(textures.owenScrambled256Tex),
scramblingTile = RTHandles.Alloc(textures.scramblingTile8SPP),
rankingTile = RTHandles.Alloc(textures.rankingTile8SPP),
scramblingTex = RTHandles.Alloc(textures.scramblingTex)
};
m_DitheredTextureSet256SPP = new DitheredTextureSet
{
owenScrambled256Tex = RTHandles.Alloc(textures.owenScrambled256Tex),
scramblingTile = RTHandles.Alloc(textures.scramblingTile256SPP),
rankingTile = RTHandles.Alloc(textures.rankingTile256SPP),
scramblingTex = RTHandles.Alloc(textures.scramblingTex)
};
}
/// <summary>
/// Cleanups up internal textures. This method should be called before disposing of this instance.
/// </summary>
public void Cleanup()
{
CoreUtils.Destroy(m_TextureArray16L);
CoreUtils.Destroy(m_TextureArray16RGB);
m_TextureArray16L = null;
m_TextureArray16RGB = null;
}
/// <summary>
/// Returns a random, single channel (luminance only) 16x16 blue noise texture.
/// </summary>
/// <returns>A single channel (luminance only) 16x16 blue noise texture.</returns>
public Texture2D GetRandom16L()
{
return textures16L[(int)(m_Random.NextDouble() * (textures16L.Length - 1))];
}
/// <summary>
/// Returns a random, multi-channel (red, green blue) 16x16 blue noise texture.
/// </summary>
/// <returns>A multi-channel (red, green blue) 16x16 blue noise texture.</returns>
public Texture2D GetRandom16RGB()
{
return textures16RGB[(int)(m_Random.NextDouble() * (textures16RGB.Length - 1))];
}
static void InitTextures(int size, TextureFormat format, Texture2D[] sourceTextures, out Texture2D[] destination, out Texture2DArray destinationArray)
{
Assert.IsNotNull(sourceTextures);
int len = sourceTextures.Length;
Assert.IsTrue(len > 0);
destination = new Texture2D[len];
destinationArray = new Texture2DArray(size, size, len, format, false, true)
{
hideFlags = HideFlags.HideAndDontSave
};
for (int i = 0; i < len; i++)
{
var noiseTex = sourceTextures[i];
// Fail safe; should never happen unless the resources asset is broken
if (noiseTex == null)
{
destination[i] = Texture2D.whiteTexture;
continue;
}
destination[i] = noiseTex;
Graphics.CopyTexture(noiseTex, 0, 0, destinationArray, i, 0);
}
}
// Structure that holds all the dithered sampling texture that shall be binded at dispatch time.
internal struct DitheredTextureSet
{
public RTHandle owenScrambled256Tex;
public RTHandle scramblingTile;
public RTHandle rankingTile;
public RTHandle scramblingTex;
}
// Structure that holds the Render Graph handles to the dithered sampling texture that have been loaded
// at a given Render Graph execution using ImportResources()
internal struct DitheredTextureHandleSet
{
public TextureHandle owenScrambled256Tex;
public TextureHandle scramblingTile;
public TextureHandle rankingTile;
public TextureHandle scramblingTex;
}
internal DitheredTextureSet DitheredTextureSet1SPP() => m_DitheredTextureSet1SPP;
internal DitheredTextureSet DitheredTextureSet8SPP() => m_DitheredTextureSet8SPP;
internal DitheredTextureSet DitheredTextureSet256SPP() => m_DitheredTextureSet256SPP;
internal static void BindDitheredTextureSet(CommandBuffer cmd, DitheredTextureSet ditheredTextureSet)
{
cmd.SetGlobalTexture(HDShaderIDs._OwenScrambledTexture, ditheredTextureSet.owenScrambled256Tex);
cmd.SetGlobalTexture(HDShaderIDs._ScramblingTileXSPP, ditheredTextureSet.scramblingTile);
cmd.SetGlobalTexture(HDShaderIDs._RankingTileXSPP, ditheredTextureSet.rankingTile);
cmd.SetGlobalTexture(HDShaderIDs._ScramblingTexture, ditheredTextureSet.scramblingTex);
}
internal static DitheredTextureHandleSet ImportSetToRenderGraph(RenderGraph renderGraph, DitheredTextureSet ditheredTextureSet)
{
var handles = new DitheredTextureHandleSet();
handles.owenScrambled256Tex = renderGraph.ImportTexture(ditheredTextureSet.owenScrambled256Tex);
handles.scramblingTile = renderGraph.ImportTexture(ditheredTextureSet.scramblingTile);
handles.rankingTile = renderGraph.ImportTexture(ditheredTextureSet.rankingTile);
handles.scramblingTex = renderGraph.ImportTexture(ditheredTextureSet.scramblingTex);
return handles;
}
// ComputeCommandBuffer API is more restrictive than UnsafeCommandBuffer and requires RG texture handles to check if Global state is affected
internal static void BindDitheredTextureSet(ComputeCommandBuffer cmd, DitheredTextureHandleSet ditheredTextureSet)
{
cmd.SetGlobalTexture(HDShaderIDs._OwenScrambledTexture, ditheredTextureSet.owenScrambled256Tex);
cmd.SetGlobalTexture(HDShaderIDs._ScramblingTileXSPP, ditheredTextureSet.scramblingTile);
cmd.SetGlobalTexture(HDShaderIDs._RankingTileXSPP, ditheredTextureSet.rankingTile);
cmd.SetGlobalTexture(HDShaderIDs._ScramblingTexture, ditheredTextureSet.scramblingTex);
}
}
}