浏览代码

Merge remote-tracking branch 'refs/remotes/origin/master' into 2018.1-experimental

/main
sebastienlagarde 6 年前
当前提交
05ee75ca
共有 32 个文件被更改,包括 547 次插入523 次删除
  1. 28
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/VolumeRendering.hlsl
  2. 2
      ScriptableRenderPipeline/Core/CoreRP/Shadow/Shadow.cs
  3. 2
      ScriptableRenderPipeline/Core/CoreRP/Textures/RTHandleSystem.RTHandle.cs
  4. 31
      ScriptableRenderPipeline/Core/CoreRP/Textures/RTHandleSystem.cs
  5. 128
      ScriptableRenderPipeline/Core/CoreRP/Textures/RTHandles.cs
  6. 2
      ScriptableRenderPipeline/Core/CoreRP/Textures/TextureCache.cs
  7. 25
      ScriptableRenderPipeline/Core/CoreRP/Utilities/CoreUtils.cs
  8. 61
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs
  9. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCameraFrameHistoryType.cs
  10. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/HDCameraEditor.Handlers.cs
  11. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/HDCameraEditor.cs
  12. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/AtmosphericScattering/VolumetricFogEditor.cs
  13. 24
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  14. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs
  15. 18
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDUtils.cs
  16. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/PlanarReflectionProbeCache.cs
  17. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionProbeCache.cs
  18. 43
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionSystemInternal.cs
  19. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/SphericalHarmonics.cs
  20. 27
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VBuffer.hlsl
  21. 34
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.compute
  22. 453
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.cs
  23. 52
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLightingController.cs
  24. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/GGXConvolution/RuntimeFilterIBL.cs
  25. 13
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  26. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/PreIntegratedFGD/PreIntegratedFGD.cs
  27. 23
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.compute
  28. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl
  29. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariablesFunctions.hlsl
  30. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/AtmosphericScattering.cs
  31. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/AtmosphericScattering.hlsl
  32. 16
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/VolumetricFog.cs

28
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/VolumeRendering.hlsl


return INV_FOUR_PI;
}
real HenyeyGreensteinPhasePartConstant(real asymmetry)
real HenyeyGreensteinPhasePartConstant(real anisotropy)
real g = asymmetry;
real g = anisotropy;
real HenyeyGreensteinPhasePartVarying(real asymmetry, real cosTheta)
real HenyeyGreensteinPhasePartVarying(real anisotropy, real cosTheta)
real g = asymmetry;
real g = anisotropy;
real HenyeyGreensteinPhaseFunction(real asymmetry, real cosTheta)
real HenyeyGreensteinPhaseFunction(real anisotropy, real cosTheta)
return HenyeyGreensteinPhasePartConstant(asymmetry) *
HenyeyGreensteinPhasePartVarying(asymmetry, cosTheta);
return HenyeyGreensteinPhasePartConstant(anisotropy) *
HenyeyGreensteinPhasePartVarying(anisotropy, cosTheta);
real CornetteShanksPhasePartConstant(real asymmetry)
real CornetteShanksPhasePartConstant(real anisotropy)
real g = asymmetry;
real g = anisotropy;
real CornetteShanksPhasePartVarying(real asymmetry, real cosTheta)
real CornetteShanksPhasePartVarying(real anisotropy, real cosTheta)
real g = asymmetry;
real g = anisotropy;
real f = rsqrt(1 + g * g - 2 * g * cosTheta); // x^(-1/2)
real h = (1 + cosTheta * cosTheta);

// A better approximation of the Mie phase function.
// Ref: Henyey–Greenstein and Mie phase functions in Monte Carlo radiative transfer computations
real CornetteShanksPhaseFunction(real asymmetry, real cosTheta)
real CornetteShanksPhaseFunction(real anisotropy, real cosTheta)
return CornetteShanksPhasePartConstant(asymmetry) *
CornetteShanksPhasePartVarying(asymmetry, cosTheta);
return CornetteShanksPhasePartConstant(anisotropy) *
CornetteShanksPhasePartVarying(anisotropy, cosTheta);
}
// Samples the interval of homogeneous participating medium using the closed-form tracking approach

2
ScriptableRenderPipeline/Core/CoreRP/Shadow/Shadow.cs


m_Shadowmap.hideFlags = HideFlags.DontSaveInEditor | HideFlags.DontSaveInBuild;
m_Shadowmap.dimension = TextureDimension.Tex2DArray;
m_Shadowmap.volumeDepth = (int) m_Slices;
m_Shadowmap.name = CoreUtils.GetRenderTargetAutoName(shadowmap.width, shadowmap.height, shadowmap.format, "Shadow", mips : shadowmap.useMipMap);
m_Shadowmap.name = CoreUtils.GetRenderTargetAutoName(shadowmap.width, shadowmap.height, 1, shadowmap.format, "Shadow", mips : shadowmap.useMipMap);
m_ShadowmapId = new RenderTargetIdentifier( m_Shadowmap );
}

2
ScriptableRenderPipeline/Core/CoreRP/Textures/RTHandleSystem.RTHandle.cs


useDynamicScale = refRT.useDynamicScale,
vrUsage = refRT.vrUsage,
memorylessMode = refRT.memorylessMode,
name = CoreUtils.GetRenderTargetAutoName(refRT.width, refRT.height, refRT.format, m_Name, mips : refRT.useMipMap)
name = CoreUtils.GetRenderTargetAutoName(refRT.width, refRT.height, refRT.volumeDepth, refRT.format, m_Name, mips : refRT.useMipMap)
};
newRT.Create();

31
ScriptableRenderPipeline/Core/CoreRP/Textures/RTHandleSystem.cs


public void DemandResize(RTHandle rth)
{
Assert.IsTrue(m_ResizeOnDemandRTs.Contains(rth), string.Format("The RTHandle {0} is not an resize on demand handle in this RTHandleSystem. Please call SwitchToResizeOnDemand(rth, true) before resizing on demand.", rth));
for (int i = 0, c = (int)RTCategory.Count; i < c; ++i)
{
if (rth.m_RTs[i] == null)

rt.height = scaledSize.y;
rt.name = CoreUtils.GetRenderTargetAutoName(
rt.width,
rt.height,
rt.format,
rth.m_Name,
mips: rt.useMipMap,
enableMSAA : enableMSAA,
rt.width,
rt.height,
rt.volumeDepth,
rt.format,
rth.m_Name,
mips: rt.useMipMap,
enableMSAA : enableMSAA,
msaaSamples: m_ScaledRTCurrentMSAASamples
);
rt.Create();

{
var rth = m_AutoSizedRTsArray[i];
rth.referenceSize = maxSize;
var rt = rth.m_RTs[(int)category];
// This can happen if you create a RTH for MSAA. By default we only create the MSAA version of the target.

if (category == RTCategory.MSAA)
rt.antiAliasing = (int)m_ScaledRTCurrentMSAASamples;
rt.name = CoreUtils.GetRenderTargetAutoName(rt.width, rt.height, rt.format, rth.m_Name, mips: rt.useMipMap, enableMSAA : category == RTCategory.MSAA, msaaSamples: m_ScaledRTCurrentMSAASamples);
rt.name = CoreUtils.GetRenderTargetAutoName(rt.width, rt.height, rt.volumeDepth, rt.format, rth.m_Name, mips: rt.useMipMap, enableMSAA : category == RTCategory.MSAA, msaaSamples: m_ScaledRTCurrentMSAASamples);
rt.Create();
}
}

useDynamicScale = useDynamicScale,
vrUsage = vrUsage,
memorylessMode = memoryless,
name = CoreUtils.GetRenderTargetAutoName(width, height, colorFormat, name, mips: useMipMap, enableMSAA: enableMSAA, msaaSamples: msaaSamples)
name = CoreUtils.GetRenderTargetAutoName(width, height, slices, colorFormat, name, mips: useMipMap, enableMSAA: enableMSAA, msaaSamples: msaaSamples)
};
rt.Create();

newRT.m_Name = name;
newRT.referenceSize = new Vector2Int(width, height);
return newRT;
}

// Since MSAA cannot be changed on the fly for a given RenderTexture, a separate instance will be created if the user requires it. This instance will be the one used after the next call of SetReferenceSize if MSAA is required.
public RTHandle Alloc(
Vector2 scaleFactor,
int slices = 1,
DepthBits depthBufferBits = DepthBits.None,
RenderTextureFormat colorFormat = RenderTextureFormat.Default,
FilterMode filterMode = FilterMode.Point,

var rth = AllocAutoSizedRenderTexture(width,
height,
1,
slices,
depthBufferBits,
colorFormat,
filterMode,

//
public RTHandle Alloc(
ScaleFunc scaleFunc,
int slices = 1,
DepthBits depthBufferBits = DepthBits.None,
RenderTextureFormat colorFormat = RenderTextureFormat.Default,
FilterMode filterMode = FilterMode.Point,

var rth = AllocAutoSizedRenderTexture(width,
height,
1,
slices,
depthBufferBits,
colorFormat,
filterMode,

useDynamicScale = useDynamicScale,
vrUsage = vrUsage,
memorylessMode = memoryless,
name = CoreUtils.GetRenderTargetAutoName(width, height, colorFormat, name, mips : useMipMap, enableMSAA: allocForMSAA, msaaSamples : m_ScaledRTCurrentMSAASamples)
name = CoreUtils.GetRenderTargetAutoName(width, height, slices, colorFormat, name, mips : useMipMap, enableMSAA: allocForMSAA, msaaSamples : m_ScaledRTCurrentMSAASamples)
};
rt.Create();

128
ScriptableRenderPipeline/Core/CoreRP/Textures/RTHandles.cs


using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering

public static int maxHeight { get { return s_DefaultInstance.maxHeight; } }
public static RTHandleSystem.RTHandle Alloc(
int width,
int height,
int slices = 1,
DepthBits depthBufferBits = DepthBits.None,
RenderTextureFormat colorFormat = RenderTextureFormat.Default,
FilterMode filterMode = FilterMode.Point,
TextureWrapMode wrapMode = TextureWrapMode.Repeat,
TextureDimension dimension = TextureDimension.Tex2D,
bool sRGB = true,
bool enableRandomWrite = false,
bool useMipMap = false,
bool autoGenerateMips = true,
int anisoLevel = 1,
float mipMapBias = 0,
MSAASamples msaaSamples = MSAASamples.None,
bool bindTextureMS = false,
bool useDynamicScale = false,
VRTextureUsage vrUsage = VRTextureUsage.None,
RenderTextureMemoryless memoryless = RenderTextureMemoryless.None,
int width,
int height,
int slices = 1,
DepthBits depthBufferBits = DepthBits.None,
RenderTextureFormat colorFormat = RenderTextureFormat.Default,
FilterMode filterMode = FilterMode.Point,
TextureWrapMode wrapMode = TextureWrapMode.Repeat,
TextureDimension dimension = TextureDimension.Tex2D,
bool sRGB = true,
bool enableRandomWrite = false,
bool useMipMap = false,
bool autoGenerateMips = true,
int anisoLevel = 1,
float mipMapBias = 0,
MSAASamples msaaSamples = MSAASamples.None,
bool bindTextureMS = false,
bool useDynamicScale = false,
VRTextureUsage vrUsage = VRTextureUsage.None,
RenderTextureMemoryless memoryless = RenderTextureMemoryless.None,
string name = ""
)
{

}
public static RTHandleSystem.RTHandle Alloc(
Vector2 scaleFactor,
DepthBits depthBufferBits = DepthBits.None,
RenderTextureFormat colorFormat = RenderTextureFormat.Default,
FilterMode filterMode = FilterMode.Point,
TextureWrapMode wrapMode = TextureWrapMode.Repeat,
TextureDimension dimension = TextureDimension.Tex2D,
bool sRGB = true,
bool enableRandomWrite = false,
bool useMipMap = false,
bool autoGenerateMips = true,
int anisoLevel = 1,
float mipMapBias = 0,
bool enableMSAA = false,
bool bindTextureMS = false,
bool useDynamicScale = false,
VRTextureUsage vrUsage = VRTextureUsage.None,
RenderTextureMemoryless memoryless = RenderTextureMemoryless.None,
Vector2 scaleFactor,
int slices = 1,
DepthBits depthBufferBits = DepthBits.None,
RenderTextureFormat colorFormat = RenderTextureFormat.Default,
FilterMode filterMode = FilterMode.Point,
TextureWrapMode wrapMode = TextureWrapMode.Repeat,
TextureDimension dimension = TextureDimension.Tex2D,
bool sRGB = true,
bool enableRandomWrite = false,
bool useMipMap = false,
bool autoGenerateMips = true,
int anisoLevel = 1,
float mipMapBias = 0,
bool enableMSAA = false,
bool bindTextureMS = false,
bool useDynamicScale = false,
VRTextureUsage vrUsage = VRTextureUsage.None,
RenderTextureMemoryless memoryless = RenderTextureMemoryless.None,
slices,
depthBufferBits,
colorFormat,
filterMode,

}
public static RTHandleSystem.RTHandle Alloc(
ScaleFunc scaleFunc,
DepthBits depthBufferBits = DepthBits.None,
RenderTextureFormat colorFormat = RenderTextureFormat.Default,
FilterMode filterMode = FilterMode.Point,
TextureWrapMode wrapMode = TextureWrapMode.Repeat,
TextureDimension dimension = TextureDimension.Tex2D,
bool sRGB = true,
bool enableRandomWrite = false,
ScaleFunc scaleFunc,
int slices = 1,
DepthBits depthBufferBits = DepthBits.None,
RenderTextureFormat colorFormat = RenderTextureFormat.Default,
FilterMode filterMode = FilterMode.Point,
TextureWrapMode wrapMode = TextureWrapMode.Repeat,
TextureDimension dimension = TextureDimension.Tex2D,
bool sRGB = true,
bool enableRandomWrite = false,
bool autoGenerateMips = true,
int anisoLevel = 1,
float mipMapBias = 0,
bool enableMSAA = false,
bool bindTextureMS = false,
bool useDynamicScale = false,
VRTextureUsage vrUsage = VRTextureUsage.None,
RenderTextureMemoryless memoryless = RenderTextureMemoryless.None,
bool autoGenerateMips = true,
int anisoLevel = 1,
float mipMapBias = 0,
bool enableMSAA = false,
bool bindTextureMS = false,
bool useDynamicScale = false,
VRTextureUsage vrUsage = VRTextureUsage.None,
RenderTextureMemoryless memoryless = RenderTextureMemoryless.None,
slices,
depthBufferBits,
colorFormat,
filterMode,

}
public static void Initialize(
int width,
int height,
bool scaledRTsupportsMSAA,
int width,
int height,
bool scaledRTsupportsMSAA,
MSAASamples scaledRTMSAASamples
)
{

}
public static void ResetReferenceSize(
int width,
int height,
bool msaa,
int width,
int height,
bool msaa,
MSAASamples msaaSamples
)
{

}
public static void SetReferenceSize(
int width,
int height,
bool msaa,
int width,
int height,
bool msaa,
MSAASamples msaaSamples
)
{

2
ScriptableRenderPipeline/Core/CoreRP/Textures/TextureCache.cs


for (int m = 0; m < m_NumPanoMipLevels; m++)
{
m_StagingRTs[m] = new RenderTexture(Mathf.Max(1, panoWidthTop >> m), Mathf.Max(1, panoHeightTop >> m), 0, RenderTextureFormat.ARGBHalf) { hideFlags = HideFlags.HideAndDontSave };
m_StagingRTs[m].name = CoreUtils.GetRenderTargetAutoName(Mathf.Max(1, panoWidthTop >> m), Mathf.Max(1, panoHeightTop >> m), RenderTextureFormat.ARGBHalf, String.Format("PanaCache{0}", m));
m_StagingRTs[m].name = CoreUtils.GetRenderTargetAutoName(Mathf.Max(1, panoWidthTop >> m), Mathf.Max(1, panoHeightTop >> m), 1, RenderTextureFormat.ARGBHalf, String.Format("PanaCache{0}", m));
}
if (m_CubeBlitMaterial)

25
ScriptableRenderPipeline/Core/CoreRP/Utilities/CoreUtils.cs


ClearRenderTarget(cmd, clearFlag, clearColor);
}
public static string GetRenderTargetAutoName(int width, int height, RenderTextureFormat format, string name = "", bool mips = false, bool enableMSAA = false, MSAASamples msaaSamples = MSAASamples.None)
public static string GetRenderTargetAutoName(int width, int height, int depth, RenderTextureFormat format, string name, bool mips = false, bool enableMSAA = false, MSAASamples msaaSamples = MSAASamples.None)
string temp;
string result = string.Format("{0}_{1}x{2}", name, width, height);
if (depth > 1)
result = string.Format("{0}x{1}", result, depth);
if (mips)
result = string.Format("{0}_{1}", result, "Mips");
result = string.Format("{0}_{1}", result, format);
temp = string.Format("{0}x{1}_{2}{3}_{4}", width, height, format, mips ? "_Mips" : "", msaaSamples.ToString());
else
temp = string.Format("{0}x{1}_{2}{3}", width, height, format, mips ? "_Mips" : "");
temp = String.Format("{0}_{1}", name == "" ? "RenderTarget" : name, temp);
result = string.Format("{0}_{1}", result, msaaSamples.ToString());
return temp;
return result;
}
public static string GetTextureAutoName(int width, int height, TextureFormat format, TextureDimension dim = TextureDimension.None, string name = "", bool mips = false, int depth = 0)

temp = string.Format("{0}x{1}_{2}{3}", width, height, format, mips ? "_Mips" : "");
temp = string.Format("{0}x{1}{2}_{3}", width, height, mips ? "_Mips" : "", format);
temp = string.Format("{0}x{1}x{2}_{3}{4}", width, height, depth, format, mips ? "_Mips" : "");
temp = string.Format("{0}x{1}x{2}{3}_{4}", width, height, depth, mips ? "_Mips" : "", format);
temp = String.Format("{0}_{1}_{2}", name == "" ? "Texture" : name, (dim == TextureDimension.None) ? "" : dim.ToString(), temp);
return temp;

61
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs


public Vector4 projectionParams;
public Vector4 screenParams;
public VolumetricLightingSystem.VBufferParameters[] vBufferParams; // Double-buffered
public PostProcessRenderContext postprocessRenderContext;
public Matrix4x4[] viewMatrixStereo;

// This is the size actually used for this camera (as it can be altered by VR for example)
int m_ActualWidth;
int m_ActualHeight;
// This is the scale and bias of the camera viewport compared to the reference size of our Render Targets (RHandle.maxSize)
Vector2 m_CameraScaleBias;
// This is the scale of the camera viewport compared to the reference size of our Render Targets (RTHandle.maxSize)
Vector2 m_ViewportScaleCurrentFrame;
Vector2 m_ViewportScalePreviousFrame;
public Vector2 scaleBias { get { return m_CameraScaleBias; } }
public Vector2 viewportScale { get { return m_ViewportScaleCurrentFrame; } }
public Vector4 doubleBufferedViewportScale { get { return new Vector4(m_ViewportScaleCurrentFrame.x, m_ViewportScaleCurrentFrame.y, m_ViewportScalePreviousFrame.x, m_ViewportScalePreviousFrame.y); } }
public MSAASamples msaaSamples { get { return m_msaaSamples; } }
public Matrix4x4 viewProjMatrix

projMatrixStereo = new Matrix4x4[2];
postprocessRenderContext = new PostProcessRenderContext();
public void Update(PostProcessLayer postProcessLayer, FrameSettings frameSettings)
// Pass all the systems that may want to update per-camera data here.
// That way you will never update an HDCamera and forget to update the dependent system.
public void Update(PostProcessLayer postProcessLayer, FrameSettings frameSettings, VolumetricLightingSystem vlSys)
{
// If TAA is enabled projMatrix will hold a jittered projection matrix. The original,
// non-jittered projection matrix can be accessed via nonJitteredProjMatrix.

int maxWidth = RTHandles.maxWidth;
int maxHeight = RTHandles.maxHeight;
m_CameraScaleBias.x = (float)m_ActualWidth / maxWidth;
m_CameraScaleBias.y = (float)m_ActualHeight / maxHeight;
m_ViewportScalePreviousFrame = m_ViewportScaleCurrentFrame; // Double-buffer
m_ViewportScaleCurrentFrame.x = (float)m_ActualWidth / maxWidth;
m_ViewportScaleCurrentFrame.y = (float)m_ActualHeight / maxHeight;
if (vlSys != null)
{
vlSys.UpdatePerCameraData(this);
}
}
// Stopgap method used to extract stereo combined matrix state.

isFirstFrame = true;
}
// Grab the HDCamera tied to a given Camera and update it.
public static HDCamera Get(Camera camera, PostProcessLayer postProcessLayer, FrameSettings frameSettings)
// Will return NULL if the camera does not exist.
public static HDCamera Get(Camera camera)
{
HDCamera hdCamera;
if (!s_Cameras.TryGetValue(camera, out hdCamera))
{
hdCamera = null;
}
return hdCamera;
}
// Pass all the systems that may want to initialize per-camera data here.
// That way you will never create an HDCamera and forget to initialize the data.
public static HDCamera Create(Camera camera, VolumetricLightingSystem vlSys)
HDCamera hdcam;
HDCamera hdCamera = new HDCamera(camera);
s_Cameras.Add(camera, hdCamera);
if (!s_Cameras.TryGetValue(camera, out hdcam))
if (vlSys != null)
hdcam = new HDCamera(camera);
s_Cameras.Add(camera, hdcam);
// Have to perform a NULL check here because the Reflection System internally allocates HDCameras.
vlSys.InitializePerCameraData(hdCamera);
hdcam.Update(postProcessLayer, frameSettings);
return hdcam;
return hdCamera;
}
public static void ClearAll()

cmd.SetGlobalVector(HDShaderIDs._WorldSpaceCameraPos, worldSpaceCameraPos);
cmd.SetGlobalFloat( HDShaderIDs._DetViewMatrix, detViewMatrix);
cmd.SetGlobalVector(HDShaderIDs._ScreenSize, screenSize);
cmd.SetGlobalVector(HDShaderIDs._ScreenToTargetScale, scaleBias);
cmd.SetGlobalVector(HDShaderIDs._ScreenToTargetScale, doubleBufferedViewportScale);
cmd.SetGlobalVector(HDShaderIDs._ZBufferParams, zBufferParams);
cmd.SetGlobalVector(HDShaderIDs._ProjectionParams, projectionParams);
cmd.SetGlobalVector(HDShaderIDs.unity_OrthoParams, unity_OrthoParams);

// Allocate buffers frames and return current frame
public RTHandleSystem.RTHandle AllocHistoryFrameRT(int id, Func<string, int, RTHandleSystem, RTHandleSystem.RTHandle> allocator)
{
m_HistoryRTSystem.AllocBuffer(id, (rts, i) => allocator(camera.name, i, rts), 2);
const int bufferCount = 2; // Hard-coded for now. Will have to see if this is enough...
m_HistoryRTSystem.AllocBuffer(id, (rts, i) => allocator(camera.name, i, rts), bufferCount);
return m_HistoryRTSystem.GetFrameRT(id, 0);
}

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCameraFrameHistoryType.cs


{
public enum HDCameraFrameHistoryType
{
DepthPyramid,
ColorPyramid
DepthPyramid = 0,
ColorPyramid = 1,
VolumetricLighting = 2,
Count = 3 // Keep this last
}
}

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/HDCameraEditor.Handlers.cs


using System;
using System;
using System.Reflection;
using UnityEngine;
using UnityEngine.Experimental.Rendering;

// And then to copy the runtime frame settings
// So this includes the runtime frame settings properly
cameraData.GetFrameSettings().CopyTo(m_PreviewAdditionalCameraData.GetFrameSettings());
m_PreviewHDCamera.Update(m_PreviewPostProcessLayer, m_PreviewAdditionalCameraData.GetFrameSettings());
m_PreviewHDCamera.Update(m_PreviewPostProcessLayer, m_PreviewAdditionalCameraData.GetFrameSettings(), null);
var previewTexture = GetPreviewTextureWithSize((int)previewSize.x, (int)previewSize.y);
m_PreviewCamera.targetTexture = previewTexture;

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Camera/HDCameraEditor.cs


m_PreviewAdditionalCameraData = m_PreviewCamera.gameObject.AddComponent<HDAdditionalCameraData>();
m_PreviewPostProcessLayer = m_PreviewCamera.gameObject.AddComponent<PostProcessLayer>();
m_PreviewHDCamera = new HDCamera(m_PreviewCamera);
m_PreviewHDCamera.Update(m_PreviewPostProcessLayer, m_PreviewAdditionalCameraData.GetFrameSettings());
m_PreviewHDCamera.Update(m_PreviewPostProcessLayer, m_PreviewAdditionalCameraData.GetFrameSettings(), null);
}
void OnDisable()

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Sky/AtmosphericScattering/VolumetricFogEditor.cs


{
private SerializedDataParameter m_Albedo;
private SerializedDataParameter m_MeanFreePath;
private SerializedDataParameter m_Asymmetry;
private SerializedDataParameter m_Anisotropy;
public override void OnEnable()
{

m_Albedo = Unpack(o.Find(x => x.albedo));
m_MeanFreePath = Unpack(o.Find(x => x.meanFreePath));
m_Asymmetry = Unpack(o.Find(x => x.asymmetry));
m_Anisotropy = Unpack(o.Find(x => x.anisotropy));
}
public override void OnInspectorGUI()

PropertyField(m_Asymmetry);
PropertyField(m_Anisotropy);
}
}
}

24
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


}
m_Asset = asset;
// Initial state of the RTHandle system.
// Tells the system that we will require MSAA or not so that we can avoid wasteful render texture allocation.
// TODO: Might want to initialize to at least the window resolution to avoid un-necessary re-alloc in the player
RTHandles.Initialize(1, 1, m_Asset.renderPipelineSettings.supportMSAA, m_Asset.renderPipelineSettings.msaaSampleCount);
var bufferPyramidProcessor = new BufferPyramidProcessor(
asset.renderPipelineResources.colorPyramidCS,
asset.renderPipelineResources.depthPyramidCS,

void InitializeRenderTextures()
{
// Initial state of the RTHandle system.
// Tells the system that we will require MSAA or not so that we can avoid wasteful render texture allocation.
// TODO: Might want to initialize to at least the window resolution to avoid un-necessary re-alloc in the player
RTHandles.Initialize(1, 1, m_Asset.renderPipelineSettings.supportMSAA, m_Asset.renderPipelineSettings.msaaSampleCount);
if(!m_Asset.renderPipelineSettings.supportForwardOnly)
m_GbufferManager.CreateBuffers();

m_LightLoop.AllocResolutionDependentBuffers((int)hdCamera.screenSize.x, (int)hdCamera.screenSize.y, m_FrameSettings.enableStereo);
}
// Warning: (resolutionChanged == false) if you open a new Editor tab of the same size!
m_VolumetricLightingSystem.ResizeVBufferAndUpdateProperties(hdCamera, m_FrameCount);
// update recorded window resolution
m_CurrentWidth = hdCamera.actualWidth;
m_CurrentHeight = hdCamera.actualHeight;

m_FrameSettings.enablePostprocess = false;
}
var hdCamera = HDCamera.Get(camera, postProcessLayer, m_FrameSettings);
var hdCamera = HDCamera.Get(camera);
if (hdCamera == null)
{
hdCamera = HDCamera.Create(camera, m_VolumetricLightingSystem);
}
hdCamera.Update(postProcessLayer, m_FrameSettings, m_VolumetricLightingSystem);
Resize(hdCamera);

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs


public static readonly int _AmbientProbeCoeffs = Shader.PropertyToID("_AmbientProbeCoeffs");
public static readonly int _GlobalExtinction = Shader.PropertyToID("_GlobalExtinction");
public static readonly int _GlobalScattering = Shader.PropertyToID("_GlobalScattering");
public static readonly int _GlobalAsymmetry = Shader.PropertyToID("_GlobalAsymmetry");
public static readonly int _GlobalAnisotropy = Shader.PropertyToID("_GlobalAnisotropy");
public static readonly int _VBufferUvScaleAndLimit = Shader.PropertyToID("_VBufferUvScaleAndLimit");
public static readonly int _VBufferPrevUvScaleAndLimit = Shader.PropertyToID("_VBufferPrevUvScaleAndLimit");
public static readonly int _VBufferPrevDepthEncodingParams = Shader.PropertyToID("_VBufferPrevDepthEncodingParams");
public static readonly int _VBufferPrevDepthDecodingParams = Shader.PropertyToID("_VBufferPrevDepthDecodingParams");
public static readonly int _VBufferCoordToViewDirWS = Shader.PropertyToID("_VBufferCoordToViewDirWS");

18
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDUtils.cs


{
// Will set the correct camera viewport as well.
SetRenderTarget(cmd, camera, destination);
BlitTexture(cmd, source, destination, camera.scaleBias, mipLevel, bilinear);
BlitTexture(cmd, source, destination, camera.viewportScale, mipLevel, bilinear);
}
// This case, both source and destination are camera-scaled but we want to override the scale/bias parameter.

{
SetRenderTarget(cmd, camera, destination);
cmd.SetViewport(destViewport);
BlitTexture(cmd, source, destination, camera.scaleBias, mipLevel, bilinear);
BlitTexture(cmd, source, destination, camera.viewportScale, mipLevel, bilinear);
cmd.Blit(source, destination, new Vector2(camera.scaleBias.x, camera.scaleBias.y), Vector2.zero);
cmd.Blit(source, destination, new Vector2(camera.viewportScale.x, camera.viewportScale.y), Vector2.zero);
}
// This particular case is for blitting a non-scaled texture into a scaled texture. So we setup the partial viewport but don't scale the input UVs.

MaterialPropertyBlock properties = null, int shaderPassId = 0)
{
HDUtils.SetRenderTarget(commandBuffer, camera, colorBuffer);
commandBuffer.SetGlobalVector(HDShaderIDs._ScreenToTargetScale, camera.scaleBias);
commandBuffer.SetGlobalVector(HDShaderIDs._ScreenToTargetScale, camera.doubleBufferedViewportScale);
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties);
}

{
HDUtils.SetRenderTarget(commandBuffer, camera, colorBuffer, depthStencilBuffer);
commandBuffer.SetGlobalVector(HDShaderIDs._ScreenToTargetScale, camera.scaleBias);
commandBuffer.SetGlobalVector(HDShaderIDs._ScreenToTargetScale, camera.doubleBufferedViewportScale);
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties);
}

{
HDUtils.SetRenderTarget(commandBuffer, camera, colorBuffers, depthStencilBuffer);
commandBuffer.SetGlobalVector(HDShaderIDs._ScreenToTargetScale, camera.scaleBias);
commandBuffer.SetGlobalVector(HDShaderIDs._ScreenToTargetScale, camera.doubleBufferedViewportScale);
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties);
}

{
CoreUtils.SetRenderTarget(commandBuffer, colorBuffer);
commandBuffer.SetGlobalVector(HDShaderIDs._ScreenToTargetScale, camera.scaleBias);
commandBuffer.SetGlobalVector(HDShaderIDs._ScreenToTargetScale, camera.doubleBufferedViewportScale);
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties);
}

Vector2 mousePixelCoord = MousePositionDebug.instance.GetMousePosition(camera.screenSize.y);
return new Vector4(mousePixelCoord.x, mousePixelCoord.y, camera.scaleBias.x * mousePixelCoord.x / camera.screenSize.x, camera.scaleBias.y * mousePixelCoord.y / camera.screenSize.y);
return new Vector4(mousePixelCoord.x, mousePixelCoord.y, camera.viewportScale.x * mousePixelCoord.x / camera.screenSize.x, camera.viewportScale.y * mousePixelCoord.y / camera.screenSize.y);
}
// Returns mouse click coordinates: (x,y) in pixels and (z,w) normalized inside the render target (not the viewport)

return new Vector4(mousePixelCoord.x, mousePixelCoord.y, camera.scaleBias.x * mousePixelCoord.x / camera.screenSize.x, camera.scaleBias.y * mousePixelCoord.y / camera.screenSize.y);
return new Vector4(mousePixelCoord.x, mousePixelCoord.y, camera.viewportScale.x * mousePixelCoord.x / camera.screenSize.x, camera.viewportScale.y * mousePixelCoord.y / camera.screenSize.y);
}
}
}

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/PlanarReflectionProbeCache.cs


using System;
using System;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline

m_TempRenderTexture.dimension = TextureDimension.Tex2D;
m_TempRenderTexture.useMipMap = true;
m_TempRenderTexture.autoGenerateMips = false;
m_TempRenderTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, RenderTextureFormat.ARGBHalf, "PlanarReflectionTemp", mips : true);
m_TempRenderTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, 1, RenderTextureFormat.ARGBHalf, "PlanarReflectionTemp", mips : true);
m_TempRenderTexture.Create();
m_ConvolutionTargetTexture = new RenderTexture(m_ProbeSize, m_ProbeSize, 1, RenderTextureFormat.ARGBHalf);

m_ConvolutionTargetTexture.autoGenerateMips = false;
m_ConvolutionTargetTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, RenderTextureFormat.ARGBHalf, "PlanarReflectionConvolution", mips: true);
m_ConvolutionTargetTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, 1, RenderTextureFormat.ARGBHalf, "PlanarReflectionConvolution", mips: true);
m_ConvolutionTargetTexture.Create();
InitializeProbeBakingStates();

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionProbeCache.cs


using System;
using System;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline

m_TempRenderTexture.dimension = TextureDimension.Cube;
m_TempRenderTexture.useMipMap = true;
m_TempRenderTexture.autoGenerateMips = false;
m_TempRenderTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, RenderTextureFormat.ARGBHalf, "ReflectionProbeTemp", mips : true);
m_TempRenderTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, 1, RenderTextureFormat.ARGBHalf, "ReflectionProbeTemp", mips : true);
m_TempRenderTexture.Create();
m_ConvolutionTargetTexture = new RenderTexture(m_ProbeSize, m_ProbeSize, 1, RenderTextureFormat.ARGBHalf);

m_ConvolutionTargetTexture.autoGenerateMips = false;
m_ConvolutionTargetTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, RenderTextureFormat.ARGBHalf, "ReflectionProbeConvolution", mips : true);
m_ConvolutionTargetTexture.name = CoreUtils.GetRenderTargetAutoName(m_ProbeSize, m_ProbeSize, 1, RenderTextureFormat.ARGBHalf, "ReflectionProbeConvolution", mips : true);
m_ConvolutionTargetTexture.Create();
InitializeProbeBakingStates();

43
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ReflectionSystemInternal.cs


using System;
using System;
using System.Collections.Generic;
using UnityEngine.Rendering;

for (var i = 0; i < length; i++)
{
var probe = m_PlanarReflectionProbe_RealtimeUpdate_WorkArray[i];
var hdCamera = HDCamera.Get(renderCamera, null, probe.frameSettings);
var hdCamera = HDCamera.Get(renderCamera);
if (hdCamera == null)
{
// Warning: this is a bad design pattern.
// An individual system should not create an HDCamera (which is a shared resource).
hdCamera = HDCamera.Create(renderCamera, null);
}
hdCamera.Update(null, probe.frameSettings, null);
if (!IsRealtimeTextureValid(probe.realtimeTexture, hdCamera))
{
if (probe.realtimeTexture != null)

for (var i = 0; i < length; i++)
{
var probe = m_PlanarReflectionProbe_RealtimeUpdate_WorkArray[i];
var hdCamera = HDCamera.Get(camera, null, probe.frameSettings);
var hdCamera = HDCamera.Get(camera);
if (hdCamera == null)
{
// Warning: this is a bad design pattern.
// An individual system should not create an HDCamera (which is a shared resource).
hdCamera = HDCamera.Create(camera, null);
}
hdCamera.Update(null, probe.frameSettings, null);
if (!IsRealtimeTextureValid(probe.realtimeTexture, hdCamera))
{
if (probe.realtimeTexture != null)

// No hide and don't save for this one
rt.useMipMap = true;
rt.autoGenerateMips = false;
rt.name = CoreUtils.GetRenderTargetAutoName(m_Parameters.planarReflectionProbeSize, m_Parameters.planarReflectionProbeSize, RenderTextureFormat.ARGBHalf, "PlanarProbeRT");
rt.name = CoreUtils.GetRenderTargetAutoName(m_Parameters.planarReflectionProbeSize, m_Parameters.planarReflectionProbeSize, 1, RenderTextureFormat.ARGBHalf, "PlanarProbeRT");
rt.Create();
return rt;
}

probe.frameSettings.CopyTo(s_RenderCameraData.GetFrameSettings());
return HDCamera.Get(camera, null, probe.frameSettings);
var hdCamera = HDCamera.Get(camera);
if (hdCamera == null)
{
// Warning: this is a bad design pattern.
// An individual system should not create an HDCamera (which is a shared resource).
hdCamera = HDCamera.Create(camera, null);
}
hdCamera.Update(null, probe.frameSettings, null);
return hdCamera;
}
static Camera GetRenderCamera()

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/SphericalHarmonics.cs


{
public float[] coeffs; // Must have the size of 3
public static ZonalHarmonicsL2 GetHenyeyGreensteinPhaseFunction(float asymmetry)
public static ZonalHarmonicsL2 GetHenyeyGreensteinPhaseFunction(float anisotropy)
float g = asymmetry;
float g = anisotropy;
var zh = new ZonalHarmonicsL2();
zh.coeffs = new float[3];

return zh;
}
public static ZonalHarmonicsL2 GetCornetteShanksPhaseFunction(float asymmetry)
public static ZonalHarmonicsL2 GetCornetteShanksPhaseFunction(float anisotropy)
float g = asymmetry;
float g = anisotropy;
var zh = new ZonalHarmonicsL2();
zh.coeffs = new float[3];

27
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VBuffer.hlsl


// Compute the linear interpolation weight.
float t = saturate((z - z0) / (z1 - z0));
// Do not saturate here, we want to know whether we are outside of the near/far plane bounds.
return d0 + t * rcpNumSlices;
}

float linearDepth,
float4 VBufferResolution,
float2 VBufferSliceCount,
float2 VBufferUvScale,
float2 VBufferUvLimit,
float4 VBufferDepthEncodingParams,
float4 VBufferDepthDecodingParams,
bool correctLinearInterpolation,

if (clampToBorder)
{
// Compute the distance to the edge, and remap it to the [0, 1] range.
// TODO: add support for the HW border clamp sampler.
// Smoothly fade from the center of the edge texel to the black border color.
float weightU = saturate((1 - 2 * abs(uv.x - 0.5)) * VBufferResolution.x);
float weightV = saturate((1 - 2 * abs(uv.y - 0.5)) * VBufferResolution.y);
float weightW = saturate((1 - 2 * abs(w - 0.5)) * VBufferSliceCount.x);

float2 weights[2], offsets[2];
BiquadraticFilter(1 - fc, weights, offsets); // Inverse-translate the filter centered around 0.5
result = (weights[0].x * weights[0].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3((ic + float2(offsets[0].x, offsets[0].y)) * VBufferResolution.zw, w), 0) // Top left
+ (weights[1].x * weights[0].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3((ic + float2(offsets[1].x, offsets[0].y)) * VBufferResolution.zw, w), 0) // Top right
+ (weights[0].x * weights[1].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3((ic + float2(offsets[0].x, offsets[1].y)) * VBufferResolution.zw, w), 0) // Bottom left
+ (weights[1].x * weights[1].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3((ic + float2(offsets[1].x, offsets[1].y)) * VBufferResolution.zw, w), 0); // Bottom right
// Apply the viewport scale right at the end.
// TODO: precompute (VBufferResolution.zw * VBufferUvScale).
result = (weights[0].x * weights[0].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3(min((ic + float2(offsets[0].x, offsets[0].y)) * (VBufferResolution.zw * VBufferUvScale), VBufferUvLimit), w), 0) // Top left
+ (weights[1].x * weights[0].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3(min((ic + float2(offsets[1].x, offsets[0].y)) * (VBufferResolution.zw * VBufferUvScale), VBufferUvLimit), w), 0) // Top right
+ (weights[0].x * weights[1].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3(min((ic + float2(offsets[0].x, offsets[1].y)) * (VBufferResolution.zw * VBufferUvScale), VBufferUvLimit), w), 0) // Bottom left
+ (weights[1].x * weights[1].y) * SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3(min((ic + float2(offsets[1].x, offsets[1].y)) * (VBufferResolution.zw * VBufferUvScale), VBufferUvLimit), w), 0); // Bottom right
result = SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3(uv, w), 0);
// Apply the viewport scale right at the end.
result = SAMPLE_TEXTURE3D_LOD(VBuffer, clampSampler, float3(min(uv * VBufferUvScale, VBufferUvLimit), w), 0);
}
result *= fadeWeight;

float4x4 viewProjMatrix,
float4 VBufferResolution,
float2 VBufferSliceCount,
float2 VBufferUvScale,
float2 VBufferUvLimit,
float4 VBufferDepthEncodingParams,
float4 VBufferDepthDecodingParams,
bool correctLinearInterpolation,

linearDepth,
VBufferResolution,
VBufferSliceCount,
VBufferUvScale,
VBufferUvLimit,
VBufferDepthEncodingParams,
VBufferDepthDecodingParams,
correctLinearInterpolation,

float linearDepth,
float4 VBufferResolution,
float2 VBufferSliceCount,
float2 VBufferUvScale,
float2 VBufferUvLimit,
float4 VBufferDepthEncodingParams,
float4 VBufferDepthDecodingParams,
bool correctLinearInterpolation,

linearDepth,
VBufferResolution,
VBufferSliceCount,
VBufferUvScale,
VBufferUvLimit,
VBufferDepthEncodingParams,
VBufferDepthDecodingParams,
correctLinearInterpolation,

34
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.compute


// Computes the light integral (in-scattered radiance) within the voxel.
// Multiplication by the scattering coefficient and the phase function is performed outside.
VoxelLighting EvaluateVoxelLighting(LightLoopContext context, uint featureFlags, PositionInputs posInput, float3 centerWS,
DualRay ray, float t0, float t1, float dt, float rndVal, float extinction, float asymmetry
DualRay ray, float t0, float t1, float dt, float rndVal, float extinction, float anisotropy
#ifdef USE_CLUSTERED_LIGHTLIST
, uint lightClusters[2])
#else

// function) is not possible. We work around this issue by reprojecting
// lighting not affected by the phase function. This basically removes
// the phase function from the temporal integration process. It is a hack.
// The downside is that asymmetry no longer benefits from temporal averaging,
// and any temporal instability of asymmetry causes causes visible jitter.
// The downside is that anisotropy no longer benefits from temporal averaging,
// and any temporal instability of anisotropy causes causes visible jitter.
// asymmetry-related calculations.
// anisotropy-related calculations.
float phase = CornetteShanksPhasePartVarying(asymmetry, cosTheta);
float phase = CornetteShanksPhasePartVarying(anisotropy, cosTheta);
// Note: the 'weight' accounts for transmittance from 't0' to 't'.
float intensity = attenuation * weight;

// function) is not possible. We work around this issue by reprojecting
// lighting not affected by the phase function. This basically removes
// the phase function from the temporal integration process. It is a hack.
// The downside is that asymmetry no longer benefits from temporal averaging,
// and any temporal instability of asymmetry causes causes visible jitter.
// The downside is that anisotropy no longer benefits from temporal averaging,
// and any temporal instability of anisotropy causes causes visible jitter.
// asymmetry-related calculations.
// anisotropy-related calculations.
float phase = CornetteShanksPhasePartVarying(asymmetry, cosTheta);
float phase = CornetteShanksPhasePartVarying(anisotropy, cosTheta);
float intensity = attenuation * rcpPdf;

// function) is not possible. We work around this issue by reprojecting
// lighting not affected by the phase function. This basically removes
// the phase function from the temporal integration process. It is a hack.
// The downside is that asymmetry no longer benefits from temporal averaging,
// and any temporal instability of asymmetry causes causes visible jitter.
// The downside is that anisotropy no longer benefits from temporal averaging,
// and any temporal instability of anisotropy causes causes visible jitter.
// asymmetry-related calculations.
float3 centerL = light.positionWS - centerWS;
// anisotropy-related calculations.
float3 centerL = light.positionWS - centerWS;
float phase = CornetteShanksPhasePartVarying(asymmetry, cosTheta);
float phase = CornetteShanksPhasePartVarying(anisotropy, cosTheta);
// Note: the 'weight' accounts for transmittance from 'tEntr' to 't'.
float intensity = attenuation * weight;

// TODO: piecewise linear.
float3 scattering = LOAD_TEXTURE3D(_VBufferDensity, voxelCoord).rgb;
float extinction = LOAD_TEXTURE3D(_VBufferDensity, voxelCoord).a;
float asymmetry = _GlobalAsymmetry;
float anisotropy = _GlobalAnisotropy;
// Prevent division by 0.
extinction = max(extinction, FLT_MIN);

#endif
VoxelLighting lighting = EvaluateVoxelLighting(context, featureFlags, posInput, centerWS,
ray, t0, t1, dt, rndVal, extinction, asymmetry
ray, t0, t1, dt, rndVal, extinction, anisotropy
#ifdef USE_CLUSTERED_LIGHTLIST
, lightClusters);
#else

_PrevViewProjMatrix,
_VBufferPrevResolution,
_VBufferPrevSliceCount.xy,
_VBufferPrevUvScaleAndLimit.xy,
_VBufferPrevUvScaleAndLimit.zw,
_VBufferPrevDepthEncodingParams,
_VBufferPrevDepthDecodingParams,
false, false, true);

453
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLighting.cs


using System;
using UnityEngine.Rendering;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{

Count
} // enum VolumetricLightingPreset
[Serializable]
public struct ControllerParameters
{
public float vBufferNearPlane; // Distance in meters
public float vBufferFarPlane; // Distance in meters
public float depthSliceDistributionUniformity; // Controls the exponential depth distribution: [0, 1]
} // struct ControllerParameters
public class VBuffer
public struct VBufferParameters
public struct Parameters
{
public Vector4 resolution;
public Vector2 sliceCount;
public Vector4 depthEncodingParams;
public Vector4 depthDecodingParams;
public Parameters(int w, int h, int d, ControllerParameters controlParams)
{
resolution = new Vector4(w, h, 1.0f / w, 1.0f / h);
sliceCount = new Vector2(d, 1.0f / d);
depthEncodingParams = Vector4.zero; // C# doesn't allow function calls before all members have been init
depthDecodingParams = Vector4.zero; // C# doesn't allow function calls before all members have been init
Update(controlParams);
}
public void Update(ControllerParameters controlParams)
{
float n = controlParams.vBufferNearPlane;
float f = controlParams.vBufferFarPlane;
float c = 2 - 2 * controlParams.depthSliceDistributionUniformity; // remap [0, 1] -> [2, 0]
depthEncodingParams = ComputeLogarithmicDepthEncodingParams(n, f, c);
depthDecodingParams = ComputeLogarithmicDepthDecodingParams(n, f, c);
}
} // struct Parameters
const int k_NumFrames = 2; // Double-buffer history and feedback
const int k_NumBuffers = 4; // See the list below
const int k_IndexDensity = 0;
const int k_IndexIntegral = 1;
const int k_IndexHistory = 2; // Depends on frame ID
const int k_IndexFeedback = 3; // Depends on frame ID
long m_ViewID = -1; // (m_ViewID > 0) if valid
RenderTexture[] m_Textures = null;
RenderTargetIdentifier[] m_Identifiers = null;
Parameters[] m_Params = null; // For the current and the previous frame
public long GetViewID()
{
return m_ViewID;
}
public Vector4 resolution;
public Vector2 sliceCount;
public Vector4 uvScaleAndLimit; // Necessary to work with sub-allocation (resource aliasing) in the RTHandle system
public Vector4 depthEncodingParams;
public Vector4 depthDecodingParams;
public bool IsValid()
public VBufferParameters(Vector3Int viewportResolution, Vector3Int bufferResolution, Vector2 depthRange, float depthDistributionUniformity)
return m_ViewID > 0 && m_Textures != null && m_Textures[0] != null;
}
int w = viewportResolution.x;
int h = viewportResolution.y;
int d = viewportResolution.z;
public Parameters GetParameters(uint frameIndex)
{
return m_Params[frameIndex & 1];
}
// The depth is fixed for now.
Vector2 uvScale = new Vector2((float)w / (float)bufferResolution.x,
(float)h / (float)bufferResolution.y);
public void SetParameters(Parameters parameters, uint frameIndex)
{
m_Params[frameIndex & 1] = parameters;
}
// vp_scale = vp_dim / tex_dim.
// clamp to (vp_dim - 0.5) / tex_dim = vp_scale - 0.5 * (1 / tex_dim) =
// vp_scale - 0.5 * (vp_scale / vp_dim) = vp_scale * (1 - 0.5 / vp_dim).
Vector2 uvLimit = new Vector2((w - 0.5f) / (float)bufferResolution.x,
(h - 0.5f) / (float)bufferResolution.y);
public RenderTargetIdentifier GetDensityBuffer()
{
Debug.Assert(IsValid());
return m_Identifiers[k_IndexDensity];
}
public RenderTargetIdentifier GetLightingIntegralBuffer() // Of the current frame
{
Debug.Assert(IsValid());
return m_Identifiers[k_IndexIntegral];
}
resolution = new Vector4(w, h, 1.0f / w, 1.0f / h);
sliceCount = new Vector2(d, 1.0f / d);
uvScaleAndLimit = new Vector4(uvScale.x, uvScale.y, uvLimit.x, uvLimit.y);
public RenderTargetIdentifier GetLightingHistoryBuffer(uint frameIndex) // From the previous frame
{
Debug.Assert(IsValid());
return m_Identifiers[k_IndexHistory + (frameIndex & 1)];
}
float n = depthRange.x;
float f = depthRange.y;
float c = 2 - 2 * depthDistributionUniformity; // remap [0, 1] -> [2, 0]
public RenderTargetIdentifier GetLightingFeedbackBuffer(uint frameIndex) // For the next frame
{
Debug.Assert(IsValid());
return m_Identifiers[k_IndexFeedback - (frameIndex & 1)];
depthEncodingParams = ComputeLogarithmicDepthEncodingParams(n, f, c);
depthDecodingParams = ComputeLogarithmicDepthDecodingParams(n, f, c);
public void Create(long viewID, int w, int h, int d, ControllerParameters controlParams)
{
Debug.Assert(viewID > 0);
Debug.Assert(w > 0 && h > 0 && d > 0);
// Clean up first.
Destroy();
m_ViewID = viewID;
m_Textures = new RenderTexture[k_NumBuffers];
m_Identifiers = new RenderTargetIdentifier[k_NumBuffers];
m_Params = new Parameters[k_NumFrames];
for (int i = 0; i < k_NumBuffers; i++)
{
m_Textures[i] = new RenderTexture(w, h, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
m_Textures[i].hideFlags = HideFlags.HideAndDontSave;
m_Textures[i].filterMode = FilterMode.Trilinear; // Custom
m_Textures[i].dimension = TextureDimension.Tex3D; // TODO: request the thick 3D tiling layout
m_Textures[i].volumeDepth = d;
m_Textures[i].enableRandomWrite = true;
m_Textures[i].name = CoreUtils.GetRenderTargetAutoName(w, h, RenderTextureFormat.ARGBHalf, String.Format("VBuffer{0}", i));
m_Textures[i].Create();
// TODO: clear the texture. Clearing 3D textures does not appear to work right now.
m_Identifiers[i] = new RenderTargetIdentifier(m_Textures[i]);
}
// Start with the same parameters for both frames. Then incrementally update them.
Parameters parameters = new Parameters(w, h, d, controlParams);
m_Params[0] = parameters;
m_Params[1] = parameters;
}
public void Destroy()
{
if (m_Textures != null)
{
for (int i = 0; i < k_NumBuffers; i++)
{
if (m_Textures[i] != null)
{
m_Textures[i].Release();
}
}
}
m_ViewID = -1;
m_Textures = null;
m_Identifiers = null;
m_Params = null;
}
} // class VBuffer
} // struct Parameters
public VolumetricLightingPreset preset { get { return (VolumetricLightingPreset)Math.Min(ShaderConfig.s_VolumetricLightingPreset, (int)VolumetricLightingPreset.Count); } }

List<VBuffer> m_VBuffers = null;
List<OrientedBBox> m_VisibleVolumeBounds = null;
List<DensityVolumeData> m_VisibleVolumeData = null;
public const int k_MaxVisibleVolumeCount = 512;

static ComputeBuffer s_VisibleVolumeDataBuffer = null;
// These two buffers do not depend on the frameID and are therefore shared by all views.
RTHandleSystem.RTHandle m_DensityBufferHandle;
RTHandleSystem.RTHandle m_LightingBufferHandle;
m_VolumeVoxelizationCS = asset.renderPipelineResources.volumeVoxelizationCS;
m_VolumetricLightingCS = asset.renderPipelineResources.volumetricLightingCS;
m_VBuffers = new List<VBuffer>();
m_VisibleVolumeBounds = new List<OrientedBBox>();
m_VisibleVolumeData = new List<DensityVolumeData>();
s_VisibleVolumeBoundsBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, System.Runtime.InteropServices.Marshal.SizeOf(typeof(OrientedBBox)));
s_VisibleVolumeDataBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DensityVolumeData)));
m_VolumeVoxelizationCS = asset.renderPipelineResources.volumeVoxelizationCS;
m_VolumetricLightingCS = asset.renderPipelineResources.volumetricLightingCS;
CreateBuffers();
public void Cleanup()
// RTHandleSystem API expects a function which computes the resolution. We define it here.
Vector2Int ComputeVBuffeResolutionXY(Vector2Int screenSize)
if (preset == VolumetricLightingPreset.Off) return;
m_VolumeVoxelizationCS = null;
m_VolumetricLightingCS = null;
Vector3Int resolution = ComputeVBufferResolution(preset, screenSize.x, screenSize.y);
for (int i = 0, n = m_VBuffers.Count; i < n; i++)
// Since the buffers owned by the VolumetricLightingSystem may have different lifetimes compared
// to those owned by the HDCamera, we need to make sure that the buffer resolution is the same
// (in order to share the UV scale and the UV limit).
if (m_LightingBufferHandle != null)
m_VBuffers[i].Destroy();
resolution.x = Math.Max(resolution.x, m_LightingBufferHandle.rt.width);
resolution.y = Math.Max(resolution.y, m_LightingBufferHandle.rt.height);
m_VBuffers = null;
m_VisibleVolumeBounds = null;
m_VisibleVolumeData = null;
CoreUtils.SafeRelease(s_VisibleVolumeBoundsBuffer);
CoreUtils.SafeRelease(s_VisibleVolumeDataBuffer);
return new Vector2Int(resolution.x, resolution.y);
public void ResizeVBufferAndUpdateProperties(HDCamera camera, uint frameIndex)
// BufferedRTHandleSystem API expects an allocator function. We define it here.
RTHandleSystem.RTHandle HistoryBufferAllocatorFunction(string viewName, int frameIndex, RTHandleSystem rtHandleSystem)
if (preset == VolumetricLightingPreset.Off) return;
var visualEnvironment = VolumeManager.instance.stack.GetComponent<VisualEnvironment>();
if (visualEnvironment == null || visualEnvironment.fogType != FogType.Volumetric) return;
frameIndex &= 1;
var controller = camera.camera.GetComponent<VolumetricLightingController>();
int d = ComputeVBufferSliceCount(preset);
if (camera.camera.cameraType == CameraType.SceneView)
{
// HACK: since it's not possible to add a component to a scene camera,
// we take one from the "main" camera (if present).
Camera mainCamera = Camera.main;
return rtHandleSystem.Alloc(scaleFunc: ComputeVBuffeResolutionXY,
slices: d,
dimension: TextureDimension.Tex3D,
colorFormat: RenderTextureFormat.ARGBHalf,
sRGB: false,
enableRandomWrite: true,
enableMSAA: false,
/* useDynamicScale: true, // <- TODO */
name: string.Format("{0}_VBufferHistory{1}", viewName, frameIndex)
);
}
if (mainCamera != null)
{
controller = mainCamera.GetComponent<VolumetricLightingController>();
}
}
void CreateBuffers()
{
Debug.Assert(m_VolumetricLightingCS != null);
if (controller == null) return;
m_VisibleVolumeBounds = new List<OrientedBBox>();
m_VisibleVolumeData = new List<DensityVolumeData>();
s_VisibleVolumeBoundsBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, Marshal.SizeOf(typeof(OrientedBBox)));
s_VisibleVolumeDataBuffer = new ComputeBuffer(k_MaxVisibleVolumeCount, Marshal.SizeOf(typeof(DensityVolumeData)));
int screenWidth = (int)camera.screenSize.x;
int screenHeight = (int)camera.screenSize.y;
long viewID = camera.GetViewID();
int d = ComputeVBufferSliceCount(preset);
Debug.Assert(viewID > 0);
m_DensityBufferHandle = RTHandles.Alloc(scaleFunc: ComputeVBuffeResolutionXY,
slices: d,
dimension: TextureDimension.Tex3D,
colorFormat: RenderTextureFormat.ARGBHalf,
sRGB: false,
enableRandomWrite: true,
enableMSAA: false,
/* useDynamicScale: true, // <- TODO */
name: "VBufferDensity");
int w = 0, h = 0, d = 0;
ComputeVBufferResolutionAndScale(preset, screenWidth, screenHeight, ref w, ref h, ref d);
m_LightingBufferHandle = RTHandles.Alloc(scaleFunc: ComputeVBuffeResolutionXY,
slices: d,
dimension: TextureDimension.Tex3D,
colorFormat: RenderTextureFormat.ARGBHalf,
sRGB: false,
enableRandomWrite: true,
enableMSAA: false,
/* useDynamicScale: true, // <- TODO */
name: "VBufferIntegral");
}
VBuffer vBuffer = FindVBuffer(viewID);
// For the initial allocation, no suballocation happens (the texture is full size).
VBufferParameters ComputeVBufferParameters(HDCamera camera, bool isInitialAllocation)
{
Vector3Int viewportResolution = ComputeVBufferResolution(preset, camera.camera.pixelWidth, camera.camera.pixelHeight);
Vector3Int bufferResolution; // Could be higher due to sub-allocation (resource aliasing) in the RTHandle system
if (vBuffer != null)
if (isInitialAllocation)
VBuffer.Parameters frameParams = vBuffer.GetParameters(frameIndex);
// Found, check resolution.
if (w == frameParams.resolution.x &&
h == frameParams.resolution.y &&
d == frameParams.sliceCount.x)
{
// The resolution matches.
// Depth parameters may have changed, so update those.
frameParams.Update(controller.parameters);
vBuffer.SetParameters(frameParams, frameIndex);
return;
}
bufferResolution = viewportResolution;
// Not found - grow the array.
vBuffer = new VBuffer();
m_VBuffers.Add(vBuffer);
// All V-Buffers of the current frame should have the same size (you have to double-buffer history, of course).
bufferResolution = new Vector3Int(m_LightingBufferHandle.rt.width, m_LightingBufferHandle.rt.height, m_LightingBufferHandle.rt.volumeDepth);
vBuffer.Create(viewID, w, h, d, controller.parameters);
var controller = VolumeManager.instance.stack.GetComponent<VolumetricLightingController>();
// We must not allow the V-Buffer to extend outside of the camera's frustum.
float n = camera.camera.nearClipPlane;
float f = camera.camera.farClipPlane;
Vector2 vBufferDepthRange = controller.depthRange.value;
vBufferDepthRange.y = Mathf.Clamp(vBufferDepthRange.y, n, f); // far
vBufferDepthRange.x = Mathf.Clamp(vBufferDepthRange.x, n, vBufferDepthRange.y); // near
float vBufferDepthDistributionUniformity = controller.depthDistributionUniformity.value;
return new VBufferParameters(viewportResolution, bufferResolution, vBufferDepthRange, vBufferDepthDistributionUniformity);
VBuffer FindVBuffer(long viewID)
public void InitializePerCameraData(HDCamera camera)
Debug.Assert(viewID > 0);
if (preset == VolumetricLightingPreset.Off) return;
VBuffer vBuffer = null;
// Start with the same parameters for both frames. Then update them one by one every frame.
var parameters = ComputeVBufferParameters(camera, true);
camera.vBufferParams = new VBufferParameters[2];
camera.vBufferParams[0] = parameters;
camera.vBufferParams[1] = parameters;
if (m_VBuffers != null)
if (camera.camera.cameraType == CameraType.Game ||
camera.camera.cameraType == CameraType.SceneView)
int n = m_VBuffers.Count;
for (int i = 0; i < n; i++)
{
// Check whether domain reload killed it...
if (viewID == m_VBuffers[i].GetViewID() && m_VBuffers[i].IsValid())
{
vBuffer = m_VBuffers[i];
}
}
// We don't need reprojection for other view types, such as reflection and preview.
camera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting, HistoryBufferAllocatorFunction);
}
return vBuffer;
// This function relies on being called once per camera per frame.
// The results are undefined otherwise.
public void UpdatePerCameraData(HDCamera camera)
{
if (preset == VolumetricLightingPreset.Off) return;
var parameters = ComputeVBufferParameters(camera, false);
// Double-buffer. I assume the cost of copying is negligible (don't want to use the frame index).
camera.vBufferParams[1] = camera.vBufferParams[0];
camera.vBufferParams[0] = parameters;
// Note: resizing of history buffer is automatic (handled by the BufferedRTHandleSystem).
}
void DestroyBuffers()
{
RTHandles.Release(m_DensityBufferHandle);
RTHandles.Release(m_LightingBufferHandle);
CoreUtils.SafeRelease(s_VisibleVolumeBoundsBuffer);
CoreUtils.SafeRelease(s_VisibleVolumeDataBuffer);
m_VisibleVolumeBounds = null;
m_VisibleVolumeData = null;
}
public void Cleanup()
{
if (preset == VolumetricLightingPreset.Off) return;
DestroyBuffers();
m_VolumeVoxelizationCS = null;
m_VolumetricLightingCS = null;
}
static int ComputeVBufferTileSize(VolumetricLightingPreset preset)

}
}
// Since a single voxel corresponds to a tile (e.g. 8x8) of pixels,
// the VBuffer can potentially extend past the boundaries of the viewport.
// The function returns the fraction of the {width, height} of the VBuffer visible on screen.
// Note: for performance reasons, the scale is unused (implicitly 1). The error is typically under 1%.
static Vector2 ComputeVBufferResolutionAndScale(VolumetricLightingPreset preset,
int screenWidth, int screenHeight,
ref int w, ref int h, ref int d)
static Vector3Int ComputeVBufferResolution(VolumetricLightingPreset preset,
int screenWidth, int screenHeight)
// Ceil(ScreenSize / TileSize).
w = (screenWidth + t - 1) / t;
h = (screenHeight + t - 1) / t;
d = ComputeVBufferSliceCount(preset);
// ceil(ScreenSize / TileSize).
int w = (screenWidth + (t - 1)) / t;
int h = (screenHeight + (t - 1)) / t;
int d = ComputeVBufferSliceCount(preset);
return new Vector2((float)screenWidth / (float)(w * t), (float)screenHeight / (float)(h * t));
return new Vector3Int(w, h, d);
}
// See EncodeLogarithmicDepthGeneralized().

return depthParams;
}
void SetPreconvolvedAmbientLightProbe(CommandBuffer cmd, float asymmetry)
void SetPreconvolvedAmbientLightProbe(CommandBuffer cmd, float anisotropy)
ZonalHarmonicsL2 phaseZH = ZonalHarmonicsL2.GetCornetteShanksPhaseFunction(asymmetry);
ZonalHarmonicsL2 phaseZH = ZonalHarmonicsL2.GetCornetteShanksPhaseFunction(anisotropy);
float CornetteShanksPhasePartConstant(float asymmetry)
float CornetteShanksPhasePartConstant(float anisotropy)
float g = asymmetry;
float g = anisotropy;
return (1.0f / (4.0f * Mathf.PI)) * 1.5f * (1.0f - g * g) / (2.0f + g * g);
}

if (preset == VolumetricLightingPreset.Off) return;
var visualEnvironment = VolumeManager.instance.stack.GetComponent<VisualEnvironment>();
if (visualEnvironment.fogType != FogType.Volumetric) return;
// VisualEnvironment sets global fog parameters: _GlobalAsymmetry, _GlobalScattering, _GlobalExtinction.
// VisualEnvironment sets global fog parameters: _GlobalAnisotropy, _GlobalScattering, _GlobalExtinction.
VBuffer vBuffer = FindVBuffer(camera.GetViewID());
if (vBuffer == null)
if (visualEnvironment.fogType != FogType.Volumetric)
{
// Set the neutral black texture.
cmd.SetGlobalTexture(HDShaderIDs._VBufferLighting, CoreUtils.blackVolumeTexture);

// Get the interpolated asymmetry value.
// Get the interpolated anisotropy value.
SetPreconvolvedAmbientLightProbe(cmd, fog.asymmetry);
SetPreconvolvedAmbientLightProbe(cmd, fog.anisotropy);
var currFrameParams = vBuffer.GetParameters(frameIndex);
var prevFrameParams = vBuffer.GetParameters(frameIndex - 1);
var currFrameParams = camera.vBufferParams[0];
var prevFrameParams = camera.vBufferParams[1];
cmd.SetGlobalVector( HDShaderIDs._VBufferUvScaleAndLimit, currFrameParams.uvScaleAndLimit);
cmd.SetGlobalVector( HDShaderIDs._VBufferPrevUvScaleAndLimit, prevFrameParams.uvScaleAndLimit);
cmd.SetGlobalTexture(HDShaderIDs._VBufferLighting, vBuffer.GetLightingIntegralBuffer());
cmd.SetGlobalTexture(HDShaderIDs._VBufferLighting, m_LightingBufferHandle);
}
public DensityVolumeList PrepareVisibleDensityVolumeList(HDCamera camera, CommandBuffer cmd)

var visualEnvironment = VolumeManager.instance.stack.GetComponent<VisualEnvironment>();
if (visualEnvironment.fogType != FogType.Volumetric) return densityVolumes;
VBuffer vBuffer = FindVBuffer(camera.GetViewID());
if (vBuffer == null) return densityVolumes;
using (new ProfilingSample(cmd, "Prepare Visible Density Volume List"))
{

m_VisibleVolumeData.Clear();
// Collect all visible finite volume data, and upload it to the GPU.
DensityVolume[] volumes = DensityVolumeManager.manager.PrepareDensityVolumeData(cmd);
DensityVolume[] volumes = DensityVolumeManager.manager.PrepareDensityVolumeData(cmd);
for (int i = 0; i < Math.Min(volumes.Length, k_MaxVisibleVolumeCount); i++)
{

obb.center -= camOffset;
// Frustum cull on the CPU for now. TODO: do it on the GPU.
// TODO: account for custom near and far planes of the V-Buffer's frustum.
// It's typically much shorter (along the Z axis) than the camera's frustum.
if (GeometryUtils.Overlap(obb, camera.frustum, 6, 8))
{
// TODO: cache these?

var visualEnvironment = VolumeManager.instance.stack.GetComponent<VisualEnvironment>();
if (visualEnvironment.fogType != FogType.Volumetric) return;
VBuffer vBuffer = FindVBuffer(camera.GetViewID());
if (vBuffer == null) return;
using (new ProfilingSample(cmd, "Volume Voxelization"))
{

int kernel = m_VolumeVoxelizationCS.FindKernel(enableClustered ? "VolumeVoxelizationClustered"
: "VolumeVoxelizationBruteforce");
var frameParams = vBuffer.GetParameters(frameIndex);
var frameParams = camera.vBufferParams[0];
Vector4 resolution = frameParams.resolution;
float vFoV = camera.camera.fieldOfView * Mathf.Deg2Rad;

volumeAtlasDimensions.y = 1.0f / volumeAtlas.width;
}
cmd.SetComputeTextureParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VBufferDensity, vBuffer.GetDensityBuffer());
cmd.SetComputeTextureParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VBufferDensity, m_DensityBufferHandle);
cmd.SetComputeBufferParam( m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeBounds, s_VisibleVolumeBoundsBuffer);
cmd.SetComputeBufferParam( m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeData, s_VisibleVolumeDataBuffer);
cmd.SetComputeTextureParam(m_VolumeVoxelizationCS, kernel, HDShaderIDs._VolumeMaskAtlas, volumeAtlas);

var visualEnvironment = VolumeManager.instance.stack.GetComponent<VisualEnvironment>();
if (visualEnvironment.fogType != FogType.Volumetric) return;
VBuffer vBuffer = FindVBuffer(camera.GetViewID());
if (vBuffer == null) return;
using (new ProfilingSample(cmd, "Volumetric Lighting"))
{

: "VolumetricLightingBruteforce");
}
var frameParams = vBuffer.GetParameters(frameIndex);
var frameParams = camera.vBufferParams[0];
Vector4 resolution = frameParams.resolution;
float vFoV = camera.camera.fieldOfView * Mathf.Deg2Rad;
// Compose the matrix which allows us to compute the world space view direction.

// Currently, we assume that they are completely uncorrelated, but maybe we should correlate them somehow.
Vector4 offset = new Vector4(xySeq[sampleIndex].x, xySeq[sampleIndex].y, zSeq[sampleIndex], frameIndex);
// Get the interpolated asymmetry value.
// Get the interpolated anisotropy value.
var fog = VolumeManager.instance.stack.GetComponent<VolumetricFog>();
// TODO: set 'm_VolumetricLightingPreset'.

cmd.SetComputeFloatParam( m_VolumetricLightingCS, HDShaderIDs._CornetteShanksConstant, CornetteShanksPhasePartConstant(fog.asymmetry));
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferDensity, vBuffer.GetDensityBuffer()); // Read
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingIntegral, vBuffer.GetLightingIntegralBuffer()); // Write
cmd.SetComputeFloatParam( m_VolumetricLightingCS, HDShaderIDs._CornetteShanksConstant, CornetteShanksPhasePartConstant(fog.anisotropy));
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferDensity, m_DensityBufferHandle); // Read
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingIntegral, m_LightingBufferHandle); // Write
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingFeedback, vBuffer.GetLightingFeedbackBuffer(frameIndex)); // Write
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingHistory, vBuffer.GetLightingHistoryBuffer(frameIndex)); // Read
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingHistory, camera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting)); // Read
cmd.SetComputeTextureParam(m_VolumetricLightingCS, kernel, HDShaderIDs._VBufferLightingFeedback, camera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting)); // Write
}
int w = (int)resolution.x;

52
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumetrics/VolumetricLightingController.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[ExecuteInEditMode]
[AddComponentMenu("Rendering/Volumetric Lighting Controller", 1101)]
public class VolumetricLightingController : MonoBehaviour
public class VolumetricLightingController : VolumeComponent
public VolumetricLightingSystem.ControllerParameters parameters;
public VolumetricLightingController()
{
parameters.vBufferNearPlane = 0.5f;
parameters.vBufferFarPlane = 64.0f;
parameters.depthSliceDistributionUniformity = 0.75f;
}
private void Awake()
{
}
private void OnEnable()
{
}
private void OnDisable()
{
}
private void Update()
{
}
private void OnValidate()
{
var camera = GetComponent<Camera>();
if (camera != null)
{
// We must not allow the V-Buffer to extend past the camera's frustum.
float n = camera.nearClipPlane;
float f = camera.farClipPlane;
parameters.vBufferFarPlane = Mathf.Clamp(parameters.vBufferFarPlane, n, f);
parameters.vBufferNearPlane = Mathf.Clamp(parameters.vBufferNearPlane, n, parameters.vBufferFarPlane);
parameters.depthSliceDistributionUniformity = Mathf.Clamp01(parameters.depthSliceDistributionUniformity);
}
else
{
Debug.Log("Volumetric Lighting Controller must be attached to a camera!");
}
}
[Tooltip("Near and far planes of camera's volumetric lighting buffers (in meters).")]
public FloatRangeParameter depthRange = new FloatRangeParameter(new Vector2(0.5f, 64.0f), 0.01f, 10000.0f);
[Tooltip("Controls the slice distribution: 0 = exponential (more slices near the camera, fewer slices far away), 1 = linear (uniform spacing).")]
public ClampedFloatParameter depthDistributionUniformity = new ClampedFloatParameter(0.75f, 0, 1);
}
} // UnityEngine.Experimental.Rendering.HDPipeline

14
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/GGXConvolution/RuntimeFilterIBL.cs


using UnityEngine.Rendering;
using UnityEngine.Rendering;
using System;
using System.Collections.Generic;

m_GgxIblSampleData.autoGenerateMips = false;
m_GgxIblSampleData.enableRandomWrite = true;
m_GgxIblSampleData.filterMode = FilterMode.Point;
m_GgxIblSampleData.name = CoreUtils.GetRenderTargetAutoName(m_GgxIblMaxSampleCount, k_GgxIblMipCountMinusOne, RenderTextureFormat.ARGBHalf, "GGXIblSampleData");
m_GgxIblSampleData.name = CoreUtils.GetRenderTargetAutoName(m_GgxIblMaxSampleCount, k_GgxIblMipCountMinusOne, 1, RenderTextureFormat.ARGBHalf, "GGXIblSampleData");
m_GgxIblSampleData.hideFlags = HideFlags.HideAndDontSave;
m_GgxIblSampleData.Create();

var lodIsMissing = i >= m_PlanarColorMips.Count;
RenderTexture rt = null;
var createRT = lodIsMissing
var createRT = lodIsMissing
? RenderTextureReadWrite.sRGB
? RenderTextureReadWrite.sRGB
: RenderTextureReadWrite.Linear
);

}
int HashRenderTextureProperties(
int width,
int width,
int depth,
RenderTextureFormat format,
int depth,
RenderTextureFormat format,
RenderTextureReadWrite sRGB)
{
return width.GetHashCode()

13
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl


// Warning: the contents are later overwritten for Standard and SSS!
outGBuffer0 = float4(surfaceData.baseColor, surfaceData.specularOcclusion);
// The sign of the Z component of the normal MUST round-trip through the G-Buffer, otherwise
// the reconstruction of the tangent frame for anisotropic GGX creates a seam along the Z axis.
// The constant was eye-balled to not cause artifacts.
// TODO: find a proper solution. E.g. we could re-shuffle the faces of the octahedron
// s.t. the sign of the Z component round-trips.
const float seamThreshold = 1.0/1024.0;
surfaceData.normalWS.z = CopySign(max(seamThreshold, abs(surfaceData.normalWS.z)), surfaceData.normalWS.z);
// With octahedral quad packing we get an artifact for reconstructed tangent at the center of this quad. We use rect packing instead to avoid it.
float2 octNormalWS = PackNormalOctRectEncode(surfaceData.normalWS);
float2 octNormalWS = PackNormalOctQuadEncode(surfaceData.normalWS);
float3 packNormalWS = PackFloat2To888(saturate(octNormalWS * 0.5 + 0.5));
// We store perceptualRoughness instead of roughness because it is perceptually linear.
outGBuffer1 = float4(packNormalWS, PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness));

float3 packNormalWS = inGBuffer1.rgb;
float2 octNormalWS = Unpack888ToFloat2(packNormalWS);
bsdfData.normalWS = UnpackNormalOctRectEncode(octNormalWS * 2.0 - 1.0);
bsdfData.normalWS = UnpackNormalOctQuadEncode(octNormalWS * 2.0 - 1.0);
bsdfData.perceptualRoughness = inGBuffer1.a;
bakeDiffuseLighting = inGBuffer3.rgb;

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/PreIntegratedFGD/PreIntegratedFGD.cs


m_PreIntegratedFGD.filterMode = FilterMode.Bilinear;
m_PreIntegratedFGD.wrapMode = TextureWrapMode.Clamp;
m_PreIntegratedFGD.hideFlags = HideFlags.DontSave;
m_PreIntegratedFGD.name = CoreUtils.GetRenderTargetAutoName(128, 128, RenderTextureFormat.ARGB2101010, "PreIntegratedFGD");
m_PreIntegratedFGD.name = CoreUtils.GetRenderTargetAutoName(128, 128, 1, RenderTextureFormat.ARGB2101010, "PreIntegratedFGD");
m_PreIntegratedFGD.Create();
m_isInit = false;

23
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScattering.compute


#define GROUP_SIZE_2D (GROUP_SIZE_1D * GROUP_SIZE_1D)
#define TEXTURE_CACHE_BORDER 2
#define TEXTURE_CACHE_SIZE_1D (GROUP_SIZE_1D + 2 * TEXTURE_CACHE_BORDER)
#define TEXTURE_CACHE_SIZE_2D (TEXTURE_CACHE_SIZE_1D * TEXTURE_CACHE_SIZE_1D)
// Check for support of typed UAV loads from FORMAT_R16G16B16A16_FLOAT.
// TODO: query the format support more precisely.

float4 _FilterKernels[DIFFUSION_PROFILE_COUNT][SSS_N_SAMPLES_NEAR_FIELD]; // XY = near field, ZW = far field; 0 = radius, 1 = reciprocal of the PDF
TEXTURE2D(_DepthTexture); // Z-buffer
TEXTURE2D(_SSSHTile); // DXGI_FORMAT_R8_UINT is not supported by Unity
TEXTURE2D(_SSSHTile); // DXGI_FORMAT_R8_UINT is not supported by Unity
TEXTURE2D(_IrradianceSource); // Includes transmitted light
#ifdef USE_INTERMEDIATE_BUFFER

// 6656 bytes used. It appears that the reserved LDS space must be a multiple of 512 bytes.
#if SSS_USE_LDS_CACHE
groupshared float4 textureCache[TEXTURE_CACHE_SIZE_1D * TEXTURE_CACHE_SIZE_1D]; // {irradiance, linearDepth}
groupshared float2 textureCache0[TEXTURE_CACHE_SIZE_2D]; // {irradiance.rg}
groupshared float2 textureCache1[TEXTURE_CACHE_SIZE_2D]; // {irradiance.b, linearDepth}
void StoreSampleToCacheMemory(float4 value, int2 cacheCoord)
{
int linearCoord = Mad24(TEXTURE_CACHE_SIZE_1D, cacheCoord.y, cacheCoord.x);
textureCache0[linearCoord] = value.rg;
textureCache1[linearCoord] = value.ba;
}
return textureCache[Mad24(TEXTURE_CACHE_SIZE_1D, cacheCoord.y, cacheCoord.x)];
int linearCoord = Mad24(TEXTURE_CACHE_SIZE_1D, cacheCoord.y, cacheCoord.x);
return float4(textureCache0[linearCoord],
textureCache1[linearCoord]);
}
#endif

#if SSS_USE_LDS_CACHE
uint2 cacheCoord = groupCoord + TEXTURE_CACHE_BORDER;
// Populate the central region of the LDS cache.
textureCache[Mad24(TEXTURE_CACHE_SIZE_1D, cacheCoord.y, cacheCoord.x)] = float4(centerIrradiance, centerViewZ);
StoreSampleToCacheMemory(float4(centerIrradiance, centerViewZ), cacheCoord);
uint numBorderQuadsPerWave = TEXTURE_CACHE_SIZE_1D / 2 - 1;
uint halfCacheWidthInQuads = TEXTURE_CACHE_SIZE_1D / 4;

}
// Populate the border region of the LDS cache.
textureCache[Mad24(TEXTURE_CACHE_SIZE_1D, cacheCoord2.y, cacheCoord2.x)] = float4(irradiance2, viewZ2);
StoreSampleToCacheMemory(float4(irradiance2, viewZ2), cacheCoord2);
}
// Wait for the LDS.

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl


// ----------------------------------------------------------------------------
// TODO: all affine matrices should be 3x4.
// Note: please use UNITY_MATRIX_X macros instead of referencing matrix variables directly.
// Important: please use macros or functions to access the CBuffer data.
// The member names and data layout can (and will) change!
// TODO: all affine matrices should be 3x4.
float4x4 _ViewMatrix;
float4x4 _InvViewMatrix;
float4x4 _ProjMatrix;

#endif
float _DetViewMatrix; // determinant(_ViewMatrix)
float4 _ScreenSize; // { w, h, 1 / w, 1 / h }
float4 _ScreenToTargetScale; // { w / RTHandle.maxWidth, h / RTHandle.maxHeight, 0, 0 }
float4 _ScreenToTargetScale; // { w / RTHandle.maxWidth, h / RTHandle.maxHeight } : xy = currFrame, zw = prevFrame
// Values used to linearize the Z buffer (http://www.humus.name/temp/Linearize%20depth.txt)
// x = 1 - f/n

float4 _FrustumPlanes[6]; // { (a, b, c) = N, d = -dot(N, P) } [L, R, T, B, N, F]
// TAA Frame Index ranges from 0 to 7. This gives you two rotations per cycle.
float4 _TaaFrameRotation; // { sin(taaFrame * PI/2), cos(taaFrame * PI/2), 0, 0 }
// t = animateMaterials ? Time.realtimeSinceStartup : 0.
float4 _Time; // { t/20, t, t*2, t*3 }

// Volumetric lighting.
float4 _AmbientProbeCoeffs[7]; // 3 bands of SH, packed, rescaled and convolved with the phase function
float _GlobalAsymmetry;
float _GlobalAnisotropy;
float4 _VBufferUvScaleAndLimit; // Necessary us to work with sub-allocation (resource aliasing) in the RTHandle system
float4 _VBufferDepthEncodingParams; // See the call site for description
float4 _VBufferDepthDecodingParams; // See the call site for description

float4 _VBufferPrevResolution;
float4 _VBufferPrevSliceCount;
float4 _VBufferPrevUvScaleAndLimit;
float4 _VBufferPrevDepthEncodingParams;
float4 _VBufferPrevDepthDecodingParams;
CBUFFER_END

14
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariablesFunctions.hlsl


return GetFullScreenTriangleTexCoord(vertexID) * _ScreenToTargetScale.xy;
}
// The size of the render target can be larger than the size of the viewport.
// This function returns the fraction of the render target covered by the viewport:
// ViewportScale = ViewportResolution / RenderTargetResolution.
// Do not assume that their size is the same, or that sampling outside of the viewport returns 0.
float2 GetViewportScaleCurrentFrame()
{
return _ScreenToTargetScale.xy;
}
float2 GetViewportScalePreviousFrame()
{
return _ScreenToTargetScale.zw;
}
#endif // UNITY_SHADER_VARIABLES_FUNCTIONS_INCLUDED

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/AtmosphericScattering.cs


cmd.SetGlobalVector(HDShaderIDs._GlobalScattering, data.scattering);
cmd.SetGlobalFloat( HDShaderIDs._GlobalExtinction, data.extinction);
cmd.SetGlobalFloat( HDShaderIDs._GlobalAsymmetry, 0.0f);
cmd.SetGlobalFloat( HDShaderIDs._GlobalAnisotropy, 0.0f);
}
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/AtmosphericScattering.hlsl


posInput.linearDepth,
_VBufferResolution,
_VBufferSliceCount.xy,
_VBufferUvScaleAndLimit.xy,
_VBufferUvScaleAndLimit.zw,
_VBufferDepthEncodingParams,
_VBufferDepthDecodingParams,
true, true);

16
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Sky/AtmosphericScattering/VolumetricFog.cs


{
public ColorParameter albedo = new ColorParameter(new Color(0.5f, 0.5f, 0.5f));
public MinFloatParameter meanFreePath = new MinFloatParameter(1000000.0f, 1.0f);
public ClampedFloatParameter asymmetry = new ClampedFloatParameter(0.0f, -1.0f, 1.0f);
public ClampedFloatParameter anisotropy = new ClampedFloatParameter(0.0f, -1.0f, 1.0f);
// Override the volume blending function.
public override void Override(VolumeComponent state, float interpFactor)

float otherExtinction = VolumeRenderingUtils.ExtinctionFromMeanFreePath(other.meanFreePath);
Vector3 otherScattering = VolumeRenderingUtils.ScatteringFromExtinctionAndAlbedo(otherExtinction, (Vector3)(Vector4)other.albedo.value);
float blendExtinction = Mathf.Lerp(otherExtinction, thisExtinction, interpFactor);
Vector3 blendScattering = Vector3.Lerp(otherScattering, thisScattering, interpFactor);
float blendAsymmetry = Mathf.Lerp(other.asymmetry, asymmetry, interpFactor);
float blendExtinction = Mathf.Lerp(otherExtinction, thisExtinction, interpFactor);
Vector3 blendScattering = Vector3.Lerp(otherScattering, thisScattering, interpFactor);
float blendAsymmetry = Mathf.Lerp(other.anisotropy, anisotropy, interpFactor);
float blendMeanFreePath = VolumeRenderingUtils.MeanFreePathFromExtinction(blendExtinction);
Color blendAlbedo = (Color)(Vector4)VolumeRenderingUtils.AlbedoFromMeanFreePathAndScattering(blendMeanFreePath, blendScattering);

other.albedo.value = blendAlbedo;
}
if (asymmetry.overrideState)
if (anisotropy.overrideState)
other.asymmetry.value = blendAsymmetry;
other.anisotropy.value = blendAsymmetry;
DensityVolumeParameters param = new DensityVolumeParameters(albedo, meanFreePath, asymmetry);
DensityVolumeParameters param = new DensityVolumeParameters(albedo, meanFreePath, anisotropy);
DensityVolumeData data = param.GetData();

cmd.SetGlobalFloat( HDShaderIDs._GlobalExtinction, data.extinction);
cmd.SetGlobalFloat( HDShaderIDs._GlobalAsymmetry, asymmetry);
cmd.SetGlobalFloat( HDShaderIDs._GlobalAnisotropy, anisotropy);
}
}
}
正在加载...
取消
保存