浏览代码

Merge pull request #1270 from Unity-Technologies/feature/SSR

Screen Space Reflection (Scene Proxy raycasting)
/main
GitHub 6 年前
当前提交
bdeba039
共有 37 个文件被更改,包括 1817 次插入400 次删除
  1. 43
      ScriptableRenderPipeline/Core/CoreRP/Debugging/MousePositionDebug.cs
  2. 1
      ScriptableRenderPipeline/HDRenderPipeline/CHANGELOG.md
  3. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCamera.cs
  4. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Camera/HDCameraFrameHistoryType.cs
  5. 228
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs
  6. 45
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs.hlsl
  7. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.hlsl
  8. 83
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugFullScreen.shader
  9. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/LightingDebug.cs
  10. 19
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/LightingDebug.cs.hlsl
  11. 37
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ScreenSpaceRefractionEditor.cs
  12. 16
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/LitUI.cs
  13. 50
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  14. 22
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs
  15. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/GlobalIlluminationUtils.cs
  16. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  17. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/PlanarReflectionProbe.cs
  18. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ProbeWrapper.cs
  19. 34
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceRefraction.cs
  20. 846
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl
  21. 13
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/Volumes/ProxyVolume.cs
  22. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs
  23. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs.hlsl
  24. 369
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  25. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.shader
  26. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitTessellation.shader
  27. 19
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl
  28. 16
      Tests/UTF_Suites_HDRP/Resources/HDRP_Deferred.asset
  29. 16
      Tests/UTF_Suites_HDRP/Resources/HDRP_Forward.asset
  30. 44
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs
  31. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs.meta
  32. 73
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ScreenSpaceLightingEditor.cs
  33. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ScreenSpaceLightingEditor.cs.meta
  34. 69
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceLighting.cs
  35. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceLighting.cs.meta
  36. 70
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceReflection.cs
  37. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceReflection.cs.meta

43
ScriptableRenderPipeline/Core/CoreRP/Debugging/MousePositionDebug.cs


using System;
using UnityEditor;
namespace UnityEngine.Experimental.Rendering
{

}
#if UNITY_EDITOR
[ExecuteInEditMode]
class GameViewEventCatcher : MonoBehaviour
{
public static GameViewEventCatcher s_Instance = null;
public static void Cleanup()
{
if (s_Instance != null)
DestroyImmediate(s_Instance.gameObject);
}
public static void Build()
{
Cleanup();
var go = new GameObject("__GameViewEventCatcher");
go.hideFlags = HideFlags.HideAndDontSave;
s_Instance = go.AddComponent<GameViewEventCatcher>();
}
void Update()
{
if (Input.mousePosition.x < 0
|| Input.mousePosition.y < 0
|| Input.mousePosition.x > Screen.width
|| Input.mousePosition.y > Screen.height)
return;
instance.m_mousePosition = Input.mousePosition;
instance.m_mousePosition.y = Screen.height - instance.m_mousePosition.y;
if (Input.GetMouseButton(1))
instance.m_MouseClickPosition = instance.m_mousePosition;
if (Input.GetKey(KeyCode.PageUp))
++instance.m_DebugStep;
if (Input.GetKey(KeyCode.PageDown))
instance.m_DebugStep = Mathf.Max(0, instance.m_DebugStep - 1);
if (Input.GetKey(KeyCode.End))
instance.m_MouseClickPosition = instance.m_mousePosition;
}
}
private Vector2 m_mousePosition = Vector2.zero;
Vector2 m_MouseClickPosition = Vector2.zero;
int m_DebugStep = 0;

#if UNITY_EDITOR
UnityEditor.SceneView.onSceneGUIDelegate -= OnSceneGUI;
UnityEditor.SceneView.onSceneGUIDelegate += OnSceneGUI;
GameViewEventCatcher.Build();
#endif
}

UnityEditor.SceneView.onSceneGUIDelegate -= OnSceneGUI;
GameViewEventCatcher.Cleanup();
#endif
}

1
ScriptableRenderPipeline/HDRenderPipeline/CHANGELOG.md


- Add stripper of shader variant when building a player. Save shader compile time.
- Disable per-object culling that was executed in C++ in HD whereas it was not used (Optimization)
- Enable texture streaming debugging (was not working before 2018.2)
- Added Screen Space Reflection with Proxy Projection Model
- Support correctly scene selection for alpha tested object
- Add per light shadow mask mode control (i.e shadow mask distance and shadow mask). It use the option NonLightmappedOnly

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


}
// Set up UnityPerView CBuffer.
public void SetupGlobalParams(CommandBuffer cmd, float time, float lastTime)
public void SetupGlobalParams(CommandBuffer cmd, float time, float lastTime, uint frameCount)
{
cmd.SetGlobalMatrix(HDShaderIDs._ViewMatrix, viewMatrix);
cmd.SetGlobalMatrix(HDShaderIDs._InvViewMatrix, viewMatrix.inverse);

cmd.SetGlobalVector(HDShaderIDs.unity_DeltaTime, new Vector4(dt, 1.0f / dt, sdt, 1.0f / sdt));
cmd.SetGlobalVector(HDShaderIDs._SinTime, new Vector4(Mathf.Sin(ct * 0.125f), Mathf.Sin(ct * 0.25f), Mathf.Sin(ct * 0.5f), Mathf.Sin(ct)));
cmd.SetGlobalVector(HDShaderIDs._CosTime, new Vector4(Mathf.Cos(ct * 0.125f), Mathf.Cos(ct * 0.25f), Mathf.Cos(ct * 0.5f), Mathf.Cos(ct)));
cmd.SetGlobalInt(HDShaderIDs._FrameCount, (int)frameCount);
}
public void SetupGlobalStereoParams(CommandBuffer cmd)

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


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

228
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs


[GenerateHLSL]
public struct ScreenSpaceTracingDebug
{
// Used to debug SSRay model
// Used to debug SSRay model
public Lit.RefractionSSRayModel tracingModel;
public Lit.ProjectionModel tracingModel;
public uint loopStartPositionSSX; // Proxy, HiZ
public uint loopStartPositionSSY; // Proxy, HiZ
public float loopStartLinearDepth; // Proxy, HiZ
public Vector3 loopRayDirectionSS; // HiZ
public uint loopStartPositionSSX; // Proxy, HiZ, Linear
public uint loopStartPositionSSY; // Proxy, HiZ, Linear
public float loopStartLinearDepth; // Proxy, HiZ, Linear
public Vector3 loopRayDirectionSS; // HiZ, Linear
public uint loopIterationMax; // HiZ
public uint loopIterationMax; // HiZ, Linear
// 9x32 bits
public Vector3 iterationPositionSS; // HiZ
public uint iterationMipLevel; // HiZ
public uint iteration; // HiZ
public float iterationLinearDepthBuffer; // HiZ
// 11x32 bits
public Vector3 iterationPositionSS; // HiZ, Linear
public uint iterationMipLevel; // HiZ, Linear
public uint iteration; // HiZ, Linear
public float iterationLinearDepthBufferMin; // HiZ, Linear
public float iterationLinearDepthBufferMax; // HiZ, Linear
public float iterationLinearDepthBufferMinThickness; // HiZ, Linear
public uint iterationCellSizeW; // HiZ
public uint iterationCellSizeH; // HiZ
public uint iterationCellSizeW; // HiZ, Linear
public uint iterationCellSizeH; // HiZ, Linear
// 4x32 bits
public bool endHitSuccess; // Proxy, HiZ
public float endLinearDepth; // Proxy, HiZ
public uint endPositionSSX; // Proxy, HiZ
public uint endPositionSSY; // Proxy, HiZ
// 5x32 bits
public int endHitSuccess; // Proxy, HiZ, Linear
public float endLinearDepth; // Proxy, HiZ, Linear
public uint endPositionSSX; // Proxy, HiZ, Linear
public uint endPositionSSY; // Proxy, HiZ, Linear
public float endHitWeight; // HiZ, Linear
// 0x32 bits (padding)
// 7x32 Lighting
public Vector3 lightingSampledColor; // All
public Vector3 lightingSpecularFGD; // All
public float lightingWeight; // All
// 2x32 bits (padding)
public Vector2 padding;
public bool intersectDepthBuffer { get { return (1.0f / iterationPositionSS.z) >= iterationLinearDepthBufferMin && (1.0f / iterationPositionSS.z) <= iterationLinearDepthBufferMinThickness; } }
}
public class DebugDisplaySettings

public static string k_PanelScreenSpaceTracing = "Screen Space Tracing";
public static string k_PanelDecals = "Decals";
//static readonly string[] k_HiZIntersectionKind = { "None", "Depth", "Cell" };
static readonly string[] k_HiZIntersectionKind = { "None", "Cell", "Depth" };
DebugUI.Widget[] m_DebugDisplayStatsItems;
DebugUI.Widget[] m_DebugMaterialItems;

public float debugOverlayRatio = 0.33f;
public FullScreenDebugMode fullScreenDebugMode = FullScreenDebugMode.None;
public float fullscreenDebugMip = 0.0f;
public bool showSSRayGrid = true;
public bool showSSRayDepthPyramid = true;
public bool showSSRayGrid = false;
public bool showSSRayDepthPyramid = false;
public bool showSSSampledColor = false;
public MaterialDebugSettings materialDebugSettings = new MaterialDebugSettings();
public LightingDebugSettings lightingDebugSettings = new LightingDebugSettings();

public static int[] debugScreenSpaceTracingProxyValues = null;
public static GUIContent[] debugScreenSpaceTracingHiZStrings = null;
public static int[] debugScreenSpaceTracingHiZValues = null;
public static GUIContent[] debugScreenSpaceTracingLinearStrings = null;
public static int[] debugScreenSpaceTracingLinearValues = null;
public static GUIContent[] debuggedAlgorithmStrings = null;
public static int[] debuggedAlgorithmValues = null;
Lit.RefractionSSRayModel m_LastSSRayModel = Lit.RefractionSSRayModel.None;
Lit.ProjectionModel m_LastProjectionModel = Lit.ProjectionModel.None;
ScreenSpaceTracingDebug m_ScreenSpaceTracingDebugData;
public ScreenSpaceTracingDebug screenSpaceTracingDebugData
{

m_ScreenSpaceTracingDebugData = value;
if (m_LastSSRayModel != m_ScreenSpaceTracingDebugData.tracingModel)
m_ScreenSpaceTracingDebugData = value;
if (m_LastProjectionModel != m_ScreenSpaceTracingDebugData.tracingModel)
m_LastSSRayModel = m_ScreenSpaceTracingDebugData.tracingModel;
RefreshScreenSpaceTracingDebug<Lit.RefractionSSRayModel>(null, m_LastSSRayModel);
m_LastProjectionModel = m_ScreenSpaceTracingDebugData.tracingModel;
RefreshScreenSpaceTracingDebug<Lit.ProjectionModel>(null, m_LastProjectionModel);
if (m_ScreenSpaceTracingDebugData.tracingModel != Lit.RefractionSSRayModel.HiZ)
if (m_ScreenSpaceTracingDebugData.tracingModel == Lit.ProjectionModel.Proxy)
{
showSSRayDepthPyramid = false;
showSSRayGrid = false;

var debugScreenSpaceTracingHiZStringsList = new List<GUIContent>();
var debugScreenSpaceTracingProxyStringsList = new List<GUIContent>();
var debugScreenSpaceTracingLinearStringsList = new List<GUIContent>();
var debugScreenSpaceTracingLinearValueList = new List<int>();
if (!g.text.StartsWith("Proxy"))
if (!g.text.StartsWith("Proxy") && !g.text.StartsWith("Linear"))
if (!g.text.StartsWith("HiZ"))
if (!g.text.StartsWith("HiZ") && !g.text.StartsWith("Linear"))
if (!g.text.StartsWith("Proxy") && !g.text.StartsWith("HiZ"))
{
debugScreenSpaceTracingLinearStringsList.Add(g);
debugScreenSpaceTracingLinearValueList.Add(v);
}
}
debugScreenSpaceTracingHiZStrings = debugScreenSpaceTracingHiZStringsList.ToArray();

debugScreenSpaceTracingLinearStrings = debugScreenSpaceTracingLinearStringsList.ToArray();
debugScreenSpaceTracingLinearValues = debugScreenSpaceTracingLinearValueList.ToArray();
debuggedAlgorithmStrings = Enum.GetNames(typeof(Lit.ProjectionModel))
.Select(t => new GUIContent(t))
.ToArray();
debuggedAlgorithmValues = (int[])Enum.GetValues(typeof(Lit.ProjectionModel));
}
public int GetDebugMaterialIndex()

}
}
void SetScreenSpaceTracingRefractionDebugMode(int value)
bool IsScreenSpaceTracingReflectionDebugEnabled()
{
return fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceTracing
&& lightingDebugSettings.debugLightingMode == DebugLightingMode.ScreenSpaceTracingReflection;
}
void SetScreenSpaceTracingReflectionDebugEnabled(bool value)
{
if (value)
{
lightingDebugSettings.debugLightingMode = DebugLightingMode.ScreenSpaceTracingReflection;
fullScreenDebugMode = FullScreenDebugMode.ScreenSpaceTracing;
}
else
{
lightingDebugSettings.debugLightingMode = DebugLightingMode.None;
fullScreenDebugMode = FullScreenDebugMode.None;
}
}
void SetScreenSpaceTracingDebugMode(int value)
lightingDebugSettings.debugLightingMode = DebugLightingMode.ScreenSpaceTracingRefraction;
lightingDebugSettings.debugScreenSpaceTracingMode = (DebugScreenSpaceTracing)value;
}
else

{
var list = new List<DebugUI.Container>();
var refractionContainer = new DebugUI.Container
var settingsContainer = new DebugUI.Container
displayName = "Refraction",
children =
displayName = "Refraction / Reflection",
children =
new DebugUI.BoolField { displayName = "Debug Enabled", getter = IsScreenSpaceTracingRefractionDebugEnabled, setter = SetScreenSpaceTracingRefractionDebugEnabled, onValueChanged = RefreshScreenSpaceTracingDebug },
new DebugUI.BoolField { displayName = "Debug Refraction Enabled", getter = IsScreenSpaceTracingRefractionDebugEnabled, setter = SetScreenSpaceTracingRefractionDebugEnabled, onValueChanged = RefreshScreenSpaceTracingDebug },
new DebugUI.BoolField { displayName = "Debug Reflection Enabled", getter = IsScreenSpaceTracingReflectionDebugEnabled, setter = SetScreenSpaceTracingReflectionDebugEnabled, onValueChanged = RefreshScreenSpaceTracingDebug },
list.Add(refractionContainer);
list.Add(settingsContainer);
if (IsScreenSpaceTracingRefractionDebugEnabled())
if (IsScreenSpaceTracingRefractionDebugEnabled()
|| IsScreenSpaceTracingReflectionDebugEnabled())
var debuggedAlgorithmCBName = string.Format("_SS{0}DebuggedAlgorithm", IsScreenSpaceTracingRefractionDebugEnabled() ? "Refraction" : "Reflection");
var debugSettingsContainer = new DebugUI.Container
{
displayName = "Debug Settings",

new DebugUI.Value { displayName = "SSRay Model", getter = () => screenSpaceTracingDebugData.tracingModel }
new DebugUI.Value { displayName = string.Empty, getter = () => "Warning: In forward only mode, debugging information may not be representative of the rendered pixel." },
new DebugUI.Value { displayName = "SSRay Model", getter = () => screenSpaceTracingDebugData.tracingModel },
new DebugUI.EnumField { displayName = "Debugged Algorithm", getter = () => Shader.GetGlobalInt(debuggedAlgorithmCBName), setter = v => Shader.SetGlobalInt(debuggedAlgorithmCBName, v), enumValues = debuggedAlgorithmValues, enumNames = debuggedAlgorithmStrings },
}
};
settingsContainer.children.Add(debugSettingsContainer);
var lightingDebug = new DebugUI.Container
{
displayName = "Lighting",
children =
{
new DebugUI.Value { displayName = "Sampled Color", getter = () => FormatVector(screenSpaceTracingDebugData.lightingSampledColor) },
new DebugUI.Value { displayName = "Specular FGD", getter = () => FormatVector(screenSpaceTracingDebugData.lightingSpecularFGD) },
new DebugUI.Value { displayName = "Weight", getter = () => screenSpaceTracingDebugData.lightingWeight.ToString("F6") },
new DebugUI.Value { displayName = "Weighted Color", getter = () => FormatVector(Vector3.Scale(screenSpaceTracingDebugData.lightingSpecularFGD, screenSpaceTracingDebugData.lightingSampledColor) * screenSpaceTracingDebugData.lightingWeight) },
refractionContainer.children.Add(debugSettingsContainer);
case Lit.RefractionSSRayModel.Proxy:
case Lit.ProjectionModel.Proxy:
new DebugUI.EnumField { displayName = "Debug Mode", getter = GetDebugLightingSubMode, setter = SetScreenSpaceTracingRefractionDebugMode, enumNames = debugScreenSpaceTracingProxyStrings, enumValues = debugScreenSpaceTracingProxyValues, onValueChanged = RefreshScreenSpaceTracingDebug }
new DebugUI.EnumField { displayName = "Debug Mode", getter = GetDebugLightingSubMode, setter = SetScreenSpaceTracingDebugMode, enumNames = debugScreenSpaceTracingProxyStrings, enumValues = debugScreenSpaceTracingProxyValues, onValueChanged = RefreshScreenSpaceTracingDebug }
refractionContainer.children.Add(
settingsContainer.children.Add(
new DebugUI.Value { displayName = "Hit Success", getter = () => screenSpaceTracingDebugData.endHitSuccess },
new DebugUI.Value { displayName = "Hit Success", getter = () => screenSpaceTracingDebugData.endHitSuccess != 0 },
new DebugUI.Value { displayName = "Proxy Shape", getter = () => screenSpaceTracingDebugData.proxyShapeType },
new DebugUI.Value { displayName = "Projection Distance", getter = () => screenSpaceTracingDebugData.projectionDistance },
new DebugUI.Value { displayName = "Start Position", getter = () => screenSpaceTracingDebugData.loopStartPositionSS },

}
}
},
lightingDebug
case Lit.RefractionSSRayModel.HiZ:
case Lit.ProjectionModel.HiZ:
new DebugUI.EnumField { displayName = "Debug Mode", getter = GetDebugLightingSubMode, setter = SetScreenSpaceTracingRefractionDebugMode, enumNames = debugScreenSpaceTracingHiZStrings, enumValues = debugScreenSpaceTracingHiZValues, onValueChanged = RefreshScreenSpaceTracingDebug },
new DebugUI.EnumField { displayName = "Debug Mode", getter = GetDebugLightingSubMode, setter = SetScreenSpaceTracingDebugMode, enumNames = debugScreenSpaceTracingHiZStrings, enumValues = debugScreenSpaceTracingHiZValues, onValueChanged = RefreshScreenSpaceTracingDebug },
new DebugUI.BoolField { displayName = "Display Grid", getter = () => showSSRayGrid, setter = v => showSSRayGrid = v },
new DebugUI.BoolField { displayName = "Display Depth", getter = () => showSSRayDepthPyramid, setter = v => showSSRayDepthPyramid = v },
new DebugUI.BoolField { displayName = "Display Sampled Color", getter = () => showSSSampledColor, setter = v => showSSSampledColor = v }
);
settingsContainer.children.Add(
new DebugUI.Container
{
displayName = "Debug Values (loop)",
children =
{
new DebugUI.Value { displayName = "Hit Success", getter = () => screenSpaceTracingDebugData.endHitSuccess != 0 },
new DebugUI.Value { displayName = "Start Position", getter = () => screenSpaceTracingDebugData.loopStartPositionSS },
new DebugUI.Value { displayName = "Start Linear Depth", getter = () => screenSpaceTracingDebugData.loopStartLinearDepth },
new DebugUI.Value { displayName = "Ray Direction SS", getter = () => new Vector2(screenSpaceTracingDebugData.loopRayDirectionSS.x, screenSpaceTracingDebugData.loopRayDirectionSS.y) },
new DebugUI.Value { displayName = "Ray Depth", getter = () => 1f / screenSpaceTracingDebugData.loopRayDirectionSS.z },
new DebugUI.Value { displayName = "End Position", getter = () => screenSpaceTracingDebugData.endPositionSS },
new DebugUI.Value { displayName = "End Linear Depth", getter = () => screenSpaceTracingDebugData.endLinearDepth },
new DebugUI.Value { displayName = "Hit Weight", getter = () => screenSpaceTracingDebugData.endHitWeight.ToString("F4") },
}
},
new DebugUI.Container
{
displayName = "Debug Values (iteration)",
children =
{
new DebugUI.Value { displayName = "Iteration", getter = () => string.Format("{0}/{1}", screenSpaceTracingDebugData.iteration, screenSpaceTracingDebugData.loopIterationMax) },
new DebugUI.Value { displayName = "Position SS", getter = () => new Vector2(screenSpaceTracingDebugData.iterationPositionSS.x, screenSpaceTracingDebugData.iterationPositionSS.y) },
new DebugUI.Value { displayName = "Depth", getter = () => 1f / screenSpaceTracingDebugData.iterationPositionSS.z },
new DebugUI.Value { displayName = "Depth Buffer Min/Min + Thickness/Max", getter = () => string.Format("{0}/{1}/{2}", screenSpaceTracingDebugData.iterationLinearDepthBufferMin, screenSpaceTracingDebugData.iterationLinearDepthBufferMinThickness, screenSpaceTracingDebugData.iterationLinearDepthBufferMax) },
new DebugUI.Value { displayName = "Intersection Thickness", getter = () => (screenSpaceTracingDebugData.iterationLinearDepthBufferMinThickness - 1f / screenSpaceTracingDebugData.iterationPositionSS.z).ToString("F6") },
new DebugUI.Value { displayName = "Depth Buffer Diff (Max - Min)", getter = () => (screenSpaceTracingDebugData.iterationLinearDepthBufferMax - screenSpaceTracingDebugData.iterationLinearDepthBufferMin).ToString("F6") },
new DebugUI.Value { displayName = "Intersect Depth Buffer", getter = () => screenSpaceTracingDebugData.intersectDepthBuffer },
new DebugUI.Value { displayName = "Mip Level", getter = () => screenSpaceTracingDebugData.iterationMipLevel },
new DebugUI.Value { displayName = "Cell Id", getter = () => screenSpaceTracingDebugData.iterationCellId },
new DebugUI.Value { displayName = "Cell Size", getter = () => screenSpaceTracingDebugData.iterationCellSize },
new DebugUI.Value { displayName = "Intersection Kind", getter = () => k_HiZIntersectionKind[(int)screenSpaceTracingDebugData.iterationIntersectionKind] },
}
},
lightingDebug
);
break;
}
case Lit.ProjectionModel.Linear:
{
debugSettingsContainer.children.Add(
new DebugUI.EnumField { displayName = "Debug Mode", getter = GetDebugLightingSubMode, setter = SetScreenSpaceTracingDebugMode, enumNames = debugScreenSpaceTracingLinearStrings, enumValues = debugScreenSpaceTracingLinearValues, onValueChanged = RefreshScreenSpaceTracingDebug },
refractionContainer.children.Add(
settingsContainer.children.Add(
new DebugUI.Value { displayName = "Hit Success", getter = () => screenSpaceTracingDebugData.endHitSuccess },
new DebugUI.Value { displayName = "Hit Success", getter = () => screenSpaceTracingDebugData.endHitSuccess != 0 },
new DebugUI.Value { displayName = "Start Position", getter = () => screenSpaceTracingDebugData.loopStartPositionSS },
new DebugUI.Value { displayName = "Start Linear Depth", getter = () => screenSpaceTracingDebugData.loopStartLinearDepth },
new DebugUI.Value { displayName = "Ray Direction SS", getter = () => new Vector2(screenSpaceTracingDebugData.loopRayDirectionSS.x, screenSpaceTracingDebugData.loopRayDirectionSS.y) },

new DebugUI.Value { displayName = "Hit Weight", getter = () => screenSpaceTracingDebugData.endHitWeight.ToString("F4") },
}
},
new DebugUI.Container

new DebugUI.Value { displayName = "Iteration", getter = () => string.Format("{0}/{1}", screenSpaceTracingDebugData.iteration, screenSpaceTracingDebugData.loopIterationMax) },
new DebugUI.Value { displayName = "Position SS", getter = () => new Vector2(screenSpaceTracingDebugData.iterationPositionSS.x, screenSpaceTracingDebugData.iterationPositionSS.y) },
new DebugUI.Value { displayName = "Depth", getter = () => 1f / screenSpaceTracingDebugData.iterationPositionSS.z },
new DebugUI.Value { displayName = "Depth Buffer", getter = () => screenSpaceTracingDebugData.iterationLinearDepthBuffer },
new DebugUI.Value { displayName = "Mip Level", getter = () => string.Format("{0}/{1}", screenSpaceTracingDebugData.iterationMipLevel, screenSpaceTracingDebugData.loopMipLevelMax) },
new DebugUI.Value { displayName = "Intersection kind", getter = () => screenSpaceTracingDebugData.iterationIntersectionKind },
new DebugUI.Value { displayName = "Intersection Thickness", getter = () => (screenSpaceTracingDebugData.iterationLinearDepthBufferMinThickness - 1f / screenSpaceTracingDebugData.iterationPositionSS.z).ToString("F6") },
new DebugUI.Value { displayName = "Depth Buffer Min/Min + Thickness/Max", getter = () => string.Format("{0}/{1}/{2}", screenSpaceTracingDebugData.iterationLinearDepthBufferMin, screenSpaceTracingDebugData.iterationLinearDepthBufferMinThickness, screenSpaceTracingDebugData.iterationLinearDepthBufferMax) },
new DebugUI.Value { displayName = "Intersect Depth Buffer", getter = () => screenSpaceTracingDebugData.intersectDepthBuffer },
new DebugUI.Value { displayName = "Mip Level", getter = () => screenSpaceTracingDebugData.iterationMipLevel },
}
},
lightingDebug
);
break;
}

values[index] = i;
index++;
}
}
static string FormatVector(Vector3 v)
{
return string.Format("({0:F6}, {1:F6}, {2:F6})", v.x, v.y, v.z);
}
}
}

45
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs.hlsl


float3 iterationPositionSS;
uint iterationMipLevel;
uint iteration;
float iterationLinearDepthBuffer;
float iterationLinearDepthBufferMin;
float iterationLinearDepthBufferMax;
float iterationLinearDepthBufferMinThickness;
bool endHitSuccess;
int endHitSuccess;
float endHitWeight;
float3 lightingSampledColor;
float3 lightingSpecularFGD;
float lightingWeight;
float2 padding;
};
//

{
return value.iteration;
}
float GetIterationLinearDepthBuffer(ScreenSpaceTracingDebug value)
float GetIterationLinearDepthBufferMin(ScreenSpaceTracingDebug value)
return value.iterationLinearDepthBuffer;
return value.iterationLinearDepthBufferMin;
}
float GetIterationLinearDepthBufferMax(ScreenSpaceTracingDebug value)
{
return value.iterationLinearDepthBufferMax;
}
float GetIterationLinearDepthBufferMinThickness(ScreenSpaceTracingDebug value)
{
return value.iterationLinearDepthBufferMinThickness;
}
int GetIterationIntersectionKind(ScreenSpaceTracingDebug value)
{

{
return value.projectionDistance;
}
bool GetEndHitSuccess(ScreenSpaceTracingDebug value)
int GetEndHitSuccess(ScreenSpaceTracingDebug value)
{
return value.endHitSuccess;
}

uint GetEndPositionSSY(ScreenSpaceTracingDebug value)
{
return value.endPositionSSY;
}
float GetEndHitWeight(ScreenSpaceTracingDebug value)
{
return value.endHitWeight;
}
float3 GetLightingSampledColor(ScreenSpaceTracingDebug value)
{
return value.lightingSampledColor;
}
float3 GetLightingSpecularFGD(ScreenSpaceTracingDebug value)
{
return value.lightingSpecularFGD;
}
float GetLightingWeight(ScreenSpaceTracingDebug value)
{
return value.lightingWeight;
}
float2 GetPadding(ScreenSpaceTracingDebug value)
{
return value.padding;
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.hlsl


CBUFFER_END
TEXTURE2D(_DebugFont); // Debug font to write string in shader
RWStructuredBuffer<ScreenSpaceTracingDebug> _DebugScreenSpaceTracingData;
RWStructuredBuffer<ScreenSpaceTracingDebug> _DebugScreenSpaceTracingData : register(u7); // TODO: Change the register number for PS4
void GetPropertiesDataDebug(uint paramId, inout float3 result, inout bool needLinearToSRGB)
{

83
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugFullScreen.shader


float _RequireToFlipInputTexture;
float _ShowGrid;
float _ShowDepthPyramidDebug;
float _ShowSSRaySampledColor;
CBUFFER_END
TEXTURE2D(_DebugFullScreenTexture);

float dist1 = abs(dot(rel_p, float2(dir.y, -dir.x)));
float dist2 = abs(dot(rel_p, dir)) - 0.5 * len;
return max(dist1, dist2);
}
void ColorWidget(
int2 positionSS,
float4 rect,
float3 borderColor,
float3 innerColor,
inout float4 debugColor,
inout float4 backgroundColor
)
{
const float4 distToRects = float4(rect.zw - positionSS, positionSS - rect.xy);
if (all(distToRects > 0))
{
const float distToRect = min(min(distToRects.x, distToRects.y), min(distToRects.z, distToRects.w));
const float sdf = clamp(distToRect * 0.5, 0, 1);
debugColor = float4(
lerp(borderColor, innerColor, sdf),
1.0
);
backgroundColor.a = 0;
}
}
float DrawArrow(float2 texcoord, float body, float head, float height, float linewidth, float antialias)

ScreenSpaceTracingDebug debug = _DebugScreenSpaceTracingData[0];
// Fetch Depth Buffer and Position Inputs
const float deviceDepth = LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, int2(input.positionCS.xy) >> debug.iterationMipLevel, debug.iterationMipLevel).r;
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, deviceDepth, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP);
const float2 deviceDepth = LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, int2(input.positionCS.xy) >> debug.iterationMipLevel, debug.iterationMipLevel).rg;
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, deviceDepth.r, UNITY_MATRIX_I_VP, UNITY_MATRIX_VP);
const uint2 loopStartPositionSS = uint2(debug.loopStartPositionSSX, debug.loopStartPositionSSY);
const uint2 endPositionSS = uint2(debug.endPositionSSX, debug.endPositionSSY);
uint2 loopStartPositionSS = uint2(debug.loopStartPositionSSX, debug.loopStartPositionSSY);
uint2 endPositionSS = uint2(debug.endPositionSSX, debug.endPositionSSY);
float3 iterationPositionSS = debug.iterationPositionSS;
if (_RequireToFlipInputTexture > 0)
{
loopStartPositionSS.y = uint(_ScreenSize.y) - loopStartPositionSS.y;
endPositionSS.y = uint(_ScreenSize.y) - endPositionSS.y;
iterationPositionSS.y = _ScreenSize.y - iterationPositionSS.y;
}
float distanceToPosition = FLT_MAX;
float positionSDF = 0;

const float raySegmentSDF = clamp(1 - distanceToRaySegment, 0, 1);
float cellSDF = 0;
float debugLinearDepth = 0;
if (debug.tracingModel == REFRACTIONSSRAYMODEL_HI_Z)
float2 debugLinearDepth = float2(LinearEyeDepth(deviceDepth.r, _ZBufferParams), LinearEyeDepth(deviceDepth.g, _ZBufferParams));
if (debug.tracingModel == PROJECTIONMODEL_HI_Z
|| debug.tracingModel == PROJECTIONMODEL_LINEAR)
distanceToPosition = length(int2(posInput.positionSS) - int2(debug.iterationPositionSS.xy));
distanceToPosition = length(int2(posInput.positionSS) - int2(iterationPositionSS.xy));
positionSDF = clamp(circleRadius - distanceToPosition, 0, 1);
// Grid rendering

cellSDF = max(distanceToCell.x, distanceToCell.y) * _ShowGrid;
debugLinearDepth = posInput.linearDepth;
}
col = float4(

const float w = clamp(1 - startPositionRingSDF - positionRingSDF, 0, 1);
col.rgb = col.rgb * w + float3(1, 1, 1) * (1 - w);
// Draw color widgets
if (_ShowSSRaySampledColor == 1)
{
// Sampled color
ColorWidget(
posInput.positionSS,
float4(10, 10, 50, 50) + endPositionSS.xyxy,
float3(1, 0, 0), debug.lightingSampledColor,
col,
color
);
// Specular FGD
ColorWidget(
posInput.positionSS,
float4(-50, 10, -10, 50) + endPositionSS.xyxy,
float3(0, 1, 0), debug.lightingSpecularFGD,
col,
color
);
// Weighted
ColorWidget(
posInput.positionSS,
float4(-50, -50, -10, -10) + endPositionSS.xyxy,
float3(0, 0, 1), debug.lightingSampledColor * debug.lightingSpecularFGD * debug.lightingWeight,
col,
color
);
}
color.rgb = frac(float3(debugLinearDepth, debugLinearDepth, debugLinearDepth) * 0.1);
color.rgb = float3(frac(debugLinearDepth * 0.1), 0.0);
col = float4(col.rgb * col.a + color.rgb, 1);
col = float4(col.rgb * col.a + color.rgb * color.a, 1);
return col;
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/LightingDebug.cs


RayDirWS,
HitDepth,
HitSuccess,
TracingModel,
HiZIntersectionKind
HiZIntersectionKind,
HiZHitWeight,
HiZSampledColor,
HiZDiff,
LinearPositionNDC,
LinearRayDirNDC,
LinearIterationCount,
LinearHitWeight,
LinearSampledColor
}
public enum ShadowMapDebugMode

19
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/LightingDebug.cs.hlsl


#define DEBUGSCREENSPACETRACING_RAY_DIR_WS (2)
#define DEBUGSCREENSPACETRACING_HIT_DEPTH (3)
#define DEBUGSCREENSPACETRACING_HIT_SUCCESS (4)
#define DEBUGSCREENSPACETRACING_HI_ZPOSITION_NDC (5)
#define DEBUGSCREENSPACETRACING_HI_ZRAY_DIR_NDC (6)
#define DEBUGSCREENSPACETRACING_HI_ZITERATION_COUNT (7)
#define DEBUGSCREENSPACETRACING_HI_ZMAX_USED_MIP_LEVEL (8)
#define DEBUGSCREENSPACETRACING_HI_ZINTERSECTION_KIND (9)
#define DEBUGSCREENSPACETRACING_TRACING_MODEL (5)
#define DEBUGSCREENSPACETRACING_HI_ZPOSITION_NDC (6)
#define DEBUGSCREENSPACETRACING_HI_ZRAY_DIR_NDC (7)
#define DEBUGSCREENSPACETRACING_HI_ZITERATION_COUNT (8)
#define DEBUGSCREENSPACETRACING_HI_ZMAX_USED_MIP_LEVEL (9)
#define DEBUGSCREENSPACETRACING_HI_ZINTERSECTION_KIND (10)
#define DEBUGSCREENSPACETRACING_HI_ZHIT_WEIGHT (11)
#define DEBUGSCREENSPACETRACING_HI_ZSAMPLED_COLOR (12)
#define DEBUGSCREENSPACETRACING_HI_ZDIFF (13)
#define DEBUGSCREENSPACETRACING_LINEAR_POSITION_NDC (14)
#define DEBUGSCREENSPACETRACING_LINEAR_RAY_DIR_NDC (15)
#define DEBUGSCREENSPACETRACING_LINEAR_ITERATION_COUNT (16)
#define DEBUGSCREENSPACETRACING_LINEAR_HIT_WEIGHT (17)
#define DEBUGSCREENSPACETRACING_LINEAR_SAMPLED_COLOR (18)
#endif

37
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ScreenSpaceRefractionEditor.cs


using System.Collections;
using UnityEngine;
using UnityEditor;
using UnityEditor.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.Rendering.HDPipeline
namespace UnityEditor.Experimental.Rendering.HDPipeline
public class ScreenSpaceRefractionEditor : VolumeComponentEditor
public class ScreenSpaceRefractionEditor : ScreenSpaceLightingEditor
SerializedDataParameter m_RayMinLevel;
SerializedDataParameter m_RayMaxLevel;
SerializedDataParameter m_RayMaxIterations;
SerializedDataParameter m_RayDepthSuccessBias;
SerializedDataParameter m_ScreenWeightDistance;
public override void OnEnable()
{
var o = new PropertyFetcher<ScreenSpaceRefraction>(serializedObject);
m_RayMinLevel = Unpack(o.Find(x => x.rayMinLevel));
m_RayMaxLevel = Unpack(o.Find(x => x.rayMaxLevel));
m_RayMaxIterations = Unpack(o.Find(x => x.rayMaxIterations));
m_RayDepthSuccessBias = Unpack(o.Find(x => x.rayDepthSuccessBias));
m_ScreenWeightDistance = Unpack(o.Find(x => x.screenWeightDistance));
}
public override void OnInspectorGUI()
{
EditorGUILayout.LabelField(CoreEditorUtils.GetContent("HiZ Settings"));
PropertyField(m_RayMinLevel, CoreEditorUtils.GetContent("Ray Min Level"));
PropertyField(m_RayMaxLevel, CoreEditorUtils.GetContent("Ray Max Level"));
PropertyField(m_RayMaxIterations, CoreEditorUtils.GetContent("Ray Max Iterations"));
PropertyField(m_RayDepthSuccessBias, CoreEditorUtils.GetContent("Ray Depth Success Bias"));
EditorGUILayout.Separator();
EditorGUILayout.LabelField(CoreEditorUtils.GetContent("Common Settings"));
PropertyField(m_ScreenWeightDistance, CoreEditorUtils.GetContent("Screen Weight Distance"));
}
}
}

16
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/LitUI.cs


// Transparency
public static string refractionModelText = "Refraction Model";
public static GUIContent refractionSSRayModelText = new GUIContent("SSRay Model", "Screen Space Ray Model");
public static GUIContent refractionProjectionModelText = new GUIContent("SSRay Model", "Screen Space Ray Model");
public static GUIContent refractionIorText = new GUIContent("Index of refraction", "Index of refraction");
public static GUIContent refractionThicknessText = new GUIContent("Refraction Thickness", "Thickness for rough refraction");
public static GUIContent refractionThicknessMultiplierText = new GUIContent("Refraction Thickness multiplier (m)", "Thickness multiplier");

protected const string kThicknessMultiplier = "_ThicknessMultiplier";
protected MaterialProperty refractionModel = null;
protected const string kRefractionModel = "_RefractionModel";
protected MaterialProperty refractionSSRayModel = null;
protected const string kRefractionSSRayModel = "_RefractionSSRayModel";
protected MaterialProperty ssrefractionProjectionModel = null;
protected const string kSSRefractionProjectionModel = "_SSRefractionProjectionModel";
protected override bool showBlendModePopup
{

// Transparency
refractionModel = FindProperty(kRefractionModel, props, false);
refractionSSRayModel = FindProperty(kRefractionSSRayModel, props, false);
ssrefractionProjectionModel = FindProperty(kSSRefractionProjectionModel, props, false);
transmittanceColor = FindProperty(kTransmittanceColor, props, false);
transmittanceColorMap = FindProperty(kTransmittanceColorMap, props, false);
atDistance = FindProperty(kATDistance, props, false);

var mode = (Lit.RefractionModel)refractionModel.floatValue;
if (mode != Lit.RefractionModel.None)
{
m_MaterialEditor.ShaderProperty(refractionSSRayModel, Styles.refractionSSRayModelText);
m_MaterialEditor.ShaderProperty(ssrefractionProjectionModel, Styles.refractionProjectionModelText);
m_MaterialEditor.ShaderProperty(ior, Styles.refractionIorText);
blendMode.floatValue = (float)BlendMode.Alpha;

CoreUtils.SetKeyword(material, "_MATERIAL_FEATURE_SPECULAR_COLOR", materialId == BaseLitGUI.MaterialId.LitSpecular);
var refractionModelValue = (Lit.RefractionModel)material.GetFloat(kRefractionModel);
var refractionSSRayModelValue = (Lit.RefractionSSRayModel)material.GetFloat(kRefractionSSRayModel);
var refractionProjectionModelValue = (Lit.ProjectionModel)material.GetFloat(kSSRefractionProjectionModel);
CoreUtils.SetKeyword(material, "_REFRACTION_SSRAY_PROXY", (refractionSSRayModelValue == Lit.RefractionSSRayModel.Proxy) && canHaveRefraction);
CoreUtils.SetKeyword(material, "_REFRACTION_SSRAY_HIZ", (refractionSSRayModelValue == Lit.RefractionSSRayModel.HiZ) && canHaveRefraction);
CoreUtils.SetKeyword(material, "_REFRACTION_SSRAY_PROXY", (refractionProjectionModelValue == Lit.ProjectionModel.Proxy) && canHaveRefraction);
CoreUtils.SetKeyword(material, "_REFRACTION_SSRAY_HIZ", (refractionProjectionModelValue == Lit.ProjectionModel.HiZ) && canHaveRefraction);
}
}
} // namespace UnityEditor

50
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


RTHandles.Release(m_DebugFullScreenTempBuffer);
m_DebugScreenSpaceTracingData.Release();
HDCamera.ClearAll();
}

var ssRefraction = VolumeManager.instance.stack.GetComponent<ScreenSpaceRefraction>()
?? ScreenSpaceRefraction.@default;
ssRefraction.PushShaderParameters(cmd);
var ssReflection = VolumeManager.instance.stack.GetComponent<ScreenSpaceReflection>()
?? ScreenSpaceReflection.@default;
ssReflection.PushShaderParameters(cmd);
hdCamera.SetupGlobalParams(cmd, m_Time, m_LastTime);
hdCamera.SetupGlobalParams(cmd, m_Time, m_LastTime, m_FrameCount);
cmd.SetGlobalInt(HDShaderIDs._SSReflectionEnabled, hdCamera.frameSettings.enableSSR ? 1 : 0);
var previousDepthPyramidRT = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.DepthPyramid);
if (previousDepthPyramidRT != null)

0.0f
));
}
else
{
cmd.SetGlobalTexture(HDShaderIDs._DepthPyramidTexture, Texture2D.blackTexture);
cmd.SetGlobalVector(HDShaderIDs._DepthPyramidSize, Vector4.one);
cmd.SetGlobalVector(HDShaderIDs._DepthPyramidScale, Vector4.one);
}
var previousColorPyramidRT = hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.ColorPyramid);
if (previousColorPyramidRT != null)

Mathf.Log(Mathf.Min(previousColorPyramidRT.rt.width, previousColorPyramidRT.rt.height), 2),
0.0f
));
}
else
{
cmd.SetGlobalTexture(HDShaderIDs._ColorPyramidTexture, Texture2D.blackTexture);
cmd.SetGlobalVector(HDShaderIDs._ColorPyramidSize, Vector4.one);
cmd.SetGlobalVector(HDShaderIDs._ColorPyramidScale, Vector4.one);
}
}
}

// In both forward and deferred, everything opaque should have been rendered at this point so we can safely copy the depth buffer for later processing.
CopyDepthBufferIfNeeded(cmd);
RenderDepthPyramid(hdCamera, cmd, renderContext, FullScreenDebugMode.DepthPyramid);
RenderCameraVelocity(m_CullResults, hdCamera, renderContext, cmd);

// Caution: We require sun light here as some skies use the sun light to render, it means that UpdateSkyEnvironment must be called after PrepareLightsForGPU.
// TODO: Try to arrange code so we can trigger this call earlier and use async compute here to run sky convolution during other passes (once we move convolution shader to compute).
UpdateSkyEnvironment(hdCamera, cmd);
RenderDepthPyramid(hdCamera, cmd, renderContext, FullScreenDebugMode.DepthPyramid);
StopStereoRendering(renderContext, hdCamera);

// Overwrite camera properties set during the shadow pass with the original camera properties.
renderContext.SetupCameraProperties(camera, hdCamera.frameSettings.enableStereo);
hdCamera.SetupGlobalParams(cmd, m_Time, m_LastTime);
hdCamera.SetupGlobalParams(cmd, m_Time, m_LastTime, m_FrameCount);
if (hdCamera.frameSettings.enableStereo)
hdCamera.SetupGlobalStereoParams(cmd);
}

// Assign -1 in tracing model to notifiy we took the data.
// When debugging in forward, we want only the first time the pixel is drawn
data.tracingModel = (Lit.RefractionSSRayModel)(-1);
data.tracingModel = (Lit.ProjectionModel)(-1);
m_DebugScreenSpaceTracingDataArray[0] = data;
m_DebugScreenSpaceTracingData.SetData(m_DebugScreenSpaceTracingDataArray);
}

// Output split lighting for materials asking for it (masked in the stencil buffer)
options.outputSplitLighting = true;
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_CurrentDebugDisplaySettings, m_MRTCache2, m_CameraDepthStencilBuffer, depthTexture, options);
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_CurrentDebugDisplaySettings, m_MRTCache2, m_CameraDepthStencilBuffer, depthTexture, options, m_DebugScreenSpaceTracingData);
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_CurrentDebugDisplaySettings, m_MRTCache2, m_CameraDepthStencilBuffer, depthTexture, options);
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_CurrentDebugDisplaySettings, m_MRTCache2, m_CameraDepthStencilBuffer, depthTexture, options, m_DebugScreenSpaceTracingData);
}
void UpdateSkyEnvironment(HDCamera hdCamera, CommandBuffer cmd)

HDUtils.SetRenderTarget(cmd, hdCamera, m_VelocityBuffer, m_CameraDepthStencilBuffer);
RenderOpaqueRenderList(cullResults, hdCamera, renderContext, cmd, HDShaderPassNames.s_MotionVectorsName, RendererConfiguration.PerObjectMotionVectors);
cmd.SetGlobalTexture(HDShaderIDs._CameraMotionVectorsTexture, m_VelocityBuffer);
cmd.SetGlobalVector(HDShaderIDs._CameraMotionVectorsSize, new Vector4(
m_VelocityBuffer.referenceSize.x,
m_VelocityBuffer.referenceSize.y,
1f / m_VelocityBuffer.referenceSize.x,
1f / m_VelocityBuffer.referenceSize.y
));
cmd.SetGlobalVector(HDShaderIDs._CameraMotionVectorsScale, new Vector4(
m_VelocityBuffer.referenceSize.x / (float)m_VelocityBuffer.rt.width,
m_VelocityBuffer.referenceSize.y / (float)m_VelocityBuffer.rt.height,
1, 0.0f
));
}
}

// If the flag hasn't been set yet on this camera, motion vectors will skip a frame.
hdCamera.camera.depthTextureMode |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth;
HDUtils.DrawFullScreen(cmd, hdCamera, m_CameraMotionVectorsMaterial, m_VelocityBuffer, m_CameraDepthStencilBuffer, null, 0);
PushFullScreenDebugTexture(hdCamera, cmd, m_VelocityBuffer, FullScreenDebugMode.MotionVectors);
}
}

cmd.SetGlobalInt(HDShaderIDs._DebugStep, HDUtils.debugStep);
cmd.SetGlobalInt(HDShaderIDs._ShowGrid, m_CurrentDebugDisplaySettings.showSSRayGrid ? 1 : 0);
cmd.SetGlobalInt(HDShaderIDs._ShowDepthPyramidDebug, m_CurrentDebugDisplaySettings.showSSRayDepthPyramid ? 1 : 0);
cmd.SetGlobalInt(HDShaderIDs._ShowSSRaySampledColor, m_CurrentDebugDisplaySettings.showSSSampledColor ? 1 : 0);
// The DebugNeedsExposure test allows us to set a neutral value if exposure is not needed. This way we don't need to make various tests inside shaders but only in this function.
cmd.SetGlobalFloat(HDShaderIDs._DebugExposure, m_CurrentDebugDisplaySettings.DebugNeedsExposure() ? lightingDebugSettings.debugExposure : 0.0f);

// (i.e. we have perform a flip, we need to flip the input texture)
m_DebugFullScreen.SetFloat(HDShaderIDs._RequireToFlipInputTexture, hdCamera.camera.cameraType != CameraType.SceneView ? 1.0f : 0.0f);
m_DebugFullScreen.SetBuffer(HDShaderIDs._DebugScreenSpaceTracingData, m_DebugScreenSpaceTracingData);
m_DebugFullScreen.SetTexture(HDShaderIDs._DepthPyramidTexture, hdCamera.GetPreviousFrameRT((int)HDCameraFrameHistoryType.DepthPyramid));
m_DebugFullScreen.SetTexture(HDShaderIDs._DepthPyramidTexture, hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.DepthPyramid));
HDUtils.DrawFullScreen(cmd, hdCamera, m_DebugFullScreen, (RenderTargetIdentifier)BuiltinRenderTextureType.CameraTarget);
PushColorPickerDebugTexture(hdCamera, cmd, (RenderTargetIdentifier)BuiltinRenderTextureType.CameraTarget);

22
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs


public static readonly int _DebugExposure = Shader.PropertyToID("_DebugExposure");
public static readonly int _DebugScreenSpaceTracingData = Shader.PropertyToID("_DebugScreenSpaceTracingData");
public static readonly int _ShowGrid = Shader.PropertyToID("_ShowGrid");
public static readonly int _ShowSSRaySampledColor = Shader.PropertyToID("_ShowSSRaySampledColor");
public static readonly int _ShowDepthPyramidDebug = Shader.PropertyToID("_ShowDepthPyramidDebug");
public static readonly int _DebugViewMaterial = Shader.PropertyToID("_DebugViewMaterial");

public static readonly int _UseTileLightList = Shader.PropertyToID("_UseTileLightList");
public static readonly int _FrameCount = Shader.PropertyToID("_FrameCount");
public static readonly int _Time = Shader.PropertyToID("_Time");
public static readonly int _LastTime = Shader.PropertyToID("_LastTime");
public static readonly int _SinTime = Shader.PropertyToID("_SinTime");

Shader.PropertyToID("_SSSBufferTexture3"),
};
public static readonly int _SSRefractionRayMarchBehindObjects = Shader.PropertyToID("_SSRefractionRayMarchBehindObjects");
public static readonly int _SSRefractionRayMaxScreenDistance = Shader.PropertyToID("_SSRefractionRayMaxScreenDistance");
public static readonly int _SSRefractionRayBlendScreenDistance = Shader.PropertyToID("_SSRefractionRayBlendScreenDistance");
public static readonly int _SSRefractionRayLevel = Shader.PropertyToID("_SSRefractionRayLevel");
public static readonly int _SSRefractionRayDepthSuccessBias = Shader.PropertyToID("_SSRefractionRayDepthSuccessBias");
public static readonly int _SSRefractionDepthBufferThickness = Shader.PropertyToID("_SSRefractionDepthBufferThickness");
public static readonly int _SSReflectionRayMarchBehindObjects = Shader.PropertyToID("_SSReflectionRayMarchBehindObjects");
public static readonly int _SSReflectionRayMaxScreenDistance = Shader.PropertyToID("_SSReflectionRayMaxScreenDistance");
public static readonly int _SSReflectionRayBlendScreenDistance = Shader.PropertyToID("_SSReflectionRayBlendScreenDistance");
public static readonly int _SSReflectionRayLevel = Shader.PropertyToID("_SSReflectionRayLevel");
public static readonly int _SSReflectionRayMinLevel = Shader.PropertyToID("_SSReflectionRayMinLevel");
public static readonly int _SSReflectionRayMaxLevel = Shader.PropertyToID("_SSReflectionRayMaxLevel");
public static readonly int _SSReflectionRayMaxIterations = Shader.PropertyToID("_SSReflectionRayMaxIterations");
public static readonly int _SSReflectionDepthBufferThickness = Shader.PropertyToID("_SSReflectionDepthBufferThickness");
public static readonly int _SSReflectionInvScreenWeightDistance = Shader.PropertyToID("_SSReflectionInvScreenWeightDistance");
public static readonly int _SSReflectionProjectionModel = Shader.PropertyToID("_SSReflectionProjectionModel");
public static readonly int _SSReflectionEnabled = Shader.PropertyToID("_SSReflectionEnabled");
public static readonly int _VelocityTexture = Shader.PropertyToID("_VelocityTexture");
public static readonly int _ShadowMaskTexture = Shader.PropertyToID("_ShadowMaskTexture");

public static readonly int _CameraDepthTexture = Shader.PropertyToID("_CameraDepthTexture");
public static readonly int _CameraMotionVectorsTexture = Shader.PropertyToID("_CameraMotionVectorsTexture");
public static readonly int _CameraMotionVectorsSize = Shader.PropertyToID("_CameraMotionVectorsSize");
public static readonly int _CameraMotionVectorsScale = Shader.PropertyToID("_CameraMotionVectorsScale");
public static readonly int _FullScreenDebugMode = Shader.PropertyToID("_FullScreenDebugMode");
public static readonly int _InputCubemap = Shader.PropertyToID("_InputCubemap");

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/GlobalIlluminationUtils.cs


// Note that the HDRI is correctly integrated in the GlobalIllumination system, we don't need to do anything regarding it.
#if UNITY_EDITOR
#endif
ld.shadow = (byte)(l.shadows != LightShadows.None ? 1 : 0);

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs


public void RenderDeferredLighting( HDCamera hdCamera, CommandBuffer cmd, DebugDisplaySettings debugDisplaySettings,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer, RenderTargetIdentifier depthTexture,
LightingPassOptions options)
LightingPassOptions options, ComputeBuffer debugSSTBuffer)
{
cmd.SetGlobalBuffer(HDShaderIDs.g_vLightListGlobal, s_LightList);

using (new ProfilingSample(cmd, sLabel, CustomSamplerId.TPRenderDeferredLighting.GetSampler()))
{
var camera = hdCamera.camera;
var ssReflection = VolumeManager.instance.stack.GetComponent<ScreenSpaceReflection>() ?? ScreenSpaceReflection.@default;
// Compute path
if (m_FrameSettings.lightLoopSettings.enableTileAndCluster && m_FrameSettings.lightLoopSettings.enableComputeLightEvaluation)

cmd.SetComputeTextureParam(deferredComputeShader, kernel, HDShaderIDs.specularLightingUAV, colorBuffers[0]);
cmd.SetComputeTextureParam(deferredComputeShader, kernel, HDShaderIDs.diffuseLightingUAV, colorBuffers[1]);
if (debugDisplaySettings.lightingDebugSettings.debugLightingMode == DebugLightingMode.ScreenSpaceTracingReflection)
cmd.SetComputeBufferParam(deferredComputeShader, kernel, HDShaderIDs._DebugScreenSpaceTracingData, debugSSTBuffer);
// always do deferred lighting in blocks of 16x16 (not same as tiled light size)
if (enableFeatureVariants)

currentLightingMaterial.SetInt(HDShaderIDs._StencilCmp, (int)CompareFunction.Equal);
}
var debugSSTThisFrame = debugDisplaySettings.lightingDebugSettings.debugLightingMode == DebugLightingMode.ScreenSpaceTracingReflection;
if (debugSSTThisFrame)
cmd.SetRandomWriteTarget(7, debugSSTBuffer);
if (debugSSTThisFrame)
cmd.ClearRandomWriteTargets();
}
}
} // End profiling

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/PlanarReflectionProbe.cs


get
{
return m_ProxyVolumeReference != null
? m_ProxyVolumeReference.proxyVolume.boxSize * 0.5f
? m_ProxyVolumeReference.proxyVolume.extents
: influenceVolume.boxBaseSize;
}
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ProbeWrapper.cs


get
{
return additional.proxyVolumeComponent != null
? additional.proxyVolumeComponent.proxyVolume.boxSize * 0.5f
? additional.proxyVolumeComponent.proxyVolume.extents
: influenceExtents;
}
}

34
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceRefraction.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[Serializable]
public class ScreenSpaceRefraction : VolumeComponent
public class ScreenSpaceRefraction : ScreenSpaceLighting
{
static ScreenSpaceRefraction s_Default = null;
public static ScreenSpaceRefraction @default

}
}
public IntParameter rayMinLevel = new IntParameter(2);
public IntParameter rayMaxLevel = new IntParameter(6);
public IntParameter rayMaxIterations = new IntParameter(32);
public FloatParameter rayDepthSuccessBias = new FloatParameter(0.1f);
public ClampedFloatParameter screenWeightDistance = new ClampedFloatParameter(0.1f, 0, 1);
public void PushShaderParameters(CommandBuffer cmd)
protected override void FetchIDs(
out int rayLevelID,
out int rayMinLevelID,
out int rayMaxLevelID,
out int rayMaxIterationsID,
out int depthBufferThicknessID,
out int invScreenWeightDistanceID,
out int rayMaxScreenDistanceID,
out int rayBlendScreenDistanceID,
out int rayMarchBehindObjectsID
)
cmd.SetGlobalInt(HDShaderIDs._SSRefractionRayMinLevel, rayMinLevel.value);
cmd.SetGlobalInt(HDShaderIDs._SSRefractionRayMaxLevel, rayMaxLevel.value);
cmd.SetGlobalInt(HDShaderIDs._SSRefractionRayMaxIterations, rayMaxIterations.value);
cmd.SetGlobalFloat(HDShaderIDs._SSRefractionRayDepthSuccessBias, rayDepthSuccessBias.value);
cmd.SetGlobalFloat(HDShaderIDs._SSRefractionInvScreenWeightDistance, 1f / screenWeightDistance.value);
rayLevelID = HDShaderIDs._SSRefractionRayLevel;
rayMinLevelID = HDShaderIDs._SSRefractionRayMinLevel;
rayMaxLevelID = HDShaderIDs._SSRefractionRayMaxLevel;
rayMaxIterationsID = HDShaderIDs._SSRefractionRayMaxIterations;
depthBufferThicknessID = HDShaderIDs._SSRefractionDepthBufferThickness;
invScreenWeightDistanceID = HDShaderIDs._SSRefractionInvScreenWeightDistance;
rayMaxScreenDistanceID = HDShaderIDs._SSRefractionRayMaxScreenDistance;
rayBlendScreenDistanceID = HDShaderIDs._SSRefractionRayBlendScreenDistance;
rayMarchBehindObjectsID = HDShaderIDs._SSRefractionRayMarchBehindObjects;
}
}
}

846
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl


#ifndef UNITY_SCREEN_SPACE_TRACING_INCLUDED
#define UNITY_SCREEN_SPACE_TRACING_INCLUDED
// How this file works:
// This file is separated in two sections: 1. Library, 2. Constant Buffer Specific Signatures
//
// 1. Library
// This section contains all function and structures for the Screen Space Tracing.
//
// 2. Constant Buffer Specific Signatures
// This section defines signatures that will use specifics constant buffers.
// Thus you can use the Screen Space Tracing library with different settings.
// It can be usefull to use it for both reflection and refraction but with different settings' sets.
//
//
// To use this file:
// 1. Define the macro SSRTID
// 2. Include the file
// 3. Undef the macro SSRTID
//
//
// Example for reflection:
// #define SSRTID Reflection
// #include "ScreenSpaceTracing.hlsl"
// #undef SSRTID
//
// Use library here, like ScreenSpaceProxyRaycastReflection(...)
// #################################################
// Notes
// #################################################
// Some banding issues can occurs when raymarching the depth buffer.
//
// This can be hidden by offsetting the ray origin with a jitter.
// Combined with a temporal filtering, the banding artifact will be smoothed.
// This will trade banding for noise.
//
// This happens when we raymarch with a ray direction that is quite different from the view vector.
// Exemple when raymarching with a direction perpendicular to the view vector:
//
// Depth buffer far
// |
// v
// near
//
// --------
// hit ==>xx
// xx
//
// fail ===>
// xx
// hit ===>xx
//
// xx
// #################################################
// Screen Space Tracing Library
// #################################################
const float DepthPlaneBias = 1E-5;
// -------------------------------------------------

struct ScreenSpaceRayHit
{
uint2 positionSS; // Position of the hit point (SS)
float2 positionNDC; // Position of the hit point (NDC)
float linearDepth; // Linear depth of the hit point
uint2 positionSS; // Position of the hit point (SS)
float2 positionNDC; // Position of the hit point (NDC)
float linearDepth; // Linear depth of the hit point
#ifdef DEBUG_DISPLAY
float3 debugOutput;

struct ScreenSpaceHiZRaymarchInput
struct ScreenSpaceRaymarchInput
uint maxIterations; // Number of iterations before failing
#ifdef DEBUG_DISPLAY
bool debug;

{
float3 rayOriginWS; // Ray origin (WS)
float3 rayDirWS; // Ray direction (WS)
EnvLightData proxyData;
EnvLightData proxyData; // Proxy to use for raycasting
#ifdef DEBUG_DISPLAY
bool debug;

// -------------------------------------------------
// Calculate the ray origin and direction in SS
// out positionSS : (x, y, 1/depth)
// out raySS : (x, y, 1/depth)
float3 rayOriginWS,
float3 rayDirWS,
uint2 bufferSize,
out float3 positionSS,
out float3 raySS
float3 rayOriginWS, // Ray origin (World Space)
float3 rayDirWS, // Ray direction (World Space)
uint2 bufferSize, // Texture size of screen buffers
out float3 positionSS, // (x, y, 1/linearDepth)
out float3 raySS, // (dx, dy, d(1/linearDepth))
out float rayEndDepth // Linear depth of the end point used to calculate raySS
const float kNearClipPlane = -0.01;
const float kMaxRayTraceDistance = 1000;
float3 rayOriginVS = mul(GetWorldToViewMatrix(), float4(rayOriginWS, 1.0)).xyz;
float3 rayDirVS = mul((float3x3)GetWorldToViewMatrix(), rayDirWS);
// Clip ray to near plane to avoid raymarching behind camera
float rayLength = ((rayOriginVS.z + rayDirVS.z * kMaxRayTraceDistance) > kNearClipPlane)
? ((kNearClipPlane - rayOriginVS.z) / rayDirVS.z)
: kMaxRayTraceDistance;
float3 rayEndWS = rayOriginWS + rayDirWS * 10;
float3 rayEndWS = rayOriginWS + rayDirWS * rayLength;
float4 positionCS = ComputeClipSpacePosition(positionWS, GetWorldToHClipMatrix());
float4 rayEndCS = ComputeClipSpacePosition(rayEndWS, GetWorldToHClipMatrix());

rayEndDepth = rayEndCS.w;
float3 rayStartSS = float3(
positionNDC.xy * bufferSize,

rayEndNDC.xy * bufferSize,
1.0 / rayEndCS.w); // Screen space depth interpolate properly in 1/z
1.0 / rayEndDepth); // Screen space depth interpolate properly in 1/z
}
// Check whether the depth of the ray is above the sampled depth
// Arguments are inversed linear depth
bool IsPositionAboveDepth(float rayDepth, float invLinearDepth)
{
// as depth is inverted, we must invert the check as well
// rayZ > HiZ <=> 1/rayZ < 1/HiZ
return rayDepth > invLinearDepth;
float LoadDepth(float2 positionSS, int level)
float2 LoadDepth(float2 positionSS, int level)
float pyramidDepth = LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, int2(positionSS.xy) >> level, level).r;
float linearDepth = LinearEyeDepth(pyramidDepth, _ZBufferParams);
float2 pyramidDepth = LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, int2(positionSS.xy) >> level, level).rg;
float2 linearDepth = float2(LinearEyeDepth(pyramidDepth.r, _ZBufferParams), LinearEyeDepth(pyramidDepth.g, _ZBufferParams));
float LoadInvDepth(float2 positionSS, int level)
float2 LoadInvDepth(float2 positionSS, int level)
float linearDepth = LoadDepth(positionSS, level);
float invLinearDepth = 1 / linearDepth;
float2 linearDepth = LoadDepth(positionSS, level);
float2 invLinearDepth = 1 / linearDepth;
return invLinearDepth;
}

return positionSS + raySS * t;
}
// Calculate intersection between a ray and a cell
float3 IntersectCellPlanes(
float3 positionSS,
float3 raySS,
float2 invRaySS,
int2 cellId,
uint2 cellSize,
int2 cellPlanes,
float2 crossOffset
float2 CalculateDistanceToCellPlanes(
float3 positionSS, // Ray Origin (Screen Space, 1/LinearDepth)
float2 invRaySS, // 1/RayDirection
int2 cellId, // (Row, Colum) of the cell
uint2 cellSize, // Size of the cell in pixel
int2 cellPlanes // Planes to intersect (one of (0,0), (1, 0), (0, 1), (1, 1))
const float SQRT_2 = sqrt(2);
const float CellPlaneBias = 1E-2;
return distanceToCellAxes;
}
// Calculate intersection between a ray and a cell
float3 IntersectCellPlanes(
float3 positionSS, // Ray Origin (Screen Space, 1/LinearDepth)
float3 raySS, // Ray Direction (Screen Space, 1/LinearDepth)
float2 invRaySS, // 1/RayDirection
int2 cellId, // (Row, Colum) of the cell
uint2 cellSize, // Size of the cell in pixel
int2 cellPlanes, // Planes to intersect (one of (0,0), (1, 0), (0, 1), (1, 1))
float2 crossOffset // Offset to use to ensure cell boundary crossing
)
{
float2 distanceToCellAxes = CalculateDistanceToCellPlanes(
positionSS,
invRaySS,
cellId,
cellSize,
cellPlanes
);
// Offset by 1E-3 to ensure cell boundary crossing
// Offset to ensure cell crossing
+ CellPlaneBias;
+ 0.1;
// Interpolate screen space to get next test point
float3 testHitPositionSS = positionSS + raySS * t;

float CalculateHitWeight(
ScreenSpaceRayHit hit,
float2 startPositionSS,
float minLinearDepth,
float settingsDepthBufferThickness,
float settingsRayMaxScreenDistance,
float settingsRayBlendScreenDistance
)
{
// Blend when the hit is near the thickness of the object
//float thicknessWeight = clamp(1 - (hit.linearDepth - minLinearDepth) / settingsDepthBufferThickness, 0, 1);
// Blend when the ray when the raymarched distance is too long
float2 screenDistanceNDC = abs(hit.positionSS.xy - startPositionSS) * _ScreenSize.zw;
float2 screenDistanceWeights = clamp((settingsRayMaxScreenDistance - screenDistanceNDC) / settingsRayBlendScreenDistance, 0, 1);
float screenDistanceWeight = min(screenDistanceWeights.x, screenDistanceWeights.y);
// return thicknessWeight * screenDistanceWeight;
return screenDistanceWeight;
}
#ifdef DEBUG_DISPLAY
// -------------------------------------------------
// Debug Utilities

float3 rayDirWS,
bool hitSuccessful,
int tracingModel,
inout ScreenSpaceRayHit hit
)
{

hit.debugOutput = frac(hit.linearDepth * 0.1);
break;
case DEBUGSCREENSPACETRACING_HIT_SUCCESS:
hit.debugOutput = hitSuccessful;
hit.debugOutput = GetIndexColor(hitSuccessful ? 1 : 2);
break;
case DEBUGSCREENSPACETRACING_TRACING_MODEL:
hit.debugOutput = GetIndexColor(tracingModel);
#endif
void DebugComputeHiZOutput(
int iteration,
float3 startPositionSS,
float3 rayDirSS,
int maxIterations,
int maxUsedLevel,
int maxMipLevel,
int intersectionKind,
inout ScreenSpaceRayHit hit
float SampleBayer4(uint2 positionSS)
{
const float4x4 Bayer4 = float4x4(0, 8, 2, 10,
12, 4, 14, 6,
3, 11, 1, 9,
15, 7, 13, 5) / 16;
return Bayer4[positionSS.x % 4][positionSS.y % 4];
}
// -------------------------------------------------
// Algorithms
// -------------------------------------------------
// -------------------------------------------------
// Algorithm: Linear Raymarching
// -------------------------------------------------
// Based on Digital Differential Analyzer and Morgan McGuire's Screen Space Ray Tracing (http://casual-effects.blogspot.fr/2014/08/screen-space-ray-tracing.html)
//
// Linear raymarching algorithm with precomputed properties
// -------------------------------------------------
bool ScreenSpaceLinearRaymarch(
ScreenSpaceRaymarchInput input,
// Settings
int settingRayLevel, // Mip level to use to ray march depth buffer
uint settingsRayMaxIterations, // Maximum number of iterations (= max number of depth samples)
float settingsDepthBufferThickness, // Bias to use when trying to detect whenever we raymarch behind a surface
float settingsRayMaxScreenDistance, // Maximum screen distance raymarched
float settingsRayBlendScreenDistance, // Distance to blend before maximum screen distance is reached
int settingsDebuggedAlgorithm, // currently debugged algorithm (see PROJECTIONMODEL defines)
// Precomputed properties
float3 startPositionSS, // Start position in Screen Space (x in pixel, y in pixel, z = 1/linearDepth)
float3 raySS, // Ray direction in Screen Space (dx in pixel, dy in pixel, z = 1/endPointLinearDepth - 1/startPointLinearDepth)
float rayEndDepth, // Linear depth of the end point used to calculate raySS.
uint2 bufferSize, // Texture size of screen buffers
// Out
out ScreenSpaceRayHit hit,
out float hitWeight,
out uint iteration
ZERO_INITIALIZE(ScreenSpaceRayHit, hit);
bool hitSuccessful = false;
iteration = 0u;
hitWeight = 0;
int mipLevel = min(max(settingRayLevel, 0), int(_DepthPyramidScale.z));
uint maxIterations = settingsRayMaxIterations;
float3 positionSS = startPositionSS;
raySS /= max(abs(raySS.x), abs(raySS.y));
raySS *= 1 << mipLevel;
#ifdef DEBUG_DISPLAY
float3 debugIterationPositionSS = positionSS;
uint debugIteration = iteration;
float debugIterationLinearDepthBufferMin = 0;
float debugIterationLinearDepthBufferMinThickness = 0;
float debugIterationLinearDepthBufferMax = 0;
#endif
float2 invLinearDepth = float2(0.0, 0.0);
float minLinearDepth = 0;
float minLinearDepthWithThickness = 0;
float positionLinearDepth = 0;
for (iteration = 0u; iteration < maxIterations; ++iteration)
{
positionSS += raySS;
// Sampled as 1/Z so it interpolate properly in screen space.
invLinearDepth = LoadInvDepth(positionSS.xy, mipLevel);
minLinearDepth = 1 / invLinearDepth.r;
minLinearDepthWithThickness = minLinearDepth + settingsDepthBufferThickness;
positionLinearDepth = 1 / positionSS.z;
bool isAboveDepth = positionLinearDepth < minLinearDepth;
bool isAboveThickness = positionLinearDepth < minLinearDepthWithThickness;
bool isBehindDepth = !isAboveThickness;
bool intersectWithDepth = !isAboveDepth && isAboveThickness;
#ifdef DEBUG_DISPLAY
// Fetch post iteration debug values
if (input.debug && _DebugStep >= int(iteration))
{
debugIterationPositionSS = positionSS;
debugIterationLinearDepthBufferMin = minLinearDepth;
debugIterationLinearDepthBufferMinThickness = minLinearDepthWithThickness;
debugIterationLinearDepthBufferMax = 1 / invLinearDepth.g;
debugIteration = iteration;
}
#endif
if (intersectWithDepth)
{
hitSuccessful = true;
break;
}
// Check if we are out of the buffer
if (any(int2(positionSS.xy) > int2(bufferSize))
|| any(positionSS.xy < 0)
)
{
hitSuccessful = false;
break;
}
}
if (iteration >= maxIterations)
hitSuccessful = false;
hit.linearDepth = 1 / positionSS.z;
hit.positionNDC = float2(positionSS.xy) / float2(bufferSize);
hit.positionSS = uint2(positionSS.xy);
// Detect when we go behind an object given a thickness
hitWeight = CalculateHitWeight(
hit,
startPositionSS.xy,
invLinearDepth.r,
settingsDepthBufferThickness,
settingsRayMaxScreenDistance,
settingsRayBlendScreenDistance
);
if (hitWeight <= 0)
hitSuccessful = false;
#ifdef DEBUG_DISPLAY
DebugComputeCommonOutput(input.rayDirWS, hitSuccessful, PROJECTIONMODEL_LINEAR, hit);
case DEBUGSCREENSPACETRACING_HI_ZPOSITION_NDC:
case DEBUGSCREENSPACETRACING_LINEAR_POSITION_NDC:
case DEBUGSCREENSPACETRACING_HI_ZITERATION_COUNT:
hit.debugOutput = float(iteration) / float(maxIterations);
case DEBUGSCREENSPACETRACING_LINEAR_ITERATION_COUNT:
hit.debugOutput = float(iteration) / float(settingsRayMaxIterations);
case DEBUGSCREENSPACETRACING_HI_ZRAY_DIR_NDC:
hit.debugOutput = float3(rayDirSS.xy * 0.5 + 0.5, frac(0.1 / rayDirSS.z));
case DEBUGSCREENSPACETRACING_LINEAR_RAY_DIR_NDC:
hit.debugOutput = float3(raySS.xy * 0.5 + 0.5, frac(0.1 / raySS.z));
case DEBUGSCREENSPACETRACING_HI_ZMAX_USED_MIP_LEVEL:
hit.debugOutput = float(maxUsedLevel) / float(maxMipLevel);
break;
case DEBUGSCREENSPACETRACING_HI_ZINTERSECTION_KIND:
hit.debugOutput = GetIndexColor(intersectionKind);
case DEBUGSCREENSPACETRACING_LINEAR_HIT_WEIGHT:
hit.debugOutput = float3(hitWeight, hitWeight, hitWeight);
}
#endif
#endif
// -------------------------------------------------
// Algorithm: Proxy raycast
// -------------------------------------------------
if (input.debug
&& _DebugScreenSpaceTracingData[0].tracingModel == -1
&& settingsDebuggedAlgorithm == PROJECTIONMODEL_LINEAR
)
{
// Build debug structure
ScreenSpaceTracingDebug debug;
ZERO_INITIALIZE(ScreenSpaceTracingDebug, debug);
#ifdef SSRTID
debug.tracingModel = PROJECTIONMODEL_LINEAR;
debug.loopStartPositionSSX = uint(startPositionSS.x);
debug.loopStartPositionSSY = uint(startPositionSS.y);
debug.loopStartLinearDepth = 1 / startPositionSS.z;
debug.loopRayDirectionSS = raySS;
debug.loopIterationMax = iteration;
debug.iterationPositionSS = debugIterationPositionSS;
debug.iterationMipLevel = mipLevel;
debug.iteration = debugIteration;
debug.iterationLinearDepthBufferMin = debugIterationLinearDepthBufferMin;
debug.iterationLinearDepthBufferMinThickness = debugIterationLinearDepthBufferMinThickness;
debug.iterationLinearDepthBufferMax = debugIterationLinearDepthBufferMax;
debug.endHitSuccess = hitSuccessful;
debug.endLinearDepth = hit.linearDepth;
debug.endPositionSSX = hit.positionSS.x;
debug.endPositionSSY = hit.positionSS.y;
debug.iterationCellSizeW = 1 << mipLevel;
debug.iterationCellSizeH = 1 << mipLevel;
debug.endHitWeight = hitWeight;
#define SSRT_SETTING(name, SSRTID) _SS ## SSRTID ## name
#define SSRT_FUNC(name, SSRTID) name ## SSRTID
_DebugScreenSpaceTracingData[0] = debug;
}
#endif
CBUFFER_START(SSRT_FUNC(UnityScreenSpaceRaymarching, SSRTID))
int SSRT_SETTING(RayMinLevel, SSRTID);
int SSRT_SETTING(RayMaxLevel, SSRTID);
int SSRT_SETTING(RayMaxIterations, SSRTID);
float SSRT_SETTING(RayDepthSuccessBias, SSRTID);
CBUFFER_END
return hitSuccessful;
}
bool SSRT_FUNC(ScreenSpaceProxyRaycast, SSRTID)(
// -------------------------------------------------
// Algorithm: Scene Proxy Raycasting
// -------------------------------------------------
// We perform a raycast against a proxy volume that approximate the current scene.
// Is is a simple shape (Sphere, Box).
// -------------------------------------------------
bool ScreenSpaceProxyRaycast(
// Settings
int settingsDebuggedAlgorithm, // currently debugged algorithm (see PROJECTIONMODEL defines)
// Out
// Initialize loop
ZERO_INITIALIZE(ScreenSpaceRayHit, hit);
float3x3 worldToPS = WorldToProxySpace(input.proxyData);

hit.positionSS = hitPositionSS;
hit.linearDepth = hitLinearDepth;
bool hitSuccessful = true;
bool hitSuccessful = hitLinearDepth > 0; // Negative means that the hit is behind the camera
DebugComputeCommonOutput(input.rayDirWS, hitSuccessful, hit);
DebugComputeCommonOutput(input.rayDirWS, hitSuccessful, PROJECTIONMODEL_PROXY, hit);
if (input.debug)
if (input.debug
&& _DebugScreenSpaceTracingData[0].tracingModel == -1
&& settingsDebuggedAlgorithm == PROJECTIONMODEL_PROXY
)
{
ScreenSpaceTracingDebug debug;
ZERO_INITIALIZE(ScreenSpaceTracingDebug, debug);

debug.tracingModel = REFRACTIONSSRAYMODEL_PROXY;
debug.tracingModel = PROJECTIONMODEL_PROXY;
debug.loopStartPositionSSX = rayOriginSS.x;
debug.loopStartPositionSSY = rayOriginSS.y;
debug.loopStartLinearDepth = rayOriginCS.w;

}
// -------------------------------------------------
// Algorithm: HiZ raymarching
// Algorithm: Linear Raymarching And Scene Proxy Raycasting
// -------------------------------------------------
// Perform a linear raymarching for close hit detection and fallback on proxy raycasting
bool ScreenSpaceLinearProxyRaycast(
ScreenSpaceProxyRaycastInput input,
// Settings (linear)
int settingRayLevel, // Mip level to use to ray march depth buffer
uint settingsRayMaxIterations, // Maximum number of iterations (= max number of depth samples)
float settingsDepthBufferThickness, // Bias to use when trying to detect whenever we raymarch behind a surface
float settingsRayMaxScreenDistance, // Maximum screen distance raymarched
float settingsRayBlendScreenDistance, // Distance to blend before maximum screen distance is reached
// Settings (common)
int settingsDebuggedAlgorithm, // currently debugged algorithm (see PROJECTIONMODEL defines)
// Out
out ScreenSpaceRayHit hit
)
{
// Perform linear raymarch
ScreenSpaceRaymarchInput inputLinear;
inputLinear.rayOriginWS = input.rayOriginWS;
inputLinear.rayDirWS = input.rayDirWS;
#ifdef DEBUG_DISPLAY
inputLinear.debug = input.debug;
#endif
// Based on Yasin Uludag, 2014. "Hi-Z Screen-Space Cone-Traced Reflections", GPU Pro5: Advanced Rendering Techniques
uint2 bufferSize = uint2(_DepthPyramidSize.xy);
// Compute properties for linear raymarch
float3 startPositionSS;
float3 raySS;
float rayEndDepth;
CalculateRaySS(
input.rayOriginWS,
input.rayDirWS,
bufferSize,
startPositionSS,
raySS,
rayEndDepth
);
bool SSRT_FUNC(ScreenSpaceHiZRaymarch, SSRTID)(
ScreenSpaceHiZRaymarchInput input,
out ScreenSpaceRayHit hit
uint iteration;
float hitWeight;
bool hitSuccessful = ScreenSpaceLinearRaymarch(
inputLinear,
// Settings
settingRayLevel,
settingsRayMaxIterations,
settingsDepthBufferThickness,
settingsRayMaxScreenDistance,
settingsRayBlendScreenDistance,
settingsDebuggedAlgorithm,
// Precomputed properties
startPositionSS,
raySS,
rayEndDepth,
bufferSize,
// Out
hit,
hitWeight,
iteration
);
if (!hitSuccessful)
{
hitSuccessful = ScreenSpaceProxyRaycast(
input,
// Settings
settingsDebuggedAlgorithm,
// Out
hit
);
}
return hitSuccessful;
}
// -------------------------------------------------
// Algorithm: HiZ raymarching
// -------------------------------------------------
// Based on Yasin Uludag, 2014. "Hi-Z Screen-Space Cone-Traced Reflections", GPU Pro5: Advanced Rendering Techniques
//
// NB: We perform first a linear raymarch to handle close hits, then we perform the actual HiZ raymarching.
// We do this for two reasons:
// - It is cheaper in case of close hit than starting with HiZ
// - It will start the HiZ algorithm with an offset, preventing false positive hit at ray origin.
// -------------------------------------------------
bool ScreenSpaceHiZRaymarch(
ScreenSpaceRaymarchInput input,
// Settings
uint settingsRayMinLevel, // Minimum mip level to use for ray marching the depth buffer in HiZ
uint settingsRayMaxLevel, // Maximum mip level to use for ray marching the depth buffer in HiZ
uint settingsRayMaxIterations, // Maximum number of iteration for the HiZ raymarching (= number of depth sample for HiZ)
float settingsDepthBufferThickness, // Bias to use when trying to detect whenever we raymarch behind a surface
float settingsRayMaxScreenDistance, // Maximum screen distance raymarched
float settingsRayBlendScreenDistance, // Distance to blend before maximum screen distance is reached
bool settingsRayMarchBehindObjects, // Whether to raymarch behind objects
int settingsDebuggedAlgorithm, // currently debugged algorithm (see PROJECTIONMODEL defines)
// out
out ScreenSpaceRayHit hit,
out float hitWeight
)
{
const float2 CROSS_OFFSET = float2(1, 1);

bool hitSuccessful = true;
hitWeight = 0;
bool hitSuccessful = false;
int minMipLevel = max(SSRT_SETTING(RayMinLevel, SSRTID), 0);
int maxMipLevel = min(SSRT_SETTING(RayMaxLevel, SSRTID), int(_DepthPyramidScale.z));
int minMipLevel = max(settingsRayMinLevel, 0u);
int maxMipLevel = min(settingsRayMaxLevel, uint(_DepthPyramidScale.z));
uint maxIterations = min(input.maxIterations, SSRT_SETTING(RayMaxIterations, SSRTID));
uint maxIterations = settingsRayMaxIterations;
float rayEndDepth;
raySS
raySS,
rayEndDepth
);
#ifdef DEBUG_DISPLAY

float3 debugIterationPositionSS = float3(0, 0, 0);
uint debugIteration = 0u;
uint debugIterationIntersectionKind = 0u;
float debugIterationLinearDepthBuffer = 0;
float debugIterationLinearDepthBufferMin = 0;
float debugIterationLinearDepthBufferMinThickness = 0;
float debugIterationLinearDepthBufferMax = 0;
iteration = 0u;
int intersectionKind = 0;
float raySSLength = length(raySS.xy);
raySS /= raySSLength;

uint2 cellSize = uint2(1, 1) << currentLevel;
float3 positionSS = startPositionSS;
float invHiZDepth = 0;
float2 invLinearDepth = float2(0.0, 0.0);
float positionLinearDepth = 0;
float minLinearDepth = 0;
float minLinearDepthWithThickness = 0;
// Intersect with first cell and add an offsot to avoid HiZ raymarching to stuck at the origin
{
const float epsilon = 1E-3;
const float minTraversal = 2 << currentLevel;
float2 distanceToCellAxes = CalculateDistanceToCellPlanes(
positionSS,
invRaySS,
int2(positionSS.xy) / cellSize,
cellSize,
cellPlanes
);
float t = min(distanceToCellAxes.x * minTraversal + epsilon, distanceToCellAxes.y * minTraversal + epsilon);
positionSS = positionSS + raySS * t;
}
bool isBehindDepth = false;
hitSuccessful = true;
if (iteration >= maxIterations)
{
hitSuccessful = false;

#ifdef DEBUG_DISPLAY
// Fetch pre iteration debug values
if (input.debug && _DebugStep >= iteration)
if (input.debug && _DebugStep >= int(iteration))
debugIterationMipLevel = currentLevel;
#endif

// Sampled as 1/Z so it interpolate properly in screen space.
invHiZDepth = LoadInvDepth(positionSS.xy, currentLevel);
invLinearDepth = LoadInvDepth(positionSS.xy, currentLevel);
positionLinearDepth = 1 / positionSS.z;
minLinearDepth = 1 / invLinearDepth.r;
minLinearDepthWithThickness = minLinearDepth + settingsDepthBufferThickness;
bool isAboveDepth = positionLinearDepth < minLinearDepth;
bool isAboveThickness = positionLinearDepth < minLinearDepthWithThickness;
isBehindDepth = !isAboveThickness;
bool intersectWithDepth = minLinearDepth >= positionLinearDepth && isAboveThickness;
if (IsPositionAboveDepth(positionSS.z, invHiZDepth))
// Nominal case, we raymarch in front of the depth buffer and accelerate with HiZ
if (isAboveDepth)
float3 candidatePositionSS = IntersectDepthPlane(positionSS, raySS, invHiZDepth);
float3 candidatePositionSS = IntersectDepthPlane(positionSS, raySS, invLinearDepth.r);
intersectionKind = HIZINTERSECTIONKIND_DEPTH;

cellId,
cellSize,
cellPlanes,
crossOffset);
crossOffset
);
intersectionKind = HIZINTERSECTIONKIND_CELL;

positionSS = candidatePositionSS;
}
// Raymarching behind object in depth buffer, this case degenerate into a linear search
else if (settingsRayMarchBehindObjects && isBehindDepth && currentLevel <= (minMipLevel + 1))
{
const int2 cellId = int2(positionSS.xy) / cellSize;
positionSS = IntersectCellPlanes(
positionSS,
raySS,
invRaySS,
cellId,
cellSize,
cellPlanes,
crossOffset
);
intersectionKind = HIZINTERSECTIONKIND_CELL;
mipLevelDelta = 1;
}
float4 distancesToBorders = float4(positionSS.xy, bufferSize - positionSS.xy);
float distanceToBorders = min(min(distancesToBorders.x, distancesToBorders.y), min(distancesToBorders.z, distancesToBorders.w));
int minLevelForBorders = int(log2(distanceToBorders));
currentLevel = min(currentLevel, minLevelForBorders);
if (input.debug && _DebugStep >= iteration)
if (input.debug && _DebugStep >= int(iteration))
debugIterationLinearDepthBuffer = 1 / invHiZDepth;
debugIterationLinearDepthBufferMin = 1 / invLinearDepth.r;
debugIterationLinearDepthBufferMinThickness = 1 / invLinearDepth.r + settingsDepthBufferThickness;
debugIterationLinearDepthBufferMax = 1 / invLinearDepth.g;
debugIteration = iteration;
debugIterationIntersectionKind = intersectionKind;
debugIterationCellSize = cellSize;

// Check if we are out of the buffer
if (any(int2(positionSS.xy) > int2(bufferSize))
|| any(positionSS.xy < 0)
)
|| any(positionSS.xy < 0))
{
hitSuccessful = false;
break;

}
hit.linearDepth = 1 / positionSS.z;
hit.positionNDC = float2(positionSS.xy) / float2(bufferSize);
hit.linearDepth = positionLinearDepth;
hit.positionNDC = float2(hit.positionSS) / float2(bufferSize);
if (hit.linearDepth > (1 / invHiZDepth) + SSRT_SETTING(RayDepthSuccessBias, SSRTID))
// Detect when we go behind an object given a thickness
hitWeight = CalculateHitWeight(
hit,
startPositionSS.xy,
minLinearDepth,
settingsDepthBufferThickness,
settingsRayMaxScreenDistance,
settingsRayBlendScreenDistance
);
if (hitWeight <= 0 || isBehindDepth)
DebugComputeCommonOutput(input.rayDirWS, hitSuccessful, hit);
DebugComputeHiZOutput(
iteration,
startPositionSS,
raySS,
SSRT_SETTING(RayMaxIterations, SSRTID),
debugLoopMipMaxUsedLevel,
maxMipLevel,
intersectionKind,
hit
);
DebugComputeCommonOutput(input.rayDirWS, hitSuccessful, PROJECTIONMODEL_HI_Z, hit);
switch (_DebugLightingSubMode)
{
case DEBUGSCREENSPACETRACING_HI_ZPOSITION_NDC:
hit.debugOutput = float3(float2(startPositionSS.xy) * _ScreenSize.zw, 0);
break;
case DEBUGSCREENSPACETRACING_HI_ZITERATION_COUNT:
hit.debugOutput = float(iteration) / float(settingsRayMaxIterations);
break;
case DEBUGSCREENSPACETRACING_HI_ZRAY_DIR_NDC:
hit.debugOutput = float3(raySS.xy * 0.5 + 0.5, frac(0.1 / raySS.z));
break;
case DEBUGSCREENSPACETRACING_HI_ZMAX_USED_MIP_LEVEL:
hit.debugOutput = float(debugLoopMipMaxUsedLevel) / float(maxMipLevel);
break;
case DEBUGSCREENSPACETRACING_HI_ZINTERSECTION_KIND:
hit.debugOutput = GetIndexColor(intersectionKind);
break;
case DEBUGSCREENSPACETRACING_HI_ZHIT_WEIGHT:
hit.debugOutput = float3(hitWeight, hitWeight, hitWeight);
break;
}
if (input.debug)
if (input.debug
&& _DebugScreenSpaceTracingData[0].tracingModel == -1
&& settingsDebuggedAlgorithm == PROJECTIONMODEL_HI_Z
)
debug.tracingModel = REFRACTIONSSRAYMODEL_HI_Z;
debug.loopStartPositionSSX = uint(startPositionSS.x);
debug.loopStartPositionSSY = uint(startPositionSS.y);
debug.loopStartLinearDepth = 1 / startPositionSS.z;
debug.loopRayDirectionSS = raySS;
debug.loopMipLevelMax = debugLoopMipMaxUsedLevel;
debug.loopIterationMax = iteration;
debug.iterationPositionSS = debugIterationPositionSS;
debug.iterationMipLevel = debugIterationMipLevel;
debug.iteration = debugIteration;
debug.iterationLinearDepthBuffer = debugIterationLinearDepthBuffer;
debug.iterationIntersectionKind = debugIterationIntersectionKind;
debug.iterationCellSizeW = debugIterationCellSize.x;
debug.iterationCellSizeH = debugIterationCellSize.y;
debug.endHitSuccess = hitSuccessful;
debug.endLinearDepth = hit.linearDepth;
debug.endPositionSSX = hit.positionSS.x;
debug.endPositionSSY = hit.positionSS.y;
debug.tracingModel = PROJECTIONMODEL_HI_Z;
debug.loopStartPositionSSX = uint(startPositionSS.x);
debug.loopStartPositionSSY = uint(startPositionSS.y);
debug.loopStartLinearDepth = 1 / startPositionSS.z;
debug.loopRayDirectionSS = raySS;
debug.loopMipLevelMax = debugLoopMipMaxUsedLevel;
debug.loopIterationMax = iteration;
debug.iterationPositionSS = debugIterationPositionSS;
debug.iterationMipLevel = debugIterationMipLevel;
debug.iteration = debugIteration;
debug.iterationLinearDepthBufferMin = debugIterationLinearDepthBufferMin;
debug.iterationLinearDepthBufferMinThickness = debugIterationLinearDepthBufferMinThickness;
debug.iterationLinearDepthBufferMax = debugIterationLinearDepthBufferMax;
debug.iterationIntersectionKind = debugIterationIntersectionKind;
debug.iterationCellSizeW = debugIterationCellSize.x;
debug.iterationCellSizeH = debugIterationCellSize.y;
debug.endHitSuccess = hitSuccessful;
debug.endLinearDepth = hit.linearDepth;
debug.endPositionSSX = hit.positionSS.x;
debug.endPositionSSY = hit.positionSS.y;
debug.endHitWeight = hitWeight;
_DebugScreenSpaceTracingData[0] = debug;
}

}
#endif
// #################################################
// Screen Space Tracing CB Specific Signatures
// #################################################
#ifdef SSRTID
// -------------------------------------------------
// Macros
// -------------------------------------------------
#define SSRT_SETTING(name, SSRTID) _SS ## SSRTID ## name
// -------------------------------------------------
// Constant buffers
// -------------------------------------------------
CBUFFER_START(MERGE_NAME(UnityScreenSpaceRaymarching, SSRTID))
int SSRT_SETTING(RayLevel, SSRTID);
int SSRT_SETTING(RayMinLevel, SSRTID);
int SSRT_SETTING(RayMaxLevel, SSRTID);
int SSRT_SETTING(RayMaxIterations, SSRTID);
float SSRT_SETTING(DepthBufferThickness, SSRTID);
float SSRT_SETTING(RayMaxScreenDistance, SSRTID);
float SSRT_SETTING(RayBlendScreenDistance, SSRTID);
int SSRT_SETTING(RayMarchBehindObjects, SSRTID);
#ifdef DEBUG_DISPLAY
int SSRT_SETTING(DebuggedAlgorithm, SSRTID);
#endif
CBUFFER_END
// -------------------------------------------------
// Algorithm: Linear Raymarching
// -------------------------------------------------
bool MERGE_NAME(ScreenSpaceLinearRaymarch, SSRTID)(
ScreenSpaceRaymarchInput input,
out ScreenSpaceRayHit hit,
out float hitWeight
)
{
uint2 bufferSize = uint2(_DepthPyramidSize.xy);
float3 startPositionSS;
float3 raySS;
float rayEndDepth;
CalculateRaySS(
input.rayOriginWS,
input.rayDirWS,
bufferSize,
startPositionSS,
raySS,
rayEndDepth
);
uint iteration;
return ScreenSpaceLinearRaymarch(
input,
// settings
SSRT_SETTING(RayLevel, SSRTID),
SSRT_SETTING(RayMaxIterations, SSRTID),
max(0.01, SSRT_SETTING(DepthBufferThickness, SSRTID)),
SSRT_SETTING(RayMaxScreenDistance, SSRTID),
SSRT_SETTING(RayBlendScreenDistance, SSRTID),
#ifdef DEBUG_DISPLAY
SSRT_SETTING(DebuggedAlgorithm, SSRTID),
#else
PROJECTIONMODEL_NONE,
#endif
// precomputed properties
startPositionSS,
raySS,
rayEndDepth,
bufferSize,
// out
hit,
hitWeight,
iteration
);
}
// -------------------------------------------------
// Algorithm: Scene Proxy Raycasting
// -------------------------------------------------
bool MERGE_NAME(ScreenSpaceProxyRaycast, SSRTID)(
ScreenSpaceProxyRaycastInput input,
out ScreenSpaceRayHit hit
)
{
#ifdef DEBUG_DISPLAY
int debuggedAlgorithm = int(SSRT_SETTING(DebuggedAlgorithm, SSRTID));
#else
int debuggedAlgorithm = int(PROJECTIONMODEL_NONE);
#endif
return ScreenSpaceProxyRaycast(
input,
// Settings
debuggedAlgorithm,
// Out
hit
);
}
// -------------------------------------------------
// Algorithm: HiZ raymarching
// -------------------------------------------------
bool MERGE_NAME(ScreenSpaceHiZRaymarch, SSRTID)(
ScreenSpaceRaymarchInput input,
out ScreenSpaceRayHit hit,
out float hitWeight
)
{
return ScreenSpaceHiZRaymarch(
input,
// Settings
SSRT_SETTING(RayMinLevel, SSRTID),
SSRT_SETTING(RayMaxLevel, SSRTID),
SSRT_SETTING(RayMaxIterations, SSRTID),
max(0.01, SSRT_SETTING(DepthBufferThickness, SSRTID)),
SSRT_SETTING(RayMaxScreenDistance, SSRTID),
SSRT_SETTING(RayBlendScreenDistance, SSRTID),
SSRT_SETTING(RayMarchBehindObjects, SSRTID) == 1,
#ifdef DEBUG_DISPLAY
SSRT_SETTING(DebuggedAlgorithm, SSRTID),
#else
PROJECTIONMODEL_NONE,
#endif
// out
hit,
hitWeight
);
}
// -------------------------------------------------
// Cleaning
// -------------------------------------------------
#undef SSRT_FUNC
#endif

13
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/Volumes/ProxyVolume.cs


public Vector3 sphereOffset { get { return m_SphereOffset; } set { m_SphereOffset = value; } }
public bool sphereInfiniteProjection { get { return m_SphereInfiniteProjection; } }
public Vector3 extents
{
get
{
switch (shapeType)
{
case ShapeType.Box: return m_BoxSize * 0.5f;
case ShapeType.Sphere: return Vector3.one * m_SphereRadius;
default: return Vector3.one;
}
}
}
public bool infiniteProjection
{
get

5
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs


};
[GenerateHLSL]
public enum RefractionSSRayModel
public enum ProjectionModel
HiZ = 2
HiZ = 2,
Linear = 3
};
[GenerateHLSL]

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs.hlsl


#define MATERIALFEATUREFLAGS_LIT_CLEAR_COAT (64)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+RefractionSSRayModel: static fields
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+ProjectionModel: static fields
#define REFRACTIONSSRAYMODEL_NONE (0)
#define REFRACTIONSSRAYMODEL_PROXY (1)
#define REFRACTIONSSRAYMODEL_HI_Z (2)
#define PROJECTIONMODEL_NONE (0)
#define PROJECTIONMODEL_PROXY (1)
#define PROJECTIONMODEL_HI_Z (2)
#define PROJECTIONMODEL_LINEAR (3)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+HiZIntersectionKind: static fields

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


// If a user do a lighting architecture without material classification, this can be remove
#include "../../Lighting/LightLoop/LightLoop.cs.hlsl"
// Currently disable SSR until critical editor fix is available
#undef LIGHTFEATUREFLAGS_SSREFLECTION
#define LIGHTFEATUREFLAGS_SSREFLECTION 0
/* 0 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_ENV | MATERIAL_FEATURE_MASK_FLAGS,
/* 0 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SSREFLECTION | MATERIAL_FEATURE_MASK_FLAGS,
/* 3 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 4 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 3 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SSREFLECTION | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 4 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SSREFLECTION | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 8 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 9 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 8 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SSREFLECTION | MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 9 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SSREFLECTION | MATERIALFEATUREFLAGS_LIT_SUBSURFACE_SCATTERING | MATERIALFEATUREFLAGS_LIT_TRANSMISSION | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 13 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_ANISOTROPY | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 14 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_ANISOTROPY | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 13 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SSREFLECTION | MATERIALFEATUREFLAGS_LIT_ANISOTROPY | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 14 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SSREFLECTION | MATERIALFEATUREFLAGS_LIT_ANISOTROPY | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 18 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 19 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 18 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SSREFLECTION | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 19 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SSREFLECTION | MATERIALFEATUREFLAGS_LIT_CLEAR_COAT | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 23 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_IRIDESCENCE | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 24 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | MATERIALFEATUREFLAGS_LIT_IRIDESCENCE | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 23 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SSREFLECTION | MATERIALFEATUREFLAGS_LIT_IRIDESCENCE | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 24 */ LIGHTFEATUREFLAGS_SKY | LIGHTFEATUREFLAGS_DIRECTIONAL | LIGHTFEATUREFLAGS_PUNCTUAL | LIGHTFEATUREFLAGS_ENV | LIGHTFEATUREFLAGS_SSREFLECTION | MATERIALFEATUREFLAGS_LIT_IRIDESCENCE | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 25 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIALFEATUREFLAGS_LIT_IRIDESCENCE | MATERIALFEATUREFLAGS_LIT_STANDARD,
/* 26 */ LIGHT_FEATURE_MASK_FLAGS_OPAQUE | MATERIAL_FEATURE_MASK_FLAGS, // Catch all case with MATERIAL_FEATURE_MASK_FLAGS is needed in case we disable material classification

// Helper functions/variable specific to this material
//-----------------------------------------------------------------------------
// SSReflection
#include "HDRP/Lighting/LightDefinition.cs.hlsl"
#include "HDRP/Lighting/Reflection/VolumeProjection.hlsl"
#define SSRTID Reflection
#include "HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl"
#undef SSRTID
#include "HDRP/Lighting/LightDefinition.cs.hlsl"
#include "HDRP/Lighting/Reflection/VolumeProjection.hlsl"
#define SSRTID Refraction
#include "HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl"
#undef SSRTID

#elif defined(_REFRACTION_SPHERE)
#define REFRACTION_MODEL(V, posInputs, bsdfData) RefractionModelSphere(V, posInputs.positionWS, bsdfData.normalWS, bsdfData.ior, bsdfData.thickness)
#endif
#if defined(_REFRACTION_SSRAY_PROXY)
#define REFRACTION_SSRAY_IN ScreenSpaceProxyRaycastInput
#define REFRACTION_SSRAY_QUERY(input, hit) ScreenSpaceProxyRaycastRefraction(input, hit)
#elif defined(_REFRACTION_SSRAY_HIZ)
#define REFRACTION_SSRAY_IN ScreenSpaceHiZRaymarchInput
#define REFRACTION_SSRAY_QUERY(input, hit) ScreenSpaceHiZRaymarchRefraction(input, hit)
#endif
#endif
// This method allows us to know at compile time what material features should be removed from the code by Tile (Indepenently of the value of material feature flag per pixel).

// TODO: We need a better hack.
preLightData.iblPerceptualRoughness *= saturate(1.2 - abs(bsdfData.anisotropy));
// Corretion of reflected direction for better handling of rough material
preLightData.iblR = GetSpecularDominantDir(N, iblR, preLightData.iblPerceptualRoughness, NdotV);
preLightData.iblR = iblR;
#ifdef LIT_USE_GGX_ENERGY_COMPENSATION
// Ref: Practical multiple scattering compensation for microfacet models.

IndirectLighting lighting;
ZERO_INITIALIZE(IndirectLighting, lighting);
switch (GPUImageBasedLightingType)
// -------------------------------
// Early out
// -------------------------------
#if !HAS_REFRACTION
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
case GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION:
{
// No refraction, no need to go further
hierarchyWeight = 1.0;
return lighting;
}
#endif
// -------------------------------
// Choose projection model
// -------------------------------
int projectionModel = PROJECTIONMODEL_NONE;
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
{
#if defined(_REFRACTION_SSRAY_HIZ)
projectionModel = PROJECTIONMODEL_HI_Z;
#elif defined(_REFRACTION_SSRAY_PROXY)
projectionModel = PROJECTIONMODEL_PROXY;
#endif
}
#else
if (_SSReflectionEnabled != 0)
projectionModel = _SSReflectionProjectionModel;
#endif
// Refraction process:
// 1. Depending on the shape model, we calculate the refracted point in world space and the optical depth
// 2. We calculate the screen space position of the refracted point
// 3. If this point is available (ie: in color buffer and point is not in front of the object)
// a. Get the corresponding color depending on the roughness from the gaussian pyramid of the color buffer
// b. Multiply by the transmittance for absorption (depends on the optical depth)
if (projectionModel == PROJECTIONMODEL_NONE)
return lighting;
// -------------------------------
// Initialize screen space tracing
// -------------------------------
float3 rayOriginWS = float3(0, 0, 0);
float3 rayDirWS = float3(0, 0, 0);
float mipLevel = 0;
#if DEBUG_DISPLAY
int debugMode = 0;
#endif
float invScreenWeightDistance = 0;
float temporalFilteringWeight = 0.1;
#if HAS_REFRACTION
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
{
// Refraction process:
// 1. Depending on the shape model, we calculate the refracted point in world space and the optical depth
// 2. We calculate the screen space position of the refracted point
// 3. If this point is available (ie: in color buffer and point is not in front of the object)
// a. Get the corresponding color depending on the roughness from the gaussian pyramid of the color buffer
// b. Multiply by the transmittance for absorption (depends on the optical depth)
float3 rayOriginWS = preLightData.transparentPositionWS;
float3 rayDirWS = preLightData.transparentRefractV;
#ifdef DEBUG_DISPLAY
int debugMode = DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION;
rayOriginWS = preLightData.transparentPositionWS;
rayDirWS = preLightData.transparentRefractV;
mipLevel = preLightData.transparentSSMipLevel;
invScreenWeightDistance = _SSRefractionInvScreenWeightDistance;
#if DEBUG_DISPLAY
debugMode = DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION;
#endif
}
else
#endif
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
{
rayOriginWS = posInput.positionWS;
rayDirWS = preLightData.iblR;
mipLevel = PositivePow(preLightData.iblPerceptualRoughness, 0.8) * uint(max(_ColorPyramidScale.z - 1, 0));
invScreenWeightDistance = _SSReflectionInvScreenWeightDistance;
#if DEBUG_DISPLAY
debugMode = DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFLECTION;
#endif
}
#if DEBUG_DISPLAY
// Initialize screen space tracing
REFRACTION_SSRAY_IN ssRayInput;
ZERO_INITIALIZE(REFRACTION_SSRAY_IN, ssRayInput);
// -------------------------------
// Screen space tracing query
// -------------------------------
ScreenSpaceRayHit hit;
ZERO_INITIALIZE(ScreenSpaceRayHit, hit);
bool hitSuccessful = false;
float hitWeight = 1;
// Common initialization
// -------------------------------
// Proxy raycasting
// -------------------------------
if (projectionModel == PROJECTIONMODEL_PROXY)
{
ScreenSpaceProxyRaycastInput ssRayInput;
ZERO_INITIALIZE(ScreenSpaceProxyRaycastInput, ssRayInput);
// Algorithm specific initialization
#ifdef _REFRACTION_SSRAY_HIZ
ssRayInput.maxIterations = uint(-1);
#elif _REFRACTION_SSRAY_PROXY
#if HAS_REFRACTION
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
hitSuccessful = ScreenSpaceProxyRaycastRefraction(ssRayInput, hit);
else
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
hitSuccessful = ScreenSpaceProxyRaycastReflection(ssRayInput, hit);
}
// Perform ray query
ScreenSpaceRayHit hit;
ZERO_INITIALIZE(ScreenSpaceRayHit, hit);
bool hitSuccessful = REFRACTION_SSRAY_QUERY(ssRayInput, hit);
// -------------------------------
// HiZ raymarching
// -------------------------------
else if (projectionModel == PROJECTIONMODEL_HI_Z)
{
ScreenSpaceRaymarchInput ssRayInput;
ZERO_INITIALIZE(ScreenSpaceRaymarchInput, ssRayInput);
// Jitter the ray origin to trade some noise instead of banding effect
ssRayInput.rayOriginWS = rayOriginWS + rayDirWS * SampleBayer4(posInput.positionSS + uint2(_FrameCount, uint(_FrameCount) / 4u)) * 0.1;
ssRayInput.rayDirWS = rayDirWS;
#if DEBUG_DISPLAY
ssRayInput.debug = debug;
#endif
#if HAS_REFRACTION
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
hitSuccessful = ScreenSpaceHiZRaymarchRefraction(ssRayInput, hit, hitWeight);
else
#endif
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
hitSuccessful = ScreenSpaceHiZRaymarchReflection(ssRayInput, hit, hitWeight);
}
if (_DebugLightingMode == debugMode
&& _DebugLightingSubMode != DEBUGSCREENSPACETRACING_COLOR)
{
float weight = 1.0;
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
lighting.specularTransmitted = hit.debugOutput;
return lighting;
}
if (_DebugLightingMode == debugMode
&& _DebugLightingSubMode != DEBUGSCREENSPACETRACING_COLOR
&& _DebugLightingSubMode != DEBUGSCREENSPACETRACING_LINEAR_SAMPLED_COLOR
&& _DebugLightingSubMode != DEBUGSCREENSPACETRACING_HI_ZSAMPLED_COLOR
)
{
float weight = 1.0;
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
lighting.specularTransmitted = hit.debugOutput;
else if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
lighting.specularReflected = hit.debugOutput;
return lighting;
}
if (!hitSuccessful)
return lighting;
if (!hitSuccessful)
return lighting;
float2 weightNDC = clamp(min(hit.positionNDC, 1 - hit.positionNDC) * _SSRefractionInvScreenWeightDistance, 0, 1);
// -------------------------------
// Resolve weight and color
// -------------------------------
// Fade pixels near the texture buffers' borders
float2 weightNDC = clamp(min(hit.positionNDC, 1 - hit.positionNDC) * invScreenWeightDistance, 0, 1);
float weight = weightNDC.x * weightNDC.y;
// TODO: Fade pixels with normal non facing the ray direction
// TODO: Fade pixels marked as foreground in stencil
float weight = weightNDC.x * weightNDC.y * hitWeight;
float hitDeviceDepth = LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, hit.positionSS, 0).r;
float hitLinearDepth = LinearEyeDepth(hitDeviceDepth, _ZBufferParams);
float hitDeviceDepth = LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, hit.positionSS, 0).r;
float hitLinearDepth = LinearEyeDepth(hitDeviceDepth, _ZBufferParams);
// Exit if texel is out of color buffer
// Or if the texel is from an object in front of the object
if (hitLinearDepth < posInput.linearDepth
|| weight == 0)
{
// Do nothing and don't update the hierarchy weight so we can fall back on refraction probe
return lighting;
}
// Exit if texel is discarded
if (weight == 0)
// Do nothing and don't update the hierarchy weight so we can fall back on refraction probe
return lighting;
UpdateLightingHierarchyWeights(hierarchyWeight, weight); // Shouldn't be needed, but safer in case we decide to change hierarchy priority
UpdateLightingHierarchyWeights(hierarchyWeight, weight); // Shouldn't be needed, but safer in case we decide to change hierarchy priority
float3 preLD = SAMPLE_TEXTURE2D_LOD(
_ColorPyramidTexture,
s_trilinear_clamp_sampler,
hit.positionNDC * _ColorPyramidScale.xy,
preLightData.transparentSSMipLevel
).rgb;
// Reproject color pyramid
float4 hitVelocityBuffer = LOAD_TEXTURE2D_LOD(
_CameraMotionVectorsTexture,
hit.positionSS,
0.0
);
// We use specularFGD as an approximation of the fresnel effect (that also handle smoothness), so take the remaining for transmission
float3 F = preLightData.specularFGD;
lighting.specularTransmitted = (1.0 - F) * preLD.rgb * preLightData.transparentTransmittance * weight;
#else
// No refraction, no need to go further
hierarchyWeight = 1.0;
float2 hitVelocityNDC;
DecodeVelocity(hitVelocityBuffer, hitVelocityNDC);
float3 preLD = SAMPLE_TEXTURE2D_LOD(
_ColorPyramidTexture,
s_trilinear_clamp_sampler,
// Offset by half a texel to properly interpolate between this pixel and its mips
(hit.positionNDC - hitVelocityNDC) * _ColorPyramidScale.xy + _ColorPyramidSize.zw * 0.5,
mipLevel
).rgb;
// With HiZ, we use a temporal filtering to reduce the noise from the ray origin jittering
if (projectionModel == PROJECTIONMODEL_HI_Z)
{
float4 currentVelocityBuffer = LOAD_TEXTURE2D_LOD(
_CameraMotionVectorsTexture,
posInput.positionSS,
0.0
);
float2 currentVelocityNDC;
DecodeVelocity(currentVelocityBuffer, currentVelocityNDC);
float3 currentLD = LOAD_TEXTURE2D_LOD(
_ColorPyramidTexture,
int2(posInput.positionSS) - int2(currentVelocityNDC * _ScreenSize.xy),
0
).rgb;
preLD = preLD * (1.0 - temporalFilteringWeight) + currentLD * temporalFilteringWeight;
}
// We use specularFGD as an approximation of the fresnel effect (that also handle smoothness)
float3 F = preLightData.specularFGD;
// -------------------------------
// Assign color
// -------------------------------
#if HAS_REFRACTION
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
lighting.specularTransmitted = (1.0 - F) * preLD.rgb * preLightData.transparentTransmittance * weight;
else
break;
}
case GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION:
{
break;
}
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
lighting.specularReflected = F * preLD.rgb * weight;
#ifdef DEBUG_DISPLAY
if (debug)
{
ScreenSpaceTracingDebug debug = _DebugScreenSpaceTracingData[0];
debug.lightingSampledColor = preLD;
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
debug.lightingSpecularFGD = 1.0 - F;
else if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
debug.lightingSpecularFGD = F;
debug.lightingWeight = weight;
_DebugScreenSpaceTracingData[0] = debug;
if (_DebugLightingMode == debugMode
&& (_DebugLightingSubMode == DEBUGSCREENSPACETRACING_LINEAR_SAMPLED_COLOR
|| _DebugLightingSubMode == DEBUGSCREENSPACETRACING_HI_ZSAMPLED_COLOR))
{
float weight = 1.0;
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
lighting.specularTransmitted = preLD.rgb;
else if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION)
lighting.specularReflected = preLD.rgb;
return lighting;
}
#endif
return lighting;
}

positionWS = preLightData.transparentPositionWS;
R = preLightData.transparentRefractV;
}
else
{
if ((lightData.envIndex & 1) == ENVCACHETYPE_CUBEMAP)
{
R = GetSpecularDominantDir(bsdfData.normalWS, R, preLightData.iblPerceptualRoughness, ClampNdotV(preLightData.NdotV));
// When we are rough, we tend to see outward shifting of the reflection when at the boundary of the projection volume
// Also it appear like more sharp. To avoid these artifact and at the same time get better match to reference we lerp to original unmodified reflection.
// Formula is empirical.
float roughness = PerceptualRoughnessToRoughness(preLightData.iblPerceptualRoughness);
R = lerp(R, preLightData.iblR, saturate(smoothstep(0, 1, roughness * roughness)));
}
}
// Note: using influenceShapeType and projectionShapeType instead of (lightData|proxyData).shapeType allow to make compiler optimization in case the type is know (like for sky)
EvaluateLight_EnvIntersection(positionWS, bsdfData.normalWS, lightData, influenceShapeType, R, weight);

float unusedWeight = 0.0;
EvaluateLight_EnvIntersection(positionWS, bsdfData.normalWS, lightData, influenceShapeType, coatR, unusedWeight);
}
// When we are rough, we tend to see outward shifting of the reflection when at the boundary of the projection volume
// Also it appear like more sharp. To avoid these artifact and at the same time get better match to reference we lerp to original unmodified reflection.
// Formula is empirical.
float roughness = PerceptualRoughnessToRoughness(preLightData.iblPerceptualRoughness);
R = lerp(R, preLightData.iblR, saturate(smoothstep(0, 1, roughness * roughness)));
float3 F = preLightData.specularFGD;

if (_DebugLightingMode != 0)
{
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
bool keepSpecular = false;
switch (_DebugLightingMode)
{

case DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION:
if (_DebugLightingSubMode != DEBUGSCREENSPACETRACING_COLOR)
diffuseLighting = lighting.indirect.specularTransmitted;
else
keepSpecular = true;
break;
case DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFLECTION:
if (_DebugLightingSubMode != DEBUGSCREENSPACETRACING_COLOR)
diffuseLighting = lighting.indirect.specularReflected;
else
keepSpecular = true;
if (!keepSpecular)
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
else if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)
{

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.shader


// Transparency
[Enum(None, 0, Plane, 1, Sphere, 2)]_RefractionModel("Refraction Model", Int) = 0
[Enum(Proxy, 1, HiZ, 2)]_RefractionSSRayModel("Refraction SSRay Model", Int) = 0
[Enum(Proxy, 1, HiZ, 2)]_SSRefractionProjectionModel("Refraction Projection Model", Int) = 0
_Ior("Index Of Refraction", Range(1.0, 2.5)) = 1.0
_ThicknessMultiplier("Thickness Multiplier", Float) = 1.0
_TransmittanceColor("Transmittance Color", Color) = (1.0, 1.0, 1.0)

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitTessellation.shader


// Transparency
[Enum(None, 0, Plane, 1, Sphere, 2)]_RefractionModel("Refraction Model", Int) = 0
[Enum(Proxy, 1, HiZ, 2)]_RefractionSSRayModel("Refraction SSRay Model", Int) = 0
[Enum(Proxy, 1, HiZ, 2)]_SSRefractionProjectionModel("Refraction Projection Model", Int) = 0
_Ior("Index Of Refraction", Range(1.0, 2.5)) = 1.0
_ThicknessMultiplier("Thickness Multiplier", Float) = 1.0
_TransmittanceColor("Transmittance Color", Color) = (1.0, 1.0, 1.0)

19
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderVariables.hlsl


float4 _SinTime; // { sin(t/8), sin(t/4), sin(t/2), sin(t) }
float4 _CosTime; // { cos(t/8), cos(t/4), cos(t/2), cos(t) }
float4 unity_DeltaTime; // { dt, 1/dt, smoothdt, 1/smoothdt }
int _FrameCount;
// Volumetric lighting.
float4 _AmbientProbeCoeffs[7]; // 3 bands of SH, packed, rescaled and convolved with the phase function

CBUFFER_START(UnityLightingParameters)
// Buffer pyramid
float4 _ColorPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size
float4 _DepthPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size
float4 _ColorPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused
float4 _DepthPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused
float4 _ColorPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size
float4 _DepthPyramidSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size
float4 _CameraMotionVectorsSize; // (x,y) = Actual Pixel Size, (z,w) = 1 / Actual Pixel Size
float4 _ColorPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused
float4 _DepthPyramidScale; // (x,y) = Screen Scale, z = lod count, w = unused
float4 _CameraMotionVectorsScale; // (x,y) = Screen Scale, z = lod count, w = unused
float _SSRefractionInvScreenWeightDistance; // Distance for screen space smoothstep with fallback
float _SSRefractionInvScreenWeightDistance; // Distance for screen space smoothstep with fallback
float _SSReflectionInvScreenWeightDistance; // Distance for screen space smoothstep with fallback
int _SSReflectionEnabled;
int _SSReflectionProjectionModel;
int _SSReflectionHiZRayMarchBehindObject;
int _SSRefractionHiZRayMarchBehindObject;
// Ambiant occlusion
float4 _AmbientOcclusionParam; // xyz occlusion color, w directLightStrenght

TEXTURE2D(_DepthPyramidTexture);
// Ambient occlusion texture
TEXTURE2D(_AmbientOcclusionTexture);
TEXTURE2D(_CameraMotionVectorsTexture);
// Custom generated by HDRP, not from Unity Engine (passed in via HDCamera)
#if defined(USING_STEREO_MATRICES)

16
Tests/UTF_Suites_HDRP/Resources/HDRP_Deferred.asset


--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1

minimumUnityVersion: 4
platforms: -1
run: 0
- name: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2204_ScreenSpaceReflectionProxyBox.unity
scene: {fileID: 102900000, guid: 371699c064b85d04ba90b577c881c643, type: 3}
scenePath: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2204_ScreenSpaceReflectionProxyBox.unity
testTypes: 2
minimumUnityVersion: 4
platforms: -1
run: 1
- name: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2206_ProbeRoughness.unity
scene: {fileID: 102900000, guid: fde2b1b0825ef5f40a0e5069afcca848, type: 3}
scenePath: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2206_ProbeRoughness.unity

run: 0
- name: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2205_ScreenSpaceReflectionProxySphere.unity
scene: {fileID: 102900000, guid: 3a4f431f1be840b45945d9ec965b621c, type: 3}
scenePath: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2205_ScreenSpaceReflectionProxySphere.unity
testTypes: 2
minimumUnityVersion: 4
platforms: -1
run: 1
- name: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2301_Shadow_Mask.unity
scene: {fileID: 102900000, guid: 1029947770f955b4290bbdd8b641f7f1, type: 3}
scenePath: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2301_Shadow_Mask.unity

16
Tests/UTF_Suites_HDRP/Resources/HDRP_Forward.asset


--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1

minimumUnityVersion: 4
platforms: -1
run: 0
- name: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2204_ScreenSpaceReflectionProxyBox.unity
scene: {fileID: 102900000, guid: 371699c064b85d04ba90b577c881c643, type: 3}
scenePath: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2204_ScreenSpaceReflectionProxyBox.unity
testTypes: 2
minimumUnityVersion: 4
platforms: -1
run: 1
- name: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2206_ProbeRoughness.unity
scene: {fileID: 102900000, guid: fde2b1b0825ef5f40a0e5069afcca848, type: 3}
scenePath: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2206_ProbeRoughness.unity

run: 0
- name: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2205_ScreenSpaceReflectionProxySphere.unity
scene: {fileID: 102900000, guid: 3a4f431f1be840b45945d9ec965b621c, type: 3}
scenePath: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2205_ScreenSpaceReflectionProxySphere.unity
testTypes: 2
minimumUnityVersion: 4
platforms: -1
run: 1
- name: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2301_Shadow_Mask.unity
scene: {fileID: 102900000, guid: 1029947770f955b4290bbdd8b641f7f1, type: 3}
scenePath: Assets/ScriptableRenderPipeline/Tests/UTF_Tests_HDRP/Scenes/2x_Lighting/2301_Shadow_Mask.unity

44
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs


using System.Collections;
using UnityEngine;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
[CanEditMultipleObjects]
[VolumeComponentEditor(typeof(ScreenSpaceReflection))]
public class HDScreenSpaceReflectionEditor : ScreenSpaceLightingEditor
{
SerializedDataParameter m_DeferredProjectionModel;
public override void OnEnable()
{
base.OnEnable();
var o = new PropertyFetcher<ScreenSpaceReflection>(serializedObject);
m_DeferredProjectionModel = Unpack(o.Find(x => x.deferredProjectionModel));
}
public override void OnInspectorGUI()
{
OnCommonInspectorGUI();
var projectionModel = (Lit.ProjectionModel)m_DeferredProjectionModel.value.enumValueIndex;
switch (projectionModel)
{
case Lit.ProjectionModel.HiZ:
EditorGUILayout.Separator();
OnHiZInspectorGUI();
break;
case Lit.ProjectionModel.Proxy:
EditorGUILayout.Separator();
OnProxyInspectorGUI();
break;
}
}
protected override void OnCommonInspectorGUI()
{
base.OnCommonInspectorGUI();
PropertyField(m_DeferredProjectionModel, CoreEditorUtils.GetContent("Projection Model"));
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs.meta


fileFormatVersion: 2
guid: e1a6d5f7801c9c749a3f7d3bf4294e87
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

73
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ScreenSpaceLightingEditor.cs


using System.Collections;
using UnityEngine;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
public class ScreenSpaceLightingEditor : VolumeComponentEditor
{
protected SerializedDataParameter m_RayLevel;
protected SerializedDataParameter m_RayMinLevel;
protected SerializedDataParameter m_RayMaxLevel;
protected SerializedDataParameter m_RayMaxIterations;
protected SerializedDataParameter m_DepthBufferThickness;
protected SerializedDataParameter m_ScreenWeightDistance;
protected SerializedDataParameter m_RayMaxScreenDistance;
protected SerializedDataParameter m_RayBlendScreenDistance;
protected SerializedDataParameter m_RayMarchBehindObjects;
public override void OnEnable()
{
var o = new PropertyFetcher<ScreenSpaceLighting>(serializedObject);
m_RayLevel = Unpack(o.Find(x => x.rayLevel));
m_RayMinLevel = Unpack(o.Find(x => x.rayMinLevel));
m_RayMaxLevel = Unpack(o.Find(x => x.rayMaxLevel));
m_RayMaxIterations = Unpack(o.Find(x => x.rayMaxIterations));
m_DepthBufferThickness = Unpack(o.Find(x => x.depthBufferThickness));
m_ScreenWeightDistance = Unpack(o.Find(x => x.screenWeightDistance));
m_RayMaxScreenDistance = Unpack(o.Find(x => x.rayMaxScreenDistance));
m_RayBlendScreenDistance = Unpack(o.Find(x => x.rayBlendScreenDistance));
m_RayMarchBehindObjects = Unpack(o.Find(x => x.rayMarchBehindObjects));
}
public override void OnInspectorGUI()
{
OnCommonInspectorGUI();
EditorGUILayout.Separator();
OnHiZInspectorGUI();
EditorGUILayout.Separator();
OnProxyInspectorGUI();
}
protected virtual void OnHiZInspectorGUI()
{
EditorGUILayout.LabelField(CoreEditorUtils.GetContent("HiZ Settings"));
PropertyField(m_RayMinLevel, CoreEditorUtils.GetContent("Ray Min Level"));
PropertyField(m_RayMaxLevel, CoreEditorUtils.GetContent("Ray Max Level"));
PropertyField(m_RayMaxIterations, CoreEditorUtils.GetContent("Ray Max Iterations"));
PropertyField(m_DepthBufferThickness, CoreEditorUtils.GetContent("Depth Buffer Thickness"));
PropertyField(m_RayMaxScreenDistance, CoreEditorUtils.GetContent("Max Raymarched Distance (NDC)"));
PropertyField(m_RayBlendScreenDistance, CoreEditorUtils.GetContent("Blended Raymarched Distance (NDC)"));
PropertyField(m_RayMarchBehindObjects, CoreEditorUtils.GetContent("Ray March Behind Objects"));
m_RayMinLevel.value.intValue = Mathf.Clamp(m_RayMinLevel.value.intValue, 0, m_RayMaxLevel.value.intValue);
m_RayMaxLevel.value.intValue = Mathf.Max(0, m_RayMaxLevel.value.intValue);
m_RayMaxIterations.value.intValue = Mathf.Max(0, m_RayMaxIterations.value.intValue);
m_DepthBufferThickness.value.floatValue = Mathf.Max(0.001f, m_DepthBufferThickness.value.floatValue);
m_RayMaxScreenDistance.value.floatValue = Mathf.Clamp(m_RayMaxScreenDistance.value.floatValue, 0.001f, 1.0f);
m_RayBlendScreenDistance.value.floatValue = Mathf.Clamp(m_RayBlendScreenDistance.value.floatValue, 0.0f, m_RayMaxScreenDistance.value.floatValue);
}
protected virtual void OnProxyInspectorGUI()
{
}
protected virtual void OnCommonInspectorGUI()
{
EditorGUILayout.LabelField(CoreEditorUtils.GetContent("Common Settings"));
PropertyField(m_ScreenWeightDistance, CoreEditorUtils.GetContent("Screen Weight Distance"));
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ScreenSpaceLightingEditor.cs.meta


fileFormatVersion: 2
guid: 5a0cc6d88bd0be54283043dc53877a64
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

69
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceLighting.cs


using System;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[Serializable]
public abstract class ScreenSpaceLighting : VolumeComponent
{
int m_RayLevelID;
int m_RayMinLevelID;
int m_RayMaxLevelID;
int m_RayMaxIterationsID;
int m_DepthBufferThicknessID;
int m_InvScreenWeightDistanceID;
int m_RayMaxScreenDistanceID;
int m_RayBlendScreenDistanceID;
int m_RayMarchBehindObjectsID;
public IntParameter rayLevel = new IntParameter(2);
public IntParameter rayMinLevel = new IntParameter(2);
public IntParameter rayMaxLevel = new IntParameter(6);
public IntParameter rayMaxIterations = new IntParameter(32);
public FloatParameter depthBufferThickness = new FloatParameter(1f);
public ClampedFloatParameter screenWeightDistance = new ClampedFloatParameter(0.1f, 0, 1);
public ClampedFloatParameter rayMaxScreenDistance = new ClampedFloatParameter(0.3f, 0, 1);
public ClampedFloatParameter rayBlendScreenDistance = new ClampedFloatParameter(0.1f, 0, 1);
public BoolParameter rayMarchBehindObjects = new BoolParameter(true);
public virtual void PushShaderParameters(CommandBuffer cmd)
{
cmd.SetGlobalInt(m_RayLevelID, rayLevel.value);
cmd.SetGlobalInt(m_RayMinLevelID, rayMinLevel.value);
cmd.SetGlobalInt(m_RayMaxLevelID, rayMaxLevel.value);
cmd.SetGlobalInt(m_RayMaxIterationsID, rayMaxIterations.value);
cmd.SetGlobalFloat(m_DepthBufferThicknessID, depthBufferThickness.value);
cmd.SetGlobalFloat(m_InvScreenWeightDistanceID, 1f / screenWeightDistance.value);
cmd.SetGlobalFloat(m_RayMaxScreenDistanceID, rayMaxScreenDistance.value);
cmd.SetGlobalFloat(m_RayBlendScreenDistanceID, rayBlendScreenDistance.value);
cmd.SetGlobalInt(m_RayMarchBehindObjectsID, rayMarchBehindObjects.value ? 1 : 0);
}
protected abstract void FetchIDs(
out int rayLevelID,
out int rayMinLevelID,
out int rayMaxLevelID,
out int rayMaxIterationsID,
out int DepthBufferThicknessID,
out int invScreenWeightDistanceID,
out int rayMaxScreenDistanceID,
out int rayBlendScreenDistanceID,
out int rayMarchBehindObjectsID
);
void Awake()
{
FetchIDs(
out m_RayLevelID,
out m_RayMinLevelID,
out m_RayMaxLevelID,
out m_RayMaxIterationsID,
out m_DepthBufferThicknessID,
out m_InvScreenWeightDistanceID,
out m_RayMaxScreenDistanceID,
out m_RayBlendScreenDistanceID,
out m_RayMarchBehindObjectsID
);
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceLighting.cs.meta


fileFormatVersion: 2
guid: abafd8c0d3ca56d44b9469b2b67fc7cc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

70
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceReflection.cs


using System;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[Serializable]
public sealed class LitProjectionModelParameter : VolumeParameter<ScreenSpaceReflection.AvailableProjectionModel>
{
public LitProjectionModelParameter() : base(ScreenSpaceReflection.AvailableProjectionModel.Proxy, false) { }
}
[Serializable]
public class ScreenSpaceReflection : ScreenSpaceLighting
{
// Values must be in sync with Lit.ProjectionModel
public enum AvailableProjectionModel
{
None = 0,
Proxy = 1,
HiZ = 2
}
static ScreenSpaceReflection s_Default = null;
public static ScreenSpaceReflection @default
{
get
{
if (s_Default == null)
{
s_Default = ScriptableObject.CreateInstance<ScreenSpaceReflection>();
s_Default.hideFlags = HideFlags.HideAndDontSave;
}
return s_Default;
}
}
int m_DeferredProjectionModel;
public LitProjectionModelParameter deferredProjectionModel = new LitProjectionModelParameter();
protected override void FetchIDs(
out int rayLevelID,
out int rayMinLevelID,
out int rayMaxLevelID,
out int rayMaxIterationsID,
out int depthBufferThicknessID,
out int screenWeightDistanceID,
out int rayMaxScreenDistanceID,
out int rayBlendScreenDistanceID,
out int rayMarchBehindObjectsID
)
{
rayLevelID = HDShaderIDs._SSReflectionRayLevel;
rayMinLevelID = HDShaderIDs._SSReflectionRayMinLevel;
rayMaxLevelID = HDShaderIDs._SSReflectionRayMaxLevel;
rayMaxIterationsID = HDShaderIDs._SSReflectionRayMaxIterations;
depthBufferThicknessID = HDShaderIDs._SSReflectionDepthBufferThickness;
screenWeightDistanceID = HDShaderIDs._SSReflectionInvScreenWeightDistance;
rayMaxScreenDistanceID = HDShaderIDs._SSReflectionRayMaxScreenDistance;
rayBlendScreenDistanceID = HDShaderIDs._SSReflectionRayBlendScreenDistance;
rayMarchBehindObjectsID = HDShaderIDs._SSReflectionRayMarchBehindObjects;
}
public override void PushShaderParameters(CommandBuffer cmd)
{
base.PushShaderParameters(cmd);
cmd.SetGlobalInt(HDShaderIDs._SSReflectionProjectionModel, (int)deferredProjectionModel.value);
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceReflection.cs.meta


fileFormatVersion: 2
guid: 384c4d03a551c44448145f4093304119
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存