浏览代码

Reflection Probe Cache: Handled input of the wrong size/format with an additional conversion step.

/Add-support-for-light-specular-color-tint
Julien Ignace 7 年前
当前提交
8b37cbb5
共有 11 个文件被更改,包括 160 次插入35 次删除
  1. 7
      ScriptableRenderPipeline/Core/ShaderLibrary/Common.hlsl
  2. 5
      ScriptableRenderPipeline/Core/ShaderLibrary/CommonMaterial.hlsl
  3. 2
      ScriptableRenderPipeline/Core/TextureCache.cs
  4. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  5. 93
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/ReflectionProbeCache.cs
  6. 2
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  7. 7
      ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/SceneSettings.cs
  8. 2
      TestbedPipelines/Fptl/FptlLighting.cs
  9. 2
      TestbedPipelines/OnTileDeferredPipeline/OnTileDeferredRenderPipeline.cs
  10. 65
      ScriptableRenderPipeline/Core/Resources/ConvertTexture.shader
  11. 8
      ScriptableRenderPipeline/Core/Resources/ConvertTexture.shader.meta

7
ScriptableRenderPipeline/Core/ShaderLibrary/Common.hlsl


clip(ditherFactor - p);
}
// MACRO from Legacy Untiy
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex, name) ((tex.xy) * name##_ST.xy + name##_ST.zw)
#define GET_TEXELSIZE_NAME(name) (name##_TexelSize)
#endif // UNITY_COMMON_INCLUDED

5
ScriptableRenderPipeline/Core/ShaderLibrary/CommonMaterial.hlsl


return subsurfaceLighting.r > 0;
}
// MACRO from Legacy Untiy
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex, name) ((tex.xy) * name##_ST.xy + name##_ST.zw)
#define GET_TEXELSIZE_NAME(name) (name##_TexelSize)
#endif // UNITY_COMMON_MATERIAL_INCLUDED

2
ScriptableRenderPipeline/Core/TextureCache.cs


}
}
public static TextureFormat GetPreferredHdrCompressedTextureFormat
public static TextureFormat GetPreferredHDRCompressedTextureFormat
{
get
{

2
ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


void RegisterDebug()
{
// These need to be Runtime Only because those values are hold by the HDRenderPipeline asset so if user change them through the editor debug menu they might change the value in the asset without noticing it.
// These need to be Runtime Only because those values are held by the HDRenderPipeline asset so if user change them through the editor debug menu they might change the value in the asset without noticing it.
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Forward Only", () => m_Asset.renderingSettings.useForwardRenderingOnly, (value) => m_Asset.renderingSettings.useForwardRenderingOnly = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Deferred Depth Prepass", () => m_Asset.renderingSettings.useDepthPrepassWithDeferredRendering, (value) => m_Asset.renderingSettings.useDepthPrepassWithDeferredRendering = (bool)value, DebugItemFlag.RuntimeOnly);
DebugMenuManager.instance.AddDebugItem<bool>("HDRP", "Deferred Depth Prepass ATest Only", () => m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass, (value) => m_Asset.renderingSettings.renderAlphaTestOnlyInDeferredPrepass = (bool)value, DebugItemFlag.RuntimeOnly);

93
ScriptableRenderPipeline/HDRenderPipeline/Lighting/ReflectionProbeCache.cs


int m_ProbeSize;
int m_CacheSize;
TextureFormat m_CacheFormat;
RenderTexture m_TempRenderTexture2;
RenderTexture m_ConvolutionTargetTexture;
Material m_ConvertTextureMaterial;
MaterialPropertyBlock m_ConvertTextureMPB;
Debug.Assert(probeFormat == TextureFormat.BC6H || probeFormat == TextureFormat.RGBAHalf, "Reflection Probe Cache format for HDRP can only be BC6H or FP16.");
m_CacheFormat = probeFormat;
m_ProbeSize = probeSize;
m_CacheSize = cacheSize;
m_TextureCache = new TextureCacheCubemap();

m_TempRenderTexture.autoGenerateMips = false;
m_TempRenderTexture.Create();
m_TempRenderTexture2 = new RenderTexture(m_ProbeSize, m_ProbeSize, 1, RenderTextureFormat.ARGBHalf);
m_TempRenderTexture2.dimension = TextureDimension.Cube;
m_TempRenderTexture2.useMipMap = true;
m_TempRenderTexture2.autoGenerateMips = false;
m_TempRenderTexture2.Create();
m_ConvolutionTargetTexture = new RenderTexture(m_ProbeSize, m_ProbeSize, 1, RenderTextureFormat.ARGBHalf);
m_ConvolutionTargetTexture.dimension = TextureDimension.Cube;
m_ConvolutionTargetTexture.useMipMap = true;
m_ConvolutionTargetTexture.autoGenerateMips = false;
m_ConvolutionTargetTexture.Create();
m_ConvertTextureMaterial = CoreUtils.CreateEngineMaterial("Hidden/SRP/BlitCubeTextureFace");
m_ConvertTextureMPB = new MaterialPropertyBlock();
InitializeProbeBakingStates();
}

m_TextureCache.NewFrame();
}
// This method is used to convert inputs that are either compressed or not of the right size.
// We can't use Graphics.ConvertTexture here because it does not work with a RenderTexture as destination.
void ConvertTexture(CommandBuffer cmd, Texture input, RenderTexture target)
{
m_ConvertTextureMPB.SetTexture("_InputTex", input);
for (int f = 0 ; f < 6 ; ++f)
{
m_ConvertTextureMPB.SetFloat("_FaceIndex", (float)f);
CoreUtils.SetRenderTarget(cmd, target, ClearFlag.None, Color.black, 0, (CubemapFace)f);
CoreUtils.DrawFullScreen(cmd, m_ConvertTextureMaterial, m_ConvertTextureMPB);
}
}
public int FetchSlice(CommandBuffer cmd, Texture texture)
{
bool needUpdate;

Cubemap cubeTexture = texture as Cubemap;
RenderTexture renderTexture = texture as RenderTexture;
Texture convolutionSourceTexture = null;
RenderTexture convolutionTargetTexture = m_TempRenderTexture2;
RenderTexture convolutionSourceTexture = null;
// TODO: Write a shader to copy the texture, because this will not work if input is compressed.
// Ideally if input is not compressed and has mipmaps, don't do anything here. Problem is, we can't know if mips have been already convolved offline...
if (cubeTexture.format != TextureFormat.RGBAHalf)
return -1;
for (int f = 0; f < 6; f++)
// if the size if different from the cache probe size or if the input texture format is compressed, we need to convert it
// 1) to a format for which we can generate mip maps
// 2) to the proper reflection probe cache size
bool sizeMismatch = cubeTexture.width != m_ProbeSize || cubeTexture.height != m_ProbeSize;
bool formatMismatch = cubeTexture.format != TextureFormat.RGBAHalf; // Temporary RT for convolution is always FP16
if (formatMismatch || sizeMismatch)
{
if(sizeMismatch)
{
Debug.LogWarningFormat("Baked Reflection Probe {0} does not match HDRP Reflection Probe Cache size of {1}. Consider baking it at the same size for better loading performance.", texture.name, m_ProbeSize);
}
else if(cubeTexture.format == TextureFormat.BC6H)
{
Debug.LogWarningFormat("Baked Reflection Probe {0} is compressed but the HDRP Reflection Probe Cache is not. Consider removing compression from the input texture for better quality.", texture.name);
}
ConvertTexture(cmd, cubeTexture, m_TempRenderTexture);
}
else
cmd.CopyTexture(cubeTexture, f, 0, m_TempRenderTexture, f, 0);
for (int f = 0; f < 6; f++)
{
cmd.CopyTexture(cubeTexture, f, 0, m_TempRenderTexture, f, 0);
}
// Ideally if input is not compressed and has mipmaps, don't do anything here. Problem is, we can't know if mips have been already convolved offline...
cmd.GenerateMips(m_TempRenderTexture);
convolutionSourceTexture = m_TempRenderTexture;
}

cmd.GenerateMips(renderTexture);
convolutionSourceTexture = renderTexture;
if(renderTexture.dimension != TextureDimension.Cube)
{
Debug.LogError("Realtime reflection probe should always be a Cube RenderTexture.");
return -1;
}
// TODO: Do a different case for downsizing, in this case, instead of doing ConvertTexture just use the relevant mipmaps.
bool sizeMismatch = renderTexture.width != m_ProbeSize || renderTexture.height != m_ProbeSize;
if (sizeMismatch)
{
ConvertTexture(cmd, renderTexture, m_TempRenderTexture);
convolutionSourceTexture = m_TempRenderTexture;
}
else
{
convolutionSourceTexture = renderTexture;
}
// Generate unfiltered mipmaps as a base for convolution
// TODO: Make sure that we don't first convolve everything on the GPU with the legacy code path executed after rendering the probe.
cmd.GenerateMips(convolutionSourceTexture);
m_IBLFilterGGX.FilterCubemap(cmd, convolutionSourceTexture, convolutionTargetTexture);
m_TextureCache.UpdateSlice(cmd, sliceIndex, convolutionTargetTexture, m_TextureCache.GetTextureUpdateCount(texture)); // Be careful to provide the update count from the input texture, not the temporary one used for baking.
m_IBLFilterGGX.FilterCubemap(cmd, convolutionSourceTexture, m_ConvolutionTargetTexture);
m_TextureCache.UpdateSlice(cmd, sliceIndex, m_ConvolutionTargetTexture, m_TextureCache.GetTextureUpdateCount(texture)); // Be careful to provide the update count from the input texture, not the temporary one used for baking.
m_ProbeBakingState[sliceIndex] = ProbeFilteringState.Ready;
}

2
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


m_CubeCookieTexArray = new TextureCacheCubemap();
m_CubeCookieTexArray.AllocTextureArray(m_CubeCookieTexArraySize, textureSettings.pointCookieSize, TextureFormat.RGBA32, true);
m_ReflectionProbeCache = new ReflectionProbeCache(iblFilterGGX, m_ReflectionProbeCacheSize, textureSettings.reflectionCubemapSize, TextureCache.GetPreferredHdrCompressedTextureFormat, true);
m_ReflectionProbeCache = new ReflectionProbeCache(iblFilterGGX, m_ReflectionProbeCacheSize, textureSettings.reflectionCubemapSize, TextureCache.GetPreferredHDRCompressedTextureFormat, true);
s_GenAABBKernel = buildScreenAABBShader.FindKernel("ScreenBoundsAABB");

7
ScriptableRenderPipeline/HDRenderPipeline/SceneSettings/SceneSettings.cs


void OnEnable()
{
SceneSettingsManager.instance.AddSceneSettings(this);
HDRenderPipeline hdPipeline = RenderPipelineManager.currentPipeline as HDRenderPipeline;
if (hdPipeline != null)
{
hdPipeline.OnSceneLoad();
}
}
void OnDisable()

2
TestbedPipelines/Fptl/FptlLighting.cs


m_CubeReflTexArray = new TextureCacheCubemap();
m_CookieTexArray.AllocTextureArray(8, m_TextureSettings.spotCookieSize, m_TextureSettings.spotCookieSize, TextureFormat.RGBA32, true);
m_CubeCookieTexArray.AllocTextureArray(4, m_TextureSettings.pointCookieSize, TextureFormat.RGBA32, true);
m_CubeReflTexArray.AllocTextureArray(64, m_TextureSettings.reflectionCubemapSize, TextureCache.GetPreferredHdrCompressedTextureFormat, true);
m_CubeReflTexArray.AllocTextureArray(64, m_TextureSettings.reflectionCubemapSize, TextureCache.GetPreferredHDRCompressedTextureFormat, true);
//m_DeferredMaterial.SetTexture("_spotCookieTextures", m_cookieTexArray.GetTexCache());
//m_DeferredMaterial.SetTexture("_pointCookieTextures", m_cubeCookieTexArray.GetTexCache());

2
TestbedPipelines/OnTileDeferredPipeline/OnTileDeferredRenderPipeline.cs


m_CubeReflTexArray = new TextureCacheCubemap();
m_CookieTexArray.AllocTextureArray(8, m_TextureSettings.spotCookieSize, m_TextureSettings.spotCookieSize, TextureFormat.RGBA32, true);
m_CubeCookieTexArray.AllocTextureArray(4, m_TextureSettings.pointCookieSize, TextureFormat.RGBA32, true);
m_CubeReflTexArray.AllocTextureArray(64, m_TextureSettings.reflectionCubemapSize, TextureCache.GetPreferredHdrCompressedTextureFormat, true);
m_CubeReflTexArray.AllocTextureArray(64, m_TextureSettings.reflectionCubemapSize, TextureCache.GetPreferredHDRCompressedTextureFormat, true);
s_LightDataBuffer = new ComputeBuffer(k_MaxLights, System.Runtime.InteropServices.Marshal.SizeOf(typeof(SFiniteLightData)));

65
ScriptableRenderPipeline/Core/Resources/ConvertTexture.shader


Shader "Hidden/SRP/BlitCubeTextureFace"
{
SubShader
{
// Cubemap blit. Takes a face index.
Pass
{
ZTest Always
ZWrite Off
Cull Off
HLSLPROGRAM
#include "../ShaderLibrary/Common.hlsl"
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
TEXTURECUBE(_InputTex);
SAMPLERCUBE(sampler_InputTex);
float _FaceIndex;
struct Attributes
{
uint vertexID : SV_VertexID;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float3 texcoord : TEXCOORD0;
};
static const float3 faceU[6] = { float3(0, 0, -1), float3(0, 0, 1), float3(1, 0, 0), float3(1, 0, 0), float3(1, 0, 0), float3(-1, 0, 0) };
static const float3 faceV[6] = { float3(0, -1, 0), float3(0, -1, 0), float3(0, 0, 1), float3(0, 0, -1), float3(0, -1, 0), float3(0, -1, 0) };
Varyings vert (Attributes input)
{
Varyings output;
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
float2 uv = GetFullScreenTriangleTexCoord(input.vertexID);
uv = uv * 2 - 1;
int idx = (int)_FaceIndex;
float3 transformU = faceU[idx];
float3 transformV = faceV[idx];
float3 n = cross(transformV, transformU);
output.texcoord = n + uv.x * transformU + uv.y * transformV;
return output;
}
float4 frag (Varyings input) : SV_Target
{
return SAMPLE_TEXTURECUBE(_InputTex, sampler_InputTex, input.texcoord);
}
ENDHLSL
}
}
Fallback Off
}

8
ScriptableRenderPipeline/Core/Resources/ConvertTexture.shader.meta


fileFormatVersion: 2
guid: d850d0a2481878d4bbf17e5126b04163
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存