485 lines
22 KiB
C#
485 lines
22 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine.Experimental.Rendering;
|
|
|
|
namespace UnityEngine.Rendering.HighDefinition
|
|
{
|
|
/// <summary>
|
|
/// Available graphic formats for the cookie atlas texture.
|
|
/// </summary>
|
|
[System.Serializable]
|
|
public enum CookieAtlasGraphicsFormat
|
|
{
|
|
/// <summary>Faster sampling but at the cost of precision.</summary>
|
|
R11G11B10 = GraphicsFormat.B10G11R11_UFloatPack32,
|
|
/// <summary>Better quality and more precision for HDR cookies but uses twice as much memory compared to R11G11B10.</summary>
|
|
R16G16B16A16 = GraphicsFormat.R16G16B16A16_SFloat,
|
|
}
|
|
|
|
class LightCookieManager
|
|
{
|
|
HDRenderPipelineAsset m_RenderPipelineAsset = null;
|
|
|
|
internal static readonly int s_texSource = Shader.PropertyToID("_SourceTexture");
|
|
internal static readonly int s_texCubeSource = Shader.PropertyToID("_SourceCubeTexture");
|
|
internal static readonly int s_sourceMipLevel = Shader.PropertyToID("_SourceMipLevel");
|
|
internal static readonly int s_sourceSize = Shader.PropertyToID("_SourceSize");
|
|
internal static readonly int s_uvLimits = Shader.PropertyToID("_UVLimits");
|
|
|
|
internal const int k_MinCookieSize = 2;
|
|
|
|
readonly Material m_MaterialFilterAreaLights;
|
|
MaterialPropertyBlock m_MPBFilterAreaLights = new MaterialPropertyBlock();
|
|
|
|
RenderTexture m_TempRenderTexture0 = null;
|
|
RenderTexture m_TempRenderTexture1 = null;
|
|
|
|
// Structure for cookies used by directional and spotlights
|
|
PowerOfTwoTextureAtlas m_CookieAtlas;
|
|
|
|
#if UNITY_2020_1_OR_NEWER
|
|
#else
|
|
int m_CookieCubeResolution;
|
|
#endif
|
|
|
|
// During the light loop, when reserving space for the cookies (first part of the light loop) the atlas
|
|
// can run out of space, in this case, we set to true this flag which will trigger a re-layouting of the
|
|
// atlas (sort entries by size and insert them again).
|
|
bool m_2DCookieAtlasNeedsLayouting = false;
|
|
bool m_NoMoreSpace = false;
|
|
readonly int cookieAtlasLastValidMip;
|
|
readonly GraphicsFormat cookieFormat;
|
|
|
|
public LightCookieManager(HDRenderPipelineAsset hdAsset, int maxCacheSize)
|
|
{
|
|
// Keep track of the render pipeline asset
|
|
m_RenderPipelineAsset = hdAsset;
|
|
var hdResources = HDRenderPipeline.defaultAsset.renderPipelineResources;
|
|
|
|
// Create the texture cookie cache that we shall be using for the area lights
|
|
GlobalLightLoopSettings gLightLoopSettings = hdAsset.currentPlatformRenderPipelineSettings.lightLoopSettings;
|
|
|
|
// Also make sure to create the engine material that is used for the filtering
|
|
m_MaterialFilterAreaLights = CoreUtils.CreateEngineMaterial(hdResources.shaders.filterAreaLightCookiesPS);
|
|
|
|
int cookieAtlasSize = (int)gLightLoopSettings.cookieAtlasSize;
|
|
cookieFormat = (GraphicsFormat)gLightLoopSettings.cookieFormat;
|
|
cookieAtlasLastValidMip = gLightLoopSettings.cookieAtlasLastValidMip;
|
|
|
|
m_CookieAtlas = new PowerOfTwoTextureAtlas(cookieAtlasSize, gLightLoopSettings.cookieAtlasLastValidMip, cookieFormat, name: "Cookie Atlas (Punctual Lights)", useMipMap: true);
|
|
|
|
#if UNITY_2020_1_OR_NEWER
|
|
#else
|
|
m_CookieCubeResolution = (int)gLightLoopSettings.pointCookieSize;
|
|
#endif
|
|
}
|
|
|
|
public void NewFrame()
|
|
{
|
|
m_CookieAtlas.ResetRequestedTexture();
|
|
m_2DCookieAtlasNeedsLayouting = false;
|
|
m_NoMoreSpace = false;
|
|
}
|
|
|
|
public void Release()
|
|
{
|
|
CoreUtils.Destroy(m_MaterialFilterAreaLights);
|
|
|
|
if (m_TempRenderTexture0 != null)
|
|
{
|
|
m_TempRenderTexture0.Release();
|
|
m_TempRenderTexture0 = null;
|
|
}
|
|
if (m_TempRenderTexture1 != null)
|
|
{
|
|
m_TempRenderTexture1.Release();
|
|
m_TempRenderTexture1 = null;
|
|
}
|
|
|
|
if (m_CookieAtlas != null)
|
|
{
|
|
m_CookieAtlas.Release();
|
|
m_CookieAtlas = null;
|
|
}
|
|
}
|
|
|
|
void ReserveTempTextureIfNeeded(CommandBuffer cmd, int mipMapCount)
|
|
{
|
|
if (m_TempRenderTexture0 == null)
|
|
{
|
|
// TODO: we don't need to allocate two temp RT, we can use the atlas as temp render texture
|
|
// it will avoid additional copy of the whole mip chain into the atlas.
|
|
int sourceWidth = m_CookieAtlas.AtlasTexture.rt.width;
|
|
int sourceHeight = m_CookieAtlas.AtlasTexture.rt.height;
|
|
|
|
string cacheName = m_CookieAtlas.AtlasTexture.name;
|
|
m_TempRenderTexture0 = new RenderTexture(sourceWidth, sourceHeight, 1, cookieFormat)
|
|
{
|
|
hideFlags = HideFlags.HideAndDontSave,
|
|
useMipMap = true,
|
|
autoGenerateMips = false,
|
|
name = cacheName + "TempAreaLightRT0"
|
|
};
|
|
|
|
// Clear the textures to avoid filtering with NaNs on consoles.
|
|
for (int mipIdx = 0; mipIdx < mipMapCount; ++mipIdx)
|
|
{
|
|
cmd.SetRenderTarget(m_TempRenderTexture0, mipIdx);
|
|
cmd.ClearRenderTarget(false, true, Color.clear);
|
|
}
|
|
|
|
// We start by a horizontal gaussian into mip 1 that reduces the width by a factor 2 but keeps the same height
|
|
m_TempRenderTexture1 = new RenderTexture(sourceWidth >> 1, sourceHeight, 1, cookieFormat)
|
|
{
|
|
hideFlags = HideFlags.HideAndDontSave,
|
|
useMipMap = true,
|
|
autoGenerateMips = false,
|
|
name = cacheName + "TempAreaLightRT1"
|
|
};
|
|
|
|
// Clear the textures to avoid filtering with NaNs on consoles.
|
|
for (int mipIdx = 0; mipIdx < mipMapCount - 1; ++mipIdx)
|
|
{
|
|
cmd.SetRenderTarget(m_TempRenderTexture1, mipIdx);
|
|
cmd.ClearRenderTarget(false, true, Color.clear);
|
|
}
|
|
}
|
|
}
|
|
|
|
Texture FilterAreaLightTexture(CommandBuffer cmd, Texture source, int finalWidth, int finalHeight)
|
|
{
|
|
if (m_MaterialFilterAreaLights == null)
|
|
{
|
|
Debug.LogError("FilterAreaLightTexture has an invalid shader. Can't filter area light cookie.");
|
|
return null;
|
|
}
|
|
|
|
int sourceWidth = m_CookieAtlas.AtlasTexture.rt.width;
|
|
int sourceHeight = m_CookieAtlas.AtlasTexture.rt.height;
|
|
int viewportWidth = finalWidth;// source.width;
|
|
int viewportHeight = finalHeight;// source.height;
|
|
int mipMapCount = 1 + Mathf.FloorToInt(Mathf.Log(Mathf.Max(source.width, source.height), 2));
|
|
|
|
ReserveTempTextureIfNeeded(cmd, mipMapCount);
|
|
|
|
using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.AreaLightCookieConvolution)))
|
|
{
|
|
int targetWidth = sourceWidth;
|
|
int targetHeight = sourceHeight;
|
|
|
|
if (source.dimension == TextureDimension.Cube)
|
|
{
|
|
m_MPBFilterAreaLights.SetInt(s_sourceMipLevel, 0);
|
|
m_MPBFilterAreaLights.SetTexture(s_texCubeSource, source);
|
|
|
|
cmd.SetRenderTarget(m_TempRenderTexture0, 0);
|
|
cmd.SetViewport(new Rect(0, 0, viewportWidth, viewportHeight));
|
|
cmd.DrawProcedural(Matrix4x4.identity, m_MaterialFilterAreaLights, 3, MeshTopology.Triangles, 3, 1, m_MPBFilterAreaLights);
|
|
}
|
|
else
|
|
{
|
|
// Start by copying the source texture to the array slice's mip 0
|
|
m_MPBFilterAreaLights.SetInt(s_sourceMipLevel, 0);
|
|
m_MPBFilterAreaLights.SetTexture(s_texSource, source);
|
|
|
|
|
|
// Since we blit the cookie texture into a common texture, to avoid leaking we blit with an extra border
|
|
int border = 1;
|
|
cmd.SetRenderTarget(m_TempRenderTexture0, 0);
|
|
cmd.SetViewport(new Rect(0, 0, viewportWidth + border, viewportHeight + border));
|
|
|
|
m_MPBFilterAreaLights.SetVector(s_sourceSize, new Vector4(viewportWidth, viewportHeight, (float)(viewportWidth + border) / viewportWidth, (float)(viewportHeight + border) / viewportHeight));
|
|
cmd.DrawProcedural(Matrix4x4.identity, m_MaterialFilterAreaLights, 0, MeshTopology.Triangles, 3, 1, m_MPBFilterAreaLights);
|
|
}
|
|
|
|
// Then operate on all the remaining mip levels
|
|
Vector4 sourceSize = Vector4.zero;
|
|
for (int mipIndex = 1; mipIndex < mipMapCount; mipIndex++)
|
|
{
|
|
{ // Perform horizontal blur
|
|
sourceSize.Set(viewportWidth / (float)sourceWidth * 1.0f, viewportHeight / (float)sourceHeight, 1.0f / sourceWidth, 1.0f / sourceHeight);
|
|
Vector4 uvLimits = new Vector4(0, 0, viewportWidth / (float)sourceWidth, viewportHeight / (float)sourceHeight);
|
|
|
|
viewportWidth = Mathf.Max(1, viewportWidth >> 1);
|
|
targetWidth = Mathf.Max(1, targetWidth >> 1);
|
|
|
|
m_MPBFilterAreaLights.SetTexture(s_texSource, m_TempRenderTexture0);
|
|
m_MPBFilterAreaLights.SetInt(s_sourceMipLevel, mipIndex - 1);
|
|
m_MPBFilterAreaLights.SetVector(s_sourceSize, sourceSize);
|
|
m_MPBFilterAreaLights.SetVector(s_uvLimits, uvLimits);
|
|
|
|
cmd.SetRenderTarget(m_TempRenderTexture1, mipIndex - 1); // Temp texture is already 1 mip lower than source
|
|
cmd.SetViewport(new Rect(0, 0, viewportWidth, viewportHeight));
|
|
cmd.DrawProcedural(Matrix4x4.identity, m_MaterialFilterAreaLights, 1, MeshTopology.Triangles, 3, 1, m_MPBFilterAreaLights);
|
|
}
|
|
|
|
sourceWidth = targetWidth;
|
|
|
|
{ // Perform vertical blur
|
|
sourceSize.Set(viewportWidth / (float)sourceWidth, viewportHeight / (float)sourceHeight * 1.0f, 1.0f / sourceWidth, 1.0f / sourceHeight);
|
|
Vector4 uvLimits = new Vector4(0, 0, viewportWidth / (float)sourceWidth, viewportHeight / (float)sourceHeight);
|
|
|
|
viewportHeight = Mathf.Max(1, viewportHeight >> 1);
|
|
targetHeight = Mathf.Max(1, targetHeight >> 1);
|
|
|
|
m_MPBFilterAreaLights.SetTexture(s_texSource, m_TempRenderTexture1);
|
|
m_MPBFilterAreaLights.SetInt(s_sourceMipLevel, mipIndex - 1);
|
|
m_MPBFilterAreaLights.SetVector(s_sourceSize, sourceSize);
|
|
m_MPBFilterAreaLights.SetVector(s_uvLimits, uvLimits);
|
|
|
|
cmd.SetRenderTarget(m_TempRenderTexture0, mipIndex);
|
|
cmd.SetViewport(new Rect(0, 0, viewportWidth, viewportHeight));
|
|
cmd.DrawProcedural(Matrix4x4.identity, m_MaterialFilterAreaLights, 2, MeshTopology.Triangles, 3, 1, m_MPBFilterAreaLights);
|
|
}
|
|
|
|
sourceHeight = targetHeight;
|
|
}
|
|
}
|
|
|
|
return m_TempRenderTexture0;
|
|
}
|
|
|
|
public void LayoutIfNeeded()
|
|
{
|
|
if (!m_2DCookieAtlasNeedsLayouting)
|
|
return;
|
|
|
|
if (!m_CookieAtlas.RelayoutEntries())
|
|
{
|
|
Debug.LogError($"No more space in the 2D Cookie Texture Atlas. To solve this issue, increase the resolution of the cookie atlas in the HDRP settings.");
|
|
m_NoMoreSpace = true;
|
|
}
|
|
}
|
|
|
|
public Vector4 Fetch2DCookie(CommandBuffer cmd, Texture cookie, Texture ies)
|
|
{
|
|
int width = (int)Mathf.Max(cookie.width, ies.height);
|
|
int height = (int)Mathf.Max(cookie.width, ies.height);
|
|
|
|
if (width < k_MinCookieSize || height < k_MinCookieSize)
|
|
return Vector4.zero;
|
|
|
|
if (!m_CookieAtlas.IsCached(out var scaleBias, m_CookieAtlas.GetTextureID(cookie, ies)) && !m_NoMoreSpace)
|
|
Debug.LogError($"Unity cannot fetch the 2D Light cookie texture: {cookie} because it is not on the cookie atlas. To resolve this, open your HDRP Asset and increase the resolution of the cookie atlas.");
|
|
|
|
if (m_CookieAtlas.NeedsUpdate(cookie, ies, false))
|
|
{
|
|
m_CookieAtlas.BlitTexture(cmd, scaleBias, ies, new Vector4(1, 1, 0, 0), blitMips: false, overrideInstanceID: m_CookieAtlas.GetTextureID(cookie, ies));
|
|
m_CookieAtlas.BlitTextureMultiply(cmd, scaleBias, cookie, new Vector4(1, 1, 0, 0), blitMips: false, overrideInstanceID: m_CookieAtlas.GetTextureID(cookie, ies));
|
|
}
|
|
|
|
return scaleBias;
|
|
}
|
|
|
|
public Vector4 Fetch2DCookie(CommandBuffer cmd, Texture cookie)
|
|
{
|
|
if (cookie.width < k_MinCookieSize || cookie.height < k_MinCookieSize)
|
|
return Vector4.zero;
|
|
|
|
if (!m_CookieAtlas.IsCached(out var scaleBias, m_CookieAtlas.GetTextureID(cookie)) && !m_NoMoreSpace)
|
|
Debug.LogError($"Unity cannot fetch the 2D Light cookie texture: {cookie} because it is not on the cookie atlas. To resolve this, open your HDRP Asset and increase the resolution of the cookie atlas.");
|
|
|
|
if (m_CookieAtlas.NeedsUpdate(cookie, false))
|
|
m_CookieAtlas.BlitTexture(cmd, scaleBias, cookie, new Vector4(1, 1, 0, 0), blitMips: false);
|
|
|
|
return scaleBias;
|
|
}
|
|
|
|
public Vector4 FetchAreaCookie(CommandBuffer cmd, Texture cookie)
|
|
{
|
|
if (cookie.width < k_MinCookieSize || cookie.height < k_MinCookieSize)
|
|
return Vector4.zero;
|
|
|
|
if (!m_CookieAtlas.IsCached(out var scaleBias, cookie) && !m_NoMoreSpace)
|
|
Debug.LogError($"Area Light cookie texture {cookie} can't be fetched without having reserved. You can try to increase the cookie atlas resolution in the HDRP settings.");
|
|
|
|
int currentID = m_CookieAtlas.GetTextureID(cookie);
|
|
//RTHandle existingTexture;
|
|
if (m_CookieAtlas.NeedsUpdate(cookie, true))
|
|
{
|
|
// Generate the mips
|
|
Texture filteredAreaLight = FilterAreaLightTexture(cmd, cookie, cookie.width, cookie.height);
|
|
Vector4 sourceScaleOffset = new Vector4((cookie.width - 0.5f) / (float)atlasTexture.rt.width, (cookie.height - 0.5f) / (float)atlasTexture.rt.height, 0, 0);
|
|
m_CookieAtlas.BlitTexture(cmd, scaleBias, filteredAreaLight, sourceScaleOffset, blitMips: true, overrideInstanceID: currentID);
|
|
}
|
|
|
|
return scaleBias;
|
|
}
|
|
|
|
public Vector4 FetchAreaCookie(CommandBuffer cmd, Texture cookie, Texture ies)
|
|
{
|
|
int width = (int)Mathf.Max(cookie.width, ies.height);
|
|
int height = (int)Mathf.Max(cookie.width, ies.height);
|
|
|
|
if (width < k_MinCookieSize || height < k_MinCookieSize)
|
|
return Vector4.zero;
|
|
|
|
#if UNITY_2020_1_OR_NEWER
|
|
int projectionSize = 2 * (int)Mathf.Max((float)cookie.width, (float)ies.width);
|
|
#else
|
|
int projectionSize = 2 * (int)Mathf.Max((float)m_CookieCubeResolution, Mathf.Max((float)cookie.width, (float)ies.width));
|
|
#endif
|
|
|
|
if (!m_CookieAtlas.IsCached(out var scaleBias, cookie, ies) && !m_NoMoreSpace)
|
|
Debug.LogError($"Area Light cookie texture {cookie} & {ies} can't be fetched without having reserved. You can try to increase the cookie atlas resolution in the HDRP settings.");
|
|
|
|
if (m_CookieAtlas.NeedsUpdate(cookie, ies, true))
|
|
{
|
|
Vector4 sourceScaleOffset = new Vector4(projectionSize / (float)atlasTexture.rt.width, projectionSize / (float)atlasTexture.rt.height, 0, 0);
|
|
|
|
Texture filteredProjected = FilterAreaLightTexture(cmd, cookie, projectionSize, projectionSize);
|
|
m_CookieAtlas.BlitOctahedralTexture(cmd, scaleBias, filteredProjected, sourceScaleOffset, blitMips: true, overrideInstanceID: m_CookieAtlas.GetTextureID(cookie, ies));
|
|
filteredProjected = FilterAreaLightTexture(cmd, ies, projectionSize, projectionSize);
|
|
m_CookieAtlas.BlitOctahedralTextureMultiply(cmd, scaleBias, filteredProjected, sourceScaleOffset, blitMips: true, overrideInstanceID: m_CookieAtlas.GetTextureID(cookie, ies));
|
|
}
|
|
|
|
return scaleBias;
|
|
}
|
|
|
|
public void ReserveSpace(Texture cookieA, Texture cookieB)
|
|
{
|
|
if (cookieA == null || cookieB == null)
|
|
return;
|
|
|
|
int width = (int)Mathf.Max(cookieA.width, cookieB.height);
|
|
int height = (int)Mathf.Max(cookieA.width, cookieB.height);
|
|
|
|
if (width < k_MinCookieSize || height < k_MinCookieSize)
|
|
return;
|
|
|
|
if (!m_CookieAtlas.ReserveSpace(cookieA, cookieB, width, height))
|
|
m_2DCookieAtlasNeedsLayouting = true;
|
|
}
|
|
|
|
public void ReserveSpace(Texture cookie)
|
|
{
|
|
if (cookie == null)
|
|
return;
|
|
|
|
if (cookie.width < k_MinCookieSize || cookie.height < k_MinCookieSize)
|
|
return;
|
|
|
|
if (!m_CookieAtlas.ReserveSpace(cookie))
|
|
m_2DCookieAtlasNeedsLayouting = true;
|
|
}
|
|
|
|
public void ReserveSpaceCube(Texture cookie)
|
|
{
|
|
if (cookie == null)
|
|
return;
|
|
|
|
Debug.Assert(cookie.dimension == TextureDimension.Cube);
|
|
|
|
int projectionSize = 2 * cookie.width;
|
|
|
|
if (projectionSize < k_MinCookieSize)
|
|
return;
|
|
|
|
if (!m_CookieAtlas.ReserveSpace(cookie, projectionSize, projectionSize))
|
|
m_2DCookieAtlasNeedsLayouting = true;
|
|
}
|
|
|
|
public void ReserveSpaceCube(Texture cookieA, Texture cookieB)
|
|
{
|
|
if (cookieA == null && cookieB == null)
|
|
return;
|
|
|
|
Debug.Assert(cookieA.dimension == TextureDimension.Cube && cookieB.dimension == TextureDimension.Cube);
|
|
|
|
int projectionSize = 2 * (int)Mathf.Max(cookieA.width, cookieB.width);
|
|
|
|
if (projectionSize < k_MinCookieSize)
|
|
return;
|
|
|
|
if (!m_CookieAtlas.ReserveSpace(cookieA, cookieB, projectionSize, projectionSize))
|
|
m_2DCookieAtlasNeedsLayouting = true;
|
|
}
|
|
|
|
public Vector4 FetchCubeCookie(CommandBuffer cmd, Texture cookie)
|
|
{
|
|
Debug.Assert(cookie != null);
|
|
Debug.Assert(cookie.dimension == TextureDimension.Cube);
|
|
|
|
#if UNITY_2020_1_OR_NEWER
|
|
int projectionSize = 2 * cookie.width;
|
|
#else
|
|
int projectionSize = 2 * (int)Mathf.Max((float)m_CookieCubeResolution, (float)cookie.width);
|
|
#endif
|
|
if (projectionSize < k_MinCookieSize)
|
|
return Vector4.zero;
|
|
|
|
if (!m_CookieAtlas.IsCached(out var scaleBias, cookie) && !m_NoMoreSpace)
|
|
Debug.LogError($"Unity cannot fetch the Cube cookie texture: {cookie} because it is not on the cookie atlas. To resolve this, open your HDRP Asset and increase the resolution of the cookie atlas.");
|
|
|
|
if (m_CookieAtlas.NeedsUpdate(cookie, true))
|
|
{
|
|
Vector4 sourceScaleOffset = new Vector4(projectionSize / (float)atlasTexture.rt.width, projectionSize / (float)atlasTexture.rt.height, 0, 0);
|
|
|
|
Texture filteredProjected = FilterAreaLightTexture(cmd, cookie, projectionSize, projectionSize);
|
|
m_CookieAtlas.BlitOctahedralTexture(cmd, scaleBias, filteredProjected, sourceScaleOffset, blitMips: true, overrideInstanceID: m_CookieAtlas.GetTextureID(cookie));
|
|
}
|
|
|
|
return scaleBias;
|
|
}
|
|
|
|
public Vector4 FetchCubeCookie(CommandBuffer cmd, Texture cookie, Texture ies)
|
|
{
|
|
Debug.Assert(cookie != null);
|
|
Debug.Assert(ies != null);
|
|
Debug.Assert(cookie.dimension == TextureDimension.Cube);
|
|
Debug.Assert(ies.dimension == TextureDimension.Cube);
|
|
|
|
#if UNITY_2020_1_OR_NEWER
|
|
int projectionSize = 2 * cookie.width;
|
|
#else
|
|
int projectionSize = 2 * (int)Mathf.Max((float)m_CookieCubeResolution, (float)cookie.width);
|
|
#endif
|
|
if (projectionSize < k_MinCookieSize)
|
|
return Vector4.zero;
|
|
|
|
if (!m_CookieAtlas.IsCached(out var scaleBias, cookie, ies) && !m_NoMoreSpace)
|
|
Debug.LogError($"Unity cannot fetch the Cube cookie texture: {cookie} because it is not on the cookie atlas. To resolve this, open your HDRP Asset and increase the resolution of the cookie atlas.");
|
|
|
|
if (m_CookieAtlas.NeedsUpdate(cookie, ies, true))
|
|
{
|
|
Vector4 sourceScaleOffset = new Vector4(projectionSize / (float)atlasTexture.rt.width, projectionSize / (float)atlasTexture.rt.height, 0, 0);
|
|
|
|
Texture filteredProjected = FilterAreaLightTexture(cmd, cookie, projectionSize, projectionSize);
|
|
m_CookieAtlas.BlitOctahedralTexture(cmd, scaleBias, filteredProjected, sourceScaleOffset, blitMips: true, overrideInstanceID: m_CookieAtlas.GetTextureID(cookie, ies));
|
|
filteredProjected = FilterAreaLightTexture(cmd, ies, projectionSize, projectionSize);
|
|
m_CookieAtlas.BlitOctahedralTextureMultiply(cmd, scaleBias, filteredProjected, sourceScaleOffset, blitMips: true, overrideInstanceID: m_CookieAtlas.GetTextureID(cookie, ies));
|
|
}
|
|
|
|
return scaleBias;
|
|
}
|
|
|
|
public void ResetAllocator() => m_CookieAtlas.ResetAllocator();
|
|
|
|
public void ClearAtlasTexture(CommandBuffer cmd) => m_CookieAtlas.ClearTarget(cmd);
|
|
|
|
public RTHandle atlasTexture => m_CookieAtlas.AtlasTexture;
|
|
|
|
public PowerOfTwoTextureAtlas atlas => m_CookieAtlas;
|
|
|
|
public Vector4 GetCookieAtlasSize()
|
|
{
|
|
return new Vector4(
|
|
m_CookieAtlas.AtlasTexture.rt.width,
|
|
m_CookieAtlas.AtlasTexture.rt.height,
|
|
1.0f / m_CookieAtlas.AtlasTexture.rt.width,
|
|
1.0f / m_CookieAtlas.AtlasTexture.rt.height
|
|
);
|
|
}
|
|
|
|
public Vector4 GetCookieAtlasDatas()
|
|
{
|
|
float padding = Mathf.Pow(2.0f, m_CookieAtlas.mipPadding) * 2.0f;
|
|
return new Vector4(
|
|
m_CookieAtlas.AtlasTexture.rt.width,
|
|
padding / (float)m_CookieAtlas.AtlasTexture.rt.width,
|
|
cookieAtlasLastValidMip,
|
|
0
|
|
);
|
|
}
|
|
}
|
|
}
|