浏览代码

(wip) Added refraction model

/main
Frédéric Vauchelles 7 年前
当前提交
4fbb1c4f
共有 24 个文件被更改,包括 836 次插入322 次删除
  1. 1
      ScriptableRenderPipeline/Core/CoreRP/Debugging/DebugUI.Panel.cs
  2. 3
      ScriptableRenderPipeline/Core/CoreRP/Debugging/DebugUI.cs
  3. 15
      ScriptableRenderPipeline/Core/CoreRP/Editor/Debugging/DebugWindow.cs
  4. 5
      ScriptableRenderPipeline/Core/CoreRP/Editor/ShaderGenerator/CSharpToHLSL.cs
  5. 46
      ScriptableRenderPipeline/Core/CoreRP/MousePositionDebug.cs
  6. 174
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs
  7. 116
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs.hlsl
  8. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.hlsl
  9. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/LightingDebug.cs
  10. 16
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/LightingDebug.cs.hlsl
  11. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/LitUI.cs
  12. 23
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  13. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs
  14. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDUtils.cs
  15. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  16. 24
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.hlsl
  17. 437
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl
  18. 7
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs.hlsl
  19. 173
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  20. 35
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ScreenSpaceRefractionVolumeEditor.cs
  21. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ScreenSpaceRefractionVolumeEditor.cs.meta
  22. 22
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceRefractionVolume.cs
  23. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceRefractionVolume.cs.meta
  24. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl.meta

1
ScriptableRenderPipeline/Core/CoreRP/Debugging/DebugUI.Panel.cs


public bool isEditorOnly { get { return (flags & Flags.EditorOnly) != 0; } }
public bool isRuntimeOnly { get { return (flags & Flags.RuntimeOnly) != 0; } }
public bool forceUpdate { get { return (flags & Flags.ForceUpdate) != 0; } }
public ObservableList<Widget> children { get; private set; }
public event Action<Panel> onSetDirty = delegate { };

3
ScriptableRenderPipeline/Core/CoreRP/Debugging/DebugUI.cs


{
None = 0,
EditorOnly = 1 << 1,
RuntimeOnly = 1 << 2
RuntimeOnly = 1 << 2,
ForceUpdate = 1 << 3
}
// Base class for all debug UI widgets

15
ScriptableRenderPipeline/Core/CoreRP/Editor/Debugging/DebugWindow.cs


// First init
m_DebugTreeState = DebugManager.instance.GetState();
UpdateWidgetStates();
EditorApplication.update -= Repaint;
var panels = DebugManager.instance.panels;
var selectedPanelIndex = m_Settings.selectedPanel;
if (selectedPanelIndex >= 0
&& selectedPanelIndex < panels.Count
&& panels[selectedPanelIndex].forceUpdate)
EditorApplication.update += Repaint;
}
// Note: this won't get called if the window is opened when the editor itself is closed

if (EditorGUI.EndChangeCheck())
{
Undo.RegisterCompleteObjectUndo(m_Settings, "Debug Panel Selection");
var previousPanel = m_Settings.selectedPanel >= 0 && m_Settings.selectedPanel < panels.Count
? panels[m_Settings.selectedPanel]
: null;
if (previousPanel != null && previousPanel.forceUpdate && !panel.forceUpdate)
EditorApplication.update -= Repaint;
else if ((previousPanel == null || !previousPanel.forceUpdate) && panel.forceUpdate)
EditorApplication.update += Repaint;
m_Settings.selectedPanel = i;
}
}

5
ScriptableRenderPipeline/Core/CoreRP/Editor/ShaderGenerator/CSharpToHLSL.cs


s_TypeName = new Dictionary<string, ShaderTypeGenerator>();
// Iterate over assemblyList, discover all applicable types with fully qualified names
var assemblyList = AppDomain.CurrentDomain.GetAssemblies().ToList();
var assemblyList = AppDomain.CurrentDomain.GetAssemblies()
// We need to exclude dynamic assemblies (their type can't be queried, throwing an exception below)
.Where(ass => !ass.IsDynamic)
.ToList();
foreach (var assembly in assemblyList)
{

46
ScriptableRenderPipeline/Core/CoreRP/MousePositionDebug.cs


}
}
public int debugStep
{
get
{
#if UNITY_EDITOR
return m_DebugStep;
#else
return 0;
#endif
}
}
Vector2 m_MouseClickPosition = Vector2.zero;
int m_DebugStep = 0;
switch (Event.current.type)
{
case EventType.MouseDown:
m_MouseClickPosition = m_mousePosition;
break;
case EventType.KeyDown:
switch (Event.current.keyCode)
{
case KeyCode.PageUp:
++m_DebugStep;
break;
case KeyCode.PageDown:
m_DebugStep = Mathf.Max(0, m_DebugStep - 1);
break;
case KeyCode.End:
// Usefull we you don't want to change the scene viewport but still update the mouse click position
m_MouseClickPosition = m_mousePosition;
break;
}
break;
}
}
#endif

}
#endif
return mousePixelCoord;
}
public Vector2 GetMouseClickPosition(float ScreenHeight)
{
#if UNITY_EDITOR
Vector2 mousePixelCoord = m_MouseClickPosition;
mousePixelCoord.y = (ScreenHeight - 1.0f) - mousePixelCoord.y;
return mousePixelCoord;
#else
return Vector2.zero;
#endif
}
}
}

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


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine.Experimental.Rendering.HDPipeline.Attributes;

PreRefractionColorPyramid,
DepthPyramid,
FinalColorPyramid,
ScreenSpaceTracing,
MaxLightingFullScreenDebug,
// Rendering

MaxRenderingFullScreenDebug
}
[GenerateHLSL]
public struct ScreenSpaceTracingDebug
{
public uint startPositionSSX;
public uint startPositionSSY;
public uint cellSizeW;
public uint cellSizeH;
public Vector3 positionSS;
public float startLinearDepth;
public uint level;
public uint levelMax;
public uint iteration;
public uint iterationMax;
public bool hitSuccess;
public float hitLinearDepth;
public Vector2 hitPositionSS;
public float hiZLinearDepth;
public Vector3 raySS;
public uint intersectionKind;
public float resultHitDepth;
public uint endPositionSSX;
public uint endPositionSSY;
public Vector2 startPositionSS { get { return new Vector2(startPositionSSX, startPositionSSY); } }
public Vector2 endPositionSS { get { return new Vector2(endPositionSSX, endPositionSSY); } }
public Vector2 cellId { get { return new Vector2(((int)positionSS.x) >> (int)level, ((int)positionSS.y) >> (int)level); } }
}
public class DebugDisplaySettings
{
public static string k_PanelDisplayStats = "Display Stats";

public static string k_PanelScreenSpaceTracing = "Screen Space Tracing";
static readonly string[] k_HiZIntersectionKind = { "None", "Depth", "Cell" };
DebugUI.Widget[] m_DebugScreenSpaceTracingItems;
public bool showSSRayGrid = true;
public bool showSSRayDepthPyramid = true;
public MaterialDebugSettings materialDebugSettings = new MaterialDebugSettings();
public LightingDebugSettings lightingDebugSettings = new LightingDebugSettings();

public static int[] lightingFullScreenDebugValues = null;
public static GUIContent[] renderingFullScreenDebugStrings = null;
public static int[] renderingFullScreenDebugValues = null;
public static GUIContent[] debugScreenSpaceTracingStrings = null;
public static int[] debugScreenSpaceTracingValues = null;
public ScreenSpaceTracingDebug screenSpaceTracingDebugData { get; internal set; }
debugScreenSpaceTracingStrings = Enum.GetNames(typeof(DebugScreenSpaceTracing)).Select(s => new GUIContent(s)).ToArray();
debugScreenSpaceTracingValues = (int[])Enum.GetValues(typeof(DebugScreenSpaceTracing));
}
public int GetDebugMaterialIndex()

public DebugLightingMode GetDebugLightingMode()
{
return lightingDebugSettings.debugLightingMode;
}
public int GetDebugLightingSubMode()
{
switch (lightingDebugSettings.debugLightingMode)
{
case DebugLightingMode.ScreenSpaceTracingRefraction:
case DebugLightingMode.ScreenSpaceTracingReflection:
return (int)lightingDebugSettings.debugScreenSpaceTracingMode;
default:
return 0;
}
}
public DebugMipMapMode GetDebugMipMapMode()

mipMapDebugSettings.debugMipMapMode = value;
}
bool IsScreenSpaceTracingIterationDebugEnabled()
{
return fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceTracing;
}
void SetScreenSpaceTracingIterationDebugEnabled(bool value)
{
if (value)
{
lightingDebugSettings.debugLightingMode = DebugLightingMode.ScreenSpaceTracingRefraction;
fullScreenDebugMode = FullScreenDebugMode.ScreenSpaceTracing;
}
else
{
lightingDebugSettings.debugLightingMode = DebugLightingMode.None;
fullScreenDebugMode = FullScreenDebugMode.None;
}
}
void SetScreenSpaceTracingDebugMode(int value)
{
var val = (DebugScreenSpaceTracing)value;
if (val != DebugScreenSpaceTracing.None)
{
lightingDebugSettings.debugLightingMode = DebugLightingMode.ScreenSpaceTracingRefraction;
lightingDebugSettings.debugScreenSpaceTracingMode = (DebugScreenSpaceTracing)value;
}
else
{
lightingDebugSettings.debugLightingMode = DebugLightingMode.None;
lightingDebugSettings.debugScreenSpaceTracingMode = DebugScreenSpaceTracing.None;
}
}
public void UpdateMaterials()
{
//if (mipMapDebugSettings.debugMipMapMode != 0)

panel.children.Add(m_DebugDisplayStatsItems);
}
void RegisterScreenSpaceTracingDebug()
{
var list = new List<DebugUI.Container>();
list.Add(new DebugUI.Container
{
displayName = "Screen Space Tracing Refraction Debug",
children =
{
new DebugUI.Container
{
displayName = "Configuration",
children =
{
new DebugUI.BoolField { displayName = "Debug Iterations", getter = IsScreenSpaceTracingIterationDebugEnabled, setter = SetScreenSpaceTracingIterationDebugEnabled, onValueChanged = RefreshScreenSpaceTracingDebug },
new DebugUI.EnumField { displayName = "Debug Mode", getter = GetDebugLightingSubMode, setter = SetScreenSpaceTracingDebugMode, enumNames = debugScreenSpaceTracingStrings, enumValues = debugScreenSpaceTracingValues, 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 },
}
}
}
});
if (IsScreenSpaceTracingIterationDebugEnabled() || GetDebugLightingSubMode() != 0)
{
list[list.Count - 1].children.Add(new DebugUI.Container
{
displayName = "Loop Information",
children =
{
new DebugUI.Value { displayName = "Start Position", getter = () => string.Format("({0:D0}, {1:D0}) px", screenSpaceTracingDebugData.startPositionSSX, screenSpaceTracingDebugData.startPositionSSY) },
new DebugUI.Value { displayName = "Start Depth", getter = () => string.Format("{0:F7} m", screenSpaceTracingDebugData.startLinearDepth) },
new DebugUI.Value { displayName = "Ray SS", getter = () => string.Format("({0:F7}, {1:F7}) px", screenSpaceTracingDebugData.raySS.x, screenSpaceTracingDebugData.raySS.y) },
new DebugUI.Value { displayName = "Ray SS Depth", getter = () => string.Format("({0:F7}) m", 1f / screenSpaceTracingDebugData.raySS.z) },
new DebugUI.Value { displayName = "Intersection Kind", getter = () => k_HiZIntersectionKind[screenSpaceTracingDebugData.intersectionKind] },
}
});
list[list.Count - 1].children.Add(
new DebugUI.Container
{
displayName = "Iteration Information",
children =
{
new DebugUI.Value { displayName = "Cell id", getter = () => string.Format("({0:F0}, {1:F0}) px", screenSpaceTracingDebugData.cellId.x, screenSpaceTracingDebugData.cellId.y) },
new DebugUI.Value { displayName = "Cell Size", getter = () => string.Format("({0:D0}, {1:D0}) px", screenSpaceTracingDebugData.cellSizeW, screenSpaceTracingDebugData.cellSizeH) },
new DebugUI.Value { displayName = "Level / Max", getter = () => string.Format("{0}/{1}", screenSpaceTracingDebugData.level, screenSpaceTracingDebugData.levelMax) },
new DebugUI.Value { displayName = "Iteration / Max", getter = () => string.Format("{0}/{1}", screenSpaceTracingDebugData.iteration + 1, screenSpaceTracingDebugData.iterationMax) },
new DebugUI.Value { displayName = "Position", getter = () => string.Format("({0:F0}, {1:F0}) px", screenSpaceTracingDebugData.positionSS.x, screenSpaceTracingDebugData.positionSS.y) },
new DebugUI.Value { displayName = "Position Depth", getter = () => string.Format("{0:F7} m", screenSpaceTracingDebugData.hitLinearDepth) },
new DebugUI.Value { displayName = "Depth Buffer", getter = () => string.Format("{0:F7} m", screenSpaceTracingDebugData.hiZLinearDepth) },
new DebugUI.Value { displayName = "Raymarched Distance", getter = () => string.Format("{0:F0} px", ((Vector2)screenSpaceTracingDebugData.positionSS - screenSpaceTracingDebugData.startPositionSS).magnitude) },
}
});
list[list.Count - 1].children.Add( new DebugUI.Container
{
displayName = "Result Information",
children =
{
new DebugUI.Value { displayName = "Success", getter = () => screenSpaceTracingDebugData.hitSuccess },
new DebugUI.Value { displayName = "Position", getter = () => string.Format("({0:D0}, {1:D0}) px", screenSpaceTracingDebugData.endPositionSSX, screenSpaceTracingDebugData.endPositionSSY) },
new DebugUI.Value { displayName = "Position Depth", getter = () => string.Format("{0:F7} m", screenSpaceTracingDebugData.resultHitDepth) },
new DebugUI.Value { displayName = "Raymarched Distance", getter = () => string.Format("{0:F0} px", (screenSpaceTracingDebugData.startPositionSS - screenSpaceTracingDebugData.endPositionSS).magnitude) },
}
});
}
m_DebugScreenSpaceTracingItems = list.ToArray();
var panel = DebugManager.instance.GetPanel(k_PanelScreenSpaceTracing, true);
panel.flags |= DebugUI.Flags.ForceUpdate;
panel.children.Add(m_DebugScreenSpaceTracingItems);
}
public void RegisterMaterialDebug()
{
m_DebugMaterialItems = new DebugUI.Widget[]

{
UnregisterDebugItems(k_PanelLighting, m_DebugLightingItems);
RegisterLightingDebug();
}
void RefreshScreenSpaceTracingDebug<T>(DebugUI.Field<T> field, T value)
{
UnregisterDebugItems(k_PanelScreenSpaceTracing, m_DebugScreenSpaceTracingItems);
RegisterScreenSpaceTracingDebug();
}
public void RegisterLightingDebug()

RegisterMaterialDebug();
RegisterLightingDebug();
RegisterRenderingDebug();
RegisterScreenSpaceTracingDebug();
}
public void UnregisterDebug()

UnregisterDebugItems(k_PanelLighting, m_DebugLightingItems);
UnregisterDebugItems(k_PanelRendering, m_DebugRenderingItems);
UnregisterDebugItems(k_PanelScreenSpaceTracing, m_DebugScreenSpaceTracingItems);
}
void UnregisterDebugItems(string panelName, DebugUI.Widget[] items)

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


#define FULLSCREENDEBUGMODE_PRE_REFRACTION_COLOR_PYRAMID (4)
#define FULLSCREENDEBUGMODE_DEPTH_PYRAMID (5)
#define FULLSCREENDEBUGMODE_FINAL_COLOR_PYRAMID (6)
#define FULLSCREENDEBUGMODE_MAX_LIGHTING_FULL_SCREEN_DEBUG (7)
#define FULLSCREENDEBUGMODE_MIN_RENDERING_FULL_SCREEN_DEBUG (8)
#define FULLSCREENDEBUGMODE_MOTION_VECTORS (9)
#define FULLSCREENDEBUGMODE_NAN_TRACKER (10)
#define FULLSCREENDEBUGMODE_MAX_RENDERING_FULL_SCREEN_DEBUG (11)
#define FULLSCREENDEBUGMODE_SCREEN_SPACE_TRACING (7)
#define FULLSCREENDEBUGMODE_MAX_LIGHTING_FULL_SCREEN_DEBUG (8)
#define FULLSCREENDEBUGMODE_MIN_RENDERING_FULL_SCREEN_DEBUG (9)
#define FULLSCREENDEBUGMODE_MOTION_VECTORS (10)
#define FULLSCREENDEBUGMODE_NAN_TRACKER (11)
#define FULLSCREENDEBUGMODE_MAX_RENDERING_FULL_SCREEN_DEBUG (12)
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.ScreenSpaceTracingDebug
// PackingRules = Exact
struct ScreenSpaceTracingDebug
{
uint startPositionSSX;
uint startPositionSSY;
uint cellSizeW;
uint cellSizeH;
float3 positionSS;
float startLinearDepth;
uint level;
uint levelMax;
uint iteration;
uint iterationMax;
bool hitSuccess;
float hitLinearDepth;
float2 hitPositionSS;
float hiZLinearDepth;
float3 raySS;
uint intersectionKind;
float resultHitDepth;
uint endPositionSSX;
uint endPositionSSY;
};
//
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.ScreenSpaceTracingDebug
//
uint GetStartPositionSSX(ScreenSpaceTracingDebug value)
{
return value.startPositionSSX;
}
uint GetStartPositionSSY(ScreenSpaceTracingDebug value)
{
return value.startPositionSSY;
}
uint GetCellSizeW(ScreenSpaceTracingDebug value)
{
return value.cellSizeW;
}
uint GetCellSizeH(ScreenSpaceTracingDebug value)
{
return value.cellSizeH;
}
float3 GetPositionSS(ScreenSpaceTracingDebug value)
{
return value.positionSS;
}
float GetStartLinearDepth(ScreenSpaceTracingDebug value)
{
return value.startLinearDepth;
}
uint GetLevel(ScreenSpaceTracingDebug value)
{
return value.level;
}
uint GetLevelMax(ScreenSpaceTracingDebug value)
{
return value.levelMax;
}
uint GetIteration(ScreenSpaceTracingDebug value)
{
return value.iteration;
}
uint GetIterationMax(ScreenSpaceTracingDebug value)
{
return value.iterationMax;
}
bool GetHitSuccess(ScreenSpaceTracingDebug value)
{
return value.hitSuccess;
}
float GetHitLinearDepth(ScreenSpaceTracingDebug value)
{
return value.hitLinearDepth;
}
float2 GetHitPositionSS(ScreenSpaceTracingDebug value)
{
return value.hitPositionSS;
}
float GetHiZLinearDepth(ScreenSpaceTracingDebug value)
{
return value.hiZLinearDepth;
}
float3 GetRaySS(ScreenSpaceTracingDebug value)
{
return value.raySS;
}
uint GetIntersectionKind(ScreenSpaceTracingDebug value)
{
return value.intersectionKind;
}
float GetResultHitDepth(ScreenSpaceTracingDebug value)
{
return value.resultHitDepth;
}
uint GetEndPositionSSX(ScreenSpaceTracingDebug value)
{
return value.endPositionSSX;
}
uint GetEndPositionSSY(ScreenSpaceTracingDebug value)
{
return value.endPositionSSY;
}
#endif

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


CBUFFER_START(UnityDebugDisplay)
// Set of parameters available when switching to debug shader mode
int _DebugLightingMode; // Match enum DebugLightingMode
int _DebugLightingSubMode;
int _DebugStep;
float4 _MouseClickPixelCoord; // xy unorm, zw norm
float _DebugEnvironmentProxyDepthScale;
float _DebugExposure;
CBUFFER_END

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


IndirectSpecularGtaoFromSsao,
EnvironmentProxyVolume,
EnvironmentSampleCoordinates,
ScreenSpaceTracingRefraction
ScreenSpaceTracingRefraction,
ScreenSpaceTracingReflection
None,
Color,
PositionNDC,
RayDirWS,
RayDirNDC,

}
public DebugLightingMode debugLightingMode = DebugLightingMode.None;
public DebugScreenSpaceTracing debugScreenSpaceTracingMode = DebugScreenSpaceTracing.None;
public ShadowMapDebugMode shadowDebugMode = ShadowMapDebugMode.None;
public bool shadowDebugUseSelection = false;
public uint shadowMapIndex = 0;

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


#define DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_GTAO_FROM_SSAO (8)
#define DEBUGLIGHTINGMODE_ENVIRONMENT_PROXY_VOLUME (9)
#define DEBUGLIGHTINGMODE_ENVIRONMENT_SAMPLE_COORDINATES (10)
#define DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION (11)
#define DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFLECTION (12)
//
// UnityEngine.Experimental.Rendering.HDPipeline.DebugScreenSpaceTracing: static fields
//
#define DEBUGSCREENSPACETRACING_NONE (0)
#define DEBUGSCREENSPACETRACING_COLOR (1)
#define DEBUGSCREENSPACETRACING_POSITION_NDC (2)
#define DEBUGSCREENSPACETRACING_RAY_DIR_WS (3)
#define DEBUGSCREENSPACETRACING_RAY_DIR_NDC (4)
#define DEBUGSCREENSPACETRACING_HIT_DEPTH (5)
#define DEBUGSCREENSPACETRACING_HIT_SUCCESS (6)
#define DEBUGSCREENSPACETRACING_ITERATION_COUNT (7)
#define DEBUGSCREENSPACETRACING_MAX_USED_MIP_LEVEL (8)
#define DEBUGSCREENSPACETRACING_INTERSECTION_KIND (9)
#endif

2
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 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");

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

23
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


FrameSettings m_FrameSettings; // Init every frame
ComputeBuffer m_DebugScreenSpaceTracingData = null;
ScreenSpaceTracingDebug[] m_DebugScreenSpaceTracingDataArray = new ScreenSpaceTracingDebug[1];
public HDRenderPipeline(HDRenderPipelineAsset asset)
{
SetRenderingFeatures();

// We don't need the debug of Scene View at runtime (each camera have its own debug settings)
FrameSettings.RegisterDebug("Scene View", m_Asset.GetFrameSettings());
#endif
m_DebugScreenSpaceTracingData = new ComputeBuffer(1, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ScreenSpaceTracingDebug)));
InitializeRenderTextures();

RTHandle.Release(m_DebugColorPickerBuffer);
RTHandle.Release(m_DebugFullScreenTempBuffer);
m_DebugScreenSpaceTracingData.Release();
}

m_DbufferManager.PushGlobalParams(cmd, m_FrameSettings);
m_VolumetricLightingSystem.PushGlobalParams(hdCamera, cmd);
var ssrefraction = VolumeManager.instance.stack.GetComponent<ScreenSpaceRefractionVolume>();
if (ssrefraction != null)
ssrefraction.PushShaderParameters(cmd);
}
}

RenderGaussianPyramidColor(hdCamera, cmd, renderContext, true);
// Render all type of transparent forward (unlit, lit, complex (hair...)) to keep the sorting between transparent objects.
cmd.SetGlobalBuffer(HDShaderIDs._DebugScreenSpaceTracingData, m_DebugScreenSpaceTracingData);
cmd.SetRandomWriteTarget(1, m_DebugScreenSpaceTracingData);
cmd.ClearRandomWriteTargets();
RenderForwardError(m_CullResults, hdCamera, renderContext, cmd, ForwardPass.Transparent);
// Fill depth buffer to reduce artifact for transparent object during postprocess

CommandBufferPool.Release(cmd);
renderContext.Submit();
if (m_CurrentDebugDisplaySettings.fullScreenDebugMode == FullScreenDebugMode.ScreenSpaceTracing)
{
m_DebugScreenSpaceTracingData.GetData(m_DebugScreenSpaceTracingDataArray);
var data = m_DebugScreenSpaceTracingDataArray[0];
m_CurrentDebugDisplaySettings.screenSpaceTracingDebugData = data;
}
} // For each camera
}

cmd.SetGlobalInt(HDShaderIDs._DebugViewMaterial, (int)m_CurrentDebugDisplaySettings.GetDebugMaterialIndex());
cmd.SetGlobalInt(HDShaderIDs._DebugLightingMode, (int)m_CurrentDebugDisplaySettings.GetDebugLightingMode());
cmd.SetGlobalInt(HDShaderIDs._DebugLightingSubMode, (int)m_CurrentDebugDisplaySettings.GetDebugLightingSubMode());
cmd.SetGlobalInt(HDShaderIDs._DebugMipMapMode, (int)m_CurrentDebugDisplaySettings.GetDebugMipMapMode());
cmd.SetGlobalVector(HDShaderIDs._DebugLightingAlbedo, debugAlbedo);

cmd.SetGlobalVector(HDShaderIDs._MousePixelCoord, HDUtils.GetMouseCoordinates(hdCamera));
cmd.SetGlobalVector(HDShaderIDs._MouseClickPixelCoord, HDUtils.GetMouseClickCoordinates(hdCamera));
cmd.SetGlobalInt(HDShaderIDs._DebugStep, HDUtils.debugStep);
// 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);

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs


public static readonly int _ViewTilesFlags = Shader.PropertyToID("_ViewTilesFlags");
public static readonly int _MousePixelCoord = Shader.PropertyToID("_MousePixelCoord");
public static readonly int _MouseClickPixelCoord = Shader.PropertyToID("_MouseClickPixelCoord");
public static readonly int _DebugStep = Shader.PropertyToID("_DebugStep");
public static readonly int _DebugScreenSpaceTracingData = Shader.PropertyToID("_DebugScreenSpaceTracingData");
public static readonly int _DebugLightingSubMode = Shader.PropertyToID("_DebugLightingSubMode");
public static readonly int _DebugLightingAlbedo = Shader.PropertyToID("_DebugLightingAlbedo");
public static readonly int _DebugLightingSmoothness = Shader.PropertyToID("_DebugLightingSmoothness");
public static readonly int _DebugLightingNormal = Shader.PropertyToID("_DebugLightingNormal");

Shader.PropertyToID("_SSSBufferTexture2"),
Shader.PropertyToID("_SSSBufferTexture3"),
};
public static readonly int _SSRefractionRayMinLevel = Shader.PropertyToID("_SSRefractionRayMinLevel");
public static readonly int _SSRefractionRayMaxLevel = Shader.PropertyToID("_SSRefractionRayMaxLevel");
public static readonly int _SSRefractionRayMaxIterations = Shader.PropertyToID("_SSRefractionRayMaxIterations");
public static readonly int _SSRefractionRayDepthSuccessBias = Shader.PropertyToID("_SSRefractionRayDepthSuccessBias");
public static readonly int _VelocityTexture = Shader.PropertyToID("_VelocityTexture");
public static readonly int _ShadowMaskTexture = Shader.PropertyToID("_ShadowMaskTexture");

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDUtils.cs


return null;
}
}
public static int debugStep { get { return MousePositionDebug.instance.debugStep; } }
static MaterialPropertyBlock s_PropertyBlock = new MaterialPropertyBlock();

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

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


m_DebugViewTilesMaterial.SetInt(HDShaderIDs._NumTiles, numTiles);
m_DebugViewTilesMaterial.SetInt(HDShaderIDs._ViewTilesFlags, (int)lightingDebug.tileClusterDebugByCategory);
m_DebugViewTilesMaterial.SetVector(HDShaderIDs._MousePixelCoord, HDUtils.GetMouseCoordinates(hdCamera));
m_DebugViewTilesMaterial.SetVector(HDShaderIDs._MouseClickPixelCoord, HDUtils.GetMouseClickCoordinates(hdCamera));
m_DebugViewTilesMaterial.SetBuffer(HDShaderIDs.g_TileList, s_TileList);
m_DebugViewTilesMaterial.SetBuffer(HDShaderIDs.g_DispatchIndirectBuffer, s_DispatchIndirectBuffer);
m_DebugViewTilesMaterial.EnableKeyword("USE_FPTL_LIGHTLIST");

// lightCategories
m_DebugViewTilesMaterial.SetInt(HDShaderIDs._ViewTilesFlags, (int)lightingDebug.tileClusterDebugByCategory);
m_DebugViewTilesMaterial.SetVector(HDShaderIDs._MousePixelCoord, HDUtils.GetMouseCoordinates(hdCamera));
m_DebugViewTilesMaterial.SetVector(HDShaderIDs._MouseClickPixelCoord, HDUtils.GetMouseClickCoordinates(hdCamera));
m_DebugViewTilesMaterial.SetBuffer(HDShaderIDs.g_vLightListGlobal, bUseClustered ? s_PerVoxelLightLists : s_LightList);
m_DebugViewTilesMaterial.EnableKeyword(bUseClustered ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DebugViewTilesMaterial.DisableKeyword(!bUseClustered ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");

24
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.hlsl


float reflectionHierarchyWeight = 0.0; // Max: 1.0
float refractionHierarchyWeight = 0.0; // Max: 1.0
// Fetch first env light to provide the scene proxy
EnvLightData firstEnvLight;
ZERO_INITIALIZE(EnvLightData, firstEnvLight);
{
#ifdef LIGHTLOOP_TILE_PASS
uint envLightStart;
uint envLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount);
#else
uint envLightCount = _EnvLightCount;
#endif
if (envLightCount > 0)
{
#ifdef LIGHTLOOP_TILE_PASS
uint envLightIndex = FetchIndex(envLightStart, 0);
#else
uint envLightIndex = 0;
#endif
firstEnvLight = _EnvLightDatas[envLightIndex];
}
}
if (featureFlags & LIGHTFEATUREFLAGS_SSREFRACTION)
{
IndirectLighting lighting = EvaluateBSDF_SSLighting(

preLightData,
bsdfData,
firstEnvLight,
GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION,
refractionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);

posInput,
preLightData,
bsdfData,
firstEnvLight,
GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION,
reflectionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);

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


// Algorithm uniform parameters
// -------------------------------------------------
CBUFFER_START(UnityScreenSpaceRaymarching)
int _SSRayMinLevel;
int _SSRayMaxLevel;
int _SSRayMaxIterations;
float _SSRayDepthSuccessBias;
CBUFFER_END
const float DepthPlaneBias = 1E-5;
// -------------------------------------------------

#endif
};
struct ScreenSpaceHiZRaymarchInput
{
float3 rayOriginWS; // Ray origin (WS)
float3 rayDirWS; // Ray direction (WS)
uint maxIterations; // Number of iterations before failing
#ifdef DEBUG_DISPLAY
bool debug;
#endif
};
struct ScreenSpaceProxyRaycastInput
{
float3 rayOriginWS; // Ray origin (WS)
float3 rayDirWS; // Ray direction (WS)
EnvLightData proxyData;
#ifdef DEBUG_DISPLAY
bool debug;
#endif
};
// -------------------------------------------------
// Utilities
// -------------------------------------------------

float3 rayDirWS,
uint2 bufferSize,
out float3 positionSS,
out float3 raySS)
out float3 raySS
)
{
float3 positionWS = rayOriginWS;
float3 rayEndWS = rayOriginWS + rayDirWS * 10;

int2 cellId,
uint2 cellSize,
int2 cellPlanes,
float2 crossOffset)
float2 crossOffset
)
{
const float SQRT_2 = sqrt(2);
const float CellPlaneBias = 1E-2;

void FillScreenSpaceRaymarchingHitDebug(
uint2 bufferSize,
float3 rayDirWS,
float3 raySS,
float3 rayDirSS,
float3 startPositionSS,
bool hitSuccessful,
int iteration,

int intersectionKind,
inout ScreenSpaceRayHit hit)
inout ScreenSpaceRayHit hit
)
if (_DebugLightingMode == DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION)
switch (_DebugLightingSubMode)
switch (_DebugLightingSubMode)
{
case DEBUGSCREENSPACETRACING_POSITION_NDC:
debugOutput = float3(float2(startPositionSS.xy) / bufferSize, 0);
break;
case DEBUGSCREENSPACETRACING_DIR_WS:
debugOutput = rayDirWS * 0.5 + 0.5;
break;
case DEBUGSCREENSPACETRACING_DIR_NDC:
debugOutput = float3(raySS.xy * 0.5 + 0.5, frac(0.1 / raySS.z));
break;
case DEBUGSCREENSPACETRACING_HIT_DEPTH:
debugOutput = frac(hit.linearDepth * 0.1);
break;
case DEBUGSCREENSPACETRACING_HIT_SUCCESS:
debugOutput = hitSuccessful;
break;
case DEBUGSCREENSPACETRACING_ITERATION_COUNT:
debugOutput = float(iteration) / float(maxIterations);
break;
case DEBUGSCREENSPACETRACING_MAX_USED_LEVEL:
debugOutput = float(maxUsedLevel) / float(maxMipLevel);
break;
case DEBUGSCREENSPACETRACING_INTERSECTION_KIND:
debugOutput = GetIndexColor(intersectionKind);
break;
}
case DEBUGSCREENSPACETRACING_POSITION_NDC:
debugOutput = float3(float2(startPositionSS.xy) / bufferSize, 0);
break;
case DEBUGSCREENSPACETRACING_DIR_WS:
debugOutput = rayDirWS * 0.5 + 0.5;
break;
case DEBUGSCREENSPACETRACING_DIR_NDC:
debugOutput = float3(rayDirSS.xy * 0.5 + 0.5, frac(0.1 / rayDirSS.z));
break;
case DEBUGSCREENSPACETRACING_HIT_DEPTH:
debugOutput = frac(hit.linearDepth * 0.1);
break;
case DEBUGSCREENSPACETRACING_HIT_SUCCESS:
debugOutput = hitSuccessful;
break;
case DEBUGSCREENSPACETRACING_ITERATION_COUNT:
debugOutput = float(iteration) / float(maxIterations);
break;
case DEBUGSCREENSPACETRACING_MAX_USED_LEVEL:
debugOutput = float(maxUsedLevel) / float(maxMipLevel);
break;
case DEBUGSCREENSPACETRACING_INTERSECTION_KIND:
debugOutput = GetIndexColor(intersectionKind);
break;
}
hit.debugOutput = debugOutput;
}

inout ScreenSpaceTracingDebug debug)
inout ScreenSpaceTracingDebug debug
)
{
debug.startPositionSSX = uint(startPositionSS.x);
debug.startPositionSSY = uint(startPositionSS.y);

float3 raySS,
bool hitSuccess,
ScreenSpaceRayHit hit,
inout ScreenSpaceTracingDebug debug)
inout ScreenSpaceTracingDebug debug
)
{
debug.levelMax = maxUsedLevel;
debug.iterationMax = iteration;

void FillScreenSpaceRaymarchingPreIterationDebug(
int iteration,
int currentLevel,
inout ScreenSpaceTracingDebug debug)
inout ScreenSpaceTracingDebug debug
)
{
if (_DebugStep >= iteration)
debug.level = currentLevel;

float3 positionSS,
float invHiZDepth,
uint intersectionKind,
inout ScreenSpaceTracingDebug debug)
inout ScreenSpaceTracingDebug debug
)
{
if (_DebugStep >= iteration)
{

}
}
#endif
#endif
struct ScreenSpaceProxyRaycastInput
{
float3 rayOriginWS; // Ray origin (WS)
float3 rayDirWS; // Ray direction (WS)
#ifdef SSRTID
#define SSRT_SETTING(name) _SS#SSRTID#name
#define SSRT_FUNC(name) name#SSRTID
#ifdef DEBUG_DISPLAY
bool writeStepDebug;
#endif
};
CBUFFER_START(SSRT_FUNC(UnityScreenSpaceRaymarching)
int SSRT_SETTING(RayMinLevel);
int SSRT_SETTING(RayMaxLevel);
int SSRT_SETTING(RayMaxIterations);
float SSRT_SETTING(RayDepthSuccessBias);
CBUFFER_END
bool ScreenSpaceEstimateRaycast(
bool SSRT_FUNC(ScreenSpaceProxyRaycast)(
out ScreenSpaceRayHit hit)
out ScreenSpaceRayHit hit
)
float3x3 worldToPS = WorldToProxySpace(input.proxyData);
float3 rayOriginPS = WorldToProxyPosition(input.proxyData, worldToPS, input.rayOriginWS);
float3 rayDirPS = mul(input.rayDirWS, worldToPS);
float projectionDistance = 0.0;
switch(input.proxyData.influenceShapeType)
{
case ENVSHAPETYPE_SPHERE:
projectionDistance = IntersectSphereProxy(input.proxyData, rayDirPS, rayOriginPS);
break;
case ENVSHAPETYPE_BOX:
projectionDistance = IntersectBoxProxy(input.proxyData, rayDirPS, rayOriginPS);
break;
}
float3 hitPositionWS = input.rayOriginWS + input.rayDirWS * projectionDistance;
float3 hitPositionCS = ComputeClipSpacePosition(hitPositionWS, GetWorldToHClipMatrix());
float2 hitPositionNDC = ComputeNormalizedDeviceCoordinates(hitPositionWS, GetWorldToHClipMatrix());
uint2 hitPositionSS = uint2(hitPositionNDC *_ScreenSize.xy);
float hitLinearDepth = hitPositionCS.w;
float linearDepth = LoadDepth(hitPositionSS, 0);
input.positionNDC = hitPositionNDC;
input.positionSS = hitPositionSS;
input.linearDepth = hitLinearDepth;
bool hitSuccessful = linearDepth >= hitLinearDepth;
#ifdef DEBUG_DISPLAY
FillScreenSpaceRaymarchingHitDebug(
uint2(_ScreenSize.xy), // bufferSize
input.rayDirWS,
float3(0.0, 0.0, 0.0), // rayDirSS
float3(0.0, 0.0, 0.0), // startPositionSS
hitSuccessful,
0, // iteration,
1, // maxIterations,
0, // maxUsedLevel,
0, // maxMipLevel,
3, // intersectionKind,
inout hit
);
if (input.debug)
{
ScreenSpaceTracingDebug debug;
ZERO_INITIALIZE(ScreenSpaceTracingDebug, debug);
FillScreenSpaceRaymarchingPreLoopDebug(
float3(0.0, 0.0, 0.0), // startPositionSS
inout debug
);
FillScreenSpaceRaymarchingPostLoopDebug(
0, // maxUsedLevel,
0, // iteration,
float3(0.0, 0.0, 0.0), // raySS,
hitSuccessful,
hit,
inout debug
);
FillScreenSpaceRaymarchingPreIterationDebug(
0, // iteration,
0, // currentLevel,
inout debug
);
FillScreenSpaceRaymarchingPostIterationDebug(
0, // iteration,
uint2(0, 0), // cellSize,
float3(0.0, 0.0, 0.0), // positionSS,
1.0 / input.linearDepth, // invHiZDepth,
3, // intersectionKind,
inout debug
);
_DebugScreenSpaceTracingData[0] = debug;
}
#endif
return false;
}

// Based on Yasin Uludag, 2014. "Hi-Z Screen-Space Cone-Traced Reflections", GPU Pro5: Advanced Rendering Techniques
struct ScreenSpaceHiZRaymarchInput
{
float3 rayOriginWS; // Ray origin (WS)
float3 rayDirWS; // Ray direction (WS)
uint maxIterations; // Number of iterations before failing
#ifdef DEBUG_DISPLAY
bool writeStepDebug;
#endif
};
bool ScreenSpaceHiZRaymarch(
bool SSRT_FUNC(ScreenSpaceHiZRaymarch)(
out ScreenSpaceRayHit hit)
out ScreenSpaceRayHit hit
)
{
const float2 CROSS_OFFSET = float2(1, 1);

uint iteration = 0u;
int minMipLevel = max(_SSRayMinLevel, 0);
int maxMipLevel = min(_SSRayMaxLevel, int(_DepthPyramidScale.z));
int minMipLevel = max(SSRT_SETTING(MinLevel), 0);
int maxMipLevel = min(SSRT_SETTING(MaxLevel), int(_DepthPyramidScale.z));
uint maxIterations = min(input.maxIterations, _SSRayMaxIterations);
uint maxIterations = min(input.maxIterations, SSRT_SETTING(MaxIterations));
float3 startPositionSS;
float3 raySS;

bufferSize,
startPositionSS,
raySS);
raySS
);
FillScreenSpaceRaymarchingPreLoopDebug(startPositionSS, debug);
if (input.debug)
FillScreenSpaceRaymarchingPreLoopDebug(startPositionSS, debug);
#endif
int intersectionKind = 0;

#ifdef DEBUG_DISPLAY
FillScreenSpaceRaymarchingPreIterationDebug(iteration, currentLevel, debug);
if (input.debug)
FillScreenSpaceRaymarchingPreIterationDebug(iteration, currentLevel, debug);
#endif
// Go down in HiZ levels by default

#ifdef DEBUG_DISPLAY
maxUsedLevel = max(maxUsedLevel, currentLevel);
FillScreenSpaceRaymarchingPostIterationDebug(
iteration,
cellSize,
positionSS,
invHiZDepth,
intersectionKind,
debug);
if (input.debug)
FillScreenSpaceRaymarchingPostIterationDebug(
iteration,
cellSize,
positionSS,
invHiZDepth,
intersectionKind,
debug
);
#endif
// Check if we are out of the buffer

hit.positionNDC = float2(positionSS.xy) / float2(bufferSize);
hit.positionSS = uint2(positionSS.xy);
if (hit.linearDepth > (1 / invHiZDepth) + _SSRayDepthSuccessBias)
if (hit.linearDepth > (1 / invHiZDepth) + SSRT_SETTING(DepthSuccessBias))
FillScreenSpaceRaymarchingPostLoopDebug(
maxUsedLevel,
iteration,
raySS,
hitSuccessful,
hit,
debug);
FillScreenSpaceRaymarchingHitDebug(
bufferSize,
input.rayDirVS,
raySS,
startPositionSS,
hitSuccessful,
iteration,
_SSRayMaxIterations,
maxMipLevel,
maxUsedLevel,
intersectionKind,
hit);
if (input.writeStepDebug)
_DebugScreenSpaceTracingData[0] = debug;
#endif
return hitSuccessful;
}
// -------------------------------------------------
// Algorithm: Linear raymarching
// -------------------------------------------------
// Based on DDA (https://en.wikipedia.org/wiki/Digital_differential_analyzer_(graphics_algorithm))
// Based on Morgan McGuire and Michael Mara, 2014. "Efficient GPU Screen-Space Ray Tracing", Journal of Computer Graphics Techniques (JCGT), 235-256
struct ScreenSpaceLinearRaymarchInput
{
float3 rayOriginVS; // Ray origin (VS)
float3 rayDirVS; // Ray direction (VS)
float4x4 projectionMatrix; // Projection matrix of the camera
uint maxIterations; // Number of iterations before failing
#ifdef DEBUG_DISPLAY
bool writeStepDebug;
#endif
};
// Basically, perform a raycast with DDA technique on a specific mip level of the Depth pyramid.
bool ScreenSpaceLinearRaymarch(
ScreenSpaceLinearRaymarchInput input,
out ScreenSpaceRayHit hit)
{
const float2 CROSS_OFFSET = float2(1, 1);
// Initialize loop
ZERO_INITIALIZE(ScreenSpaceRayHit, hit);
bool hitSuccessful = true;
uint iteration = 0u;
int level = clamp(_SSRayMinLevel, 0, int(_DepthPyramidScale.z));
uint2 bufferSize = uint2(_DepthPyramidSize.xy);
uint maxIterations = min(input.maxIterations, _SSRayMaxIterations);
float3 startPositionSS;
float3 raySS;
CalculateRaySS(
input.rayOriginVS,
input.rayDirVS,
input.projectionMatrix,
bufferSize,
startPositionSS,
raySS);
#ifdef DEBUG_DISPLAY
ScreenSpaceTracingDebug debug;
ZERO_INITIALIZE(ScreenSpaceTracingDebug, debug);
FillScreenSpaceRaymarchingPreLoopDebug(startPositionSS, debug);
#endif
float maxAbsAxis = max(abs(raySS.x), abs(raySS.y));
// No need to raymarch if the ray is along camera's foward
if (maxAbsAxis < 1E-7)
if (input.debug)
hit.distanceSS = 1 / startPositionSS.z;
hit.linearDepth = 1 / startPositionSS.z;
hit.positionSS = uint2(startPositionSS.xy);
FillScreenSpaceRaymarchingPostLoopDebug(
maxUsedLevel,
iteration,
raySS,
hitSuccessful,
hit,
debug
);
FillScreenSpaceRaymarchingHitDebug(
bufferSize,
input.rayDirVS,
raySS,
startPositionSS,
hitSuccessful,
iteration,
SSRT_SETTING(MaxIterations),
maxMipLevel,
maxUsedLevel,
intersectionKind,
hit
);
_DebugScreenSpaceTracingData[0] = debug;
else
{
// DDA step
raySS /= max(abs(raySS.x), abs(raySS.y));
raySS *= _SSRayMinLevel;
float distanceStepSS = length(raySS.xy);
float3 positionSS = startPositionSS;
// TODO: We should have a for loop from the starting point to the far/near plane
while (iteration < maxIterations)
{
#ifdef DEBUG_DISPLAY
FillScreenSpaceRaymarchingPreIterationDebug(iteration, 0, debug);
#endif
positionSS += raySS;
hit.distanceSS += distanceStepSS;
float invHiZDepth = LoadInvDepth(positionSS.xy, _SSRayMinLevel);
#ifdef DEBUG_DISPLAY
FillScreenSpaceRaymarchingPostIterationDebug(
iteration,
uint2(0, 0),
positionSS,
invHiZDepth,
0,
debug);
#endif
if (!IsPositionAboveDepth(positionSS.z, invHiZDepth))
{
if (1 / positionSS.z > (1 / invHiZDepth + _SSRayDepthSuccessBias))
hitSuccessful = false;
break;
}
// Check if we are out of the buffer
if (any(int2(positionSS.xy) > int2(bufferSize))
|| any(positionSS.xy < 0))
{
hitSuccessful = false;
break;
}
++iteration;
}
hit.linearDepth = 1 / positionSS.z;
hit.positionNDC = float2(positionSS.xy) / float2(bufferSize);
hit.positionSS = uint2(positionSS.xy);
}
#ifdef DEBUG_DISPLAY
FillScreenSpaceRaymarchingPostLoopDebug(
0,
iteration,
raySS,
hitSuccessful,
hit,
debug);
FillScreenSpaceRaymarchingHitDebug(
bufferSize,
input.rayDirVS,
raySS,
startPositionSS,
hitSuccessful,
iteration,
_SSRayMaxIterations,
0,
0,
0,
hit);
if (input.writeStepDebug)
_DebugScreenSpaceTracingData[0] = debug;
#undef SSRT_SETTING
#endif

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


#define MATERIALFEATUREFLAGS_LIT_CLEAR_COAT (64)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+RefractionMode: static fields
//
#define REFRACTIONMODE_NONE (0)
#define REFRACTIONMODE_PLANE (1)
#define REFRACTIONMODE_SPHERE (2)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Lit+SurfaceData: static fields
//
#define DEBUGVIEW_LIT_SURFACEDATA_MATERIAL_FEATURES (1000)

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


#if HAS_REFRACTION
# include "CoreRP/ShaderLibrary/Refraction.hlsl"
# define SSRTID Refraction
# include "HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl"
# undef SSRTID
# if defined(_REFRACTION_PLANE)
# define REFRACTION_MODEL(V, posInputs, bsdfData) RefractionModelPlane(V, posInputs.positionWS, bsdfData.normalWS, bsdfData.ior, bsdfData.thickness)

#endif
float3 EstimateRaycast(float3 V, PositionInputs posInputs, float3 positionWS, float3 rayWS)
{
// For all refraction approximation, to calculate the refracted point in world space,
// we approximate the scene as a plane (back plane) with normal -V at the depth hit point.
// (We avoid to raymarch the depth texture to get the refracted point.)
uint2 depthSize = uint2(_PyramidDepthMipSize.xy);
// Get the depth of the approximated back plane
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, posInputs.positionNDC * (depthSize >> 2), 2).r;
float depth = LinearEyeDepth(pyramidDepth, _ZBufferParams);
// Distance from point to the back plane
float depthFromPositionInput = depth - posInputs.linearDepth;
float offset = dot(-V, positionWS - posInputs.positionWS);
float depthFromPosition = depthFromPositionInput - offset;
float hitDistanceFromPosition = depthFromPosition / dot(-V, rayWS);
return positionWS + rayWS * hitDistanceFromPosition;
}
# if defined(_REFRACTION_SSRAY_PROXY)
# define REFRACTION_SSRAY_IN ScreenSpaceProxyRaycastInput
# define REFRACTION_SSRAY_QUERY(input, hit) ScreenSpaceProxyRaycastRefraction(input, out hit)
# elif defined(_REFRACTION_SSRAY_HIZ)
# define REFRACTION_SSRAY_IN ScreenSpaceHiZRaymarchInput
# define REFRACTION_SSRAY_QUERY(input, hit) ScreenSpaceHiZRaymarchRefraction(input, out 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).
// This is only useful for classification during lighting, so it's not needed in EncodeIntoGBuffer and ConvertSurfaceDataToBSDFData (where we always know exactly what the material feature is)

IndirectLighting EvaluateBSDF_SSLighting(LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, BSDFData bsdfData,
EnvLightData envLightData,
int GPUImageBasedLightingType,
inout float hierarchyWeight)
{

{
case GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION:
{
#if HAS_REFRACTION
// Refraction process:

// 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)
#ifdef _REFRACTION_SSRAY_PROXY
#elif _REFRACTION_SSRAY_HIZ
#endif
float3 rayOriginWS = preLightData.transparentPositionWS;
float3 rayDirWS = preLightData.transparentRefractV;
#if DEBUG_DISPLAY
int debugMode = DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION;
bool debug = _DebugLightingMode == debugMode
&& !any(int2(_MouseClickPixelCoord.xy) - int2(posInput.positionSS));
#endif
// Initialize screen space tracing
REFRACTION_SSRAY_IN input;
ZERO_INITIALIZE(REFRACTION_SSRAY_IN, input);
// Common initialization
input.rayOriginWS = rayOriginWS;
input.rayDirWS = rayDirWS;
#if DEBUG_DISPLAY
input.debug = debug
#endif
// Algorithm specific initialization
#ifdef _REFRACTION_SSRAY_HIZ
input.maxIterations = uint(-1);
#elif _REFRACTION_SSRAY_PROXY
input.proxyData = envLightData;
#endif
// Perform ray query
ScreenSpaceRayHit hit;
ZERO_INITIALIZE(ScreenSpaceRayHit, hit);
REFRACTION_SSRAY_QUERY(input, hit);
// Debug screen space tracing
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == debugMode
&& _DebugLightingSubMode != DEBUGSCREENSPACETRACING_COLOR)
{
float weight = 1.0;
UpdateLightingHierarchyWeights(hierarchyWeight, weight);
lighting.specularTransmitted = hit.debugOutput;
return lighting;
}
#endif
float3 refractedBackPointWS = EstimateRaycast(V, posInput, preLightData.transparentPositionWS, preLightData.transparentRefractV);
if (!hitSuccessful)
return lighting;
// Calculate screen space coordinates of refracted point in back plane
float2 refractedBackPointNDC = ComputeNormalizedDeviceCoordinates(refractedBackPointWS, UNITY_MATRIX_VP);
uint2 depthSize = uint2(_PyramidDepthMipSize.xy);
float refractedBackPointDepth = LinearEyeDepth(LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, refractedBackPointNDC * depthSize, 0).r, _ZBufferParams);
float2 weightNDC = clamp(min(hit.positionNDC, 1 - hit.positionNDC) * _InvScreenWeightDistance, 0, 1);
weightNDC = weightNDC * weightNDC * (3 - 2 * weightNDC);
float weight = weightNDC.x * weightNDC.y;
if (refractedBackPointDepth < posInput.linearDepth
|| any(refractedBackPointNDC < 0.0)
|| any(refractedBackPointNDC > 1.0))
if (hit.linearDepth < posInput.linearDepth
|| weight == 0)
// Map the roughness to the correct mip map level of the color pyramid
lighting.specularTransmitted = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, refractedBackPointNDC * _GaussianPyramidColorMipSize.xy, preLightData.transparentSSMipLevel).rgb;
UpdateLightingHierarchyWeights(hierarchyWeight, weight); // Shouldn't be needed, but safer in case we decide to change hierarchy priority
// Beer-Lamber law for absorption
lighting.specularTransmitted *= preLightData.transparentTransmittance;
float3 preLD = SAMPLE_TEXTURE2D_LOD(
_ColorPyramidTexture,
s_trilinear_clamp_sampler,
hit.positionNDC * _ColorPyramidScale.xy,
preLightData.transparentSSMipLevel
).rgb;
float weight = 1.0;
UpdateLightingHierarchyWeights(hierarchyWeight, weight); // Shouldn't be needed, but safer in case we decide to change hierarchy priority
// We use specularFGD as an approximation of the fresnel effect (that also handle smoothness), so take the remaining for transmission
lighting.specularTransmitted *= (1.0 - preLightData.specularFGD) * weight;
// 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;

#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_LUX_METER)
switch(_DebugLightingMode)
diffuseLighting = lighting.direct.diffuse + bakeLightingData.bakeDiffuseLighting;
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION_FROM_SSAO)
{
diffuseLighting = indirectAmbientOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION_FROM_SSAO)
{
diffuseLighting = specularOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
case DEBUGLIGHTINGMODE_LUX_METER:
diffuseLighting = lighting.direct.diffuse + bakeLightingData.bakeDiffuseLighting;
break;
case DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_OCCLUSION_FROM_SSAO:
diffuseLighting = indirectAmbientOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
break;
case DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_OCCLUSION_FROM_SSAO:
diffuseLighting = specularOcclusion;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
break;
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_GTAO_FROM_SSAO)
{
diffuseLighting = GTAOMultiBounce(indirectAmbientOcclusion, bsdfData.diffuseColor);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
else if (_DebugLightingMode == DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_GTAO_FROM_SSAO)
{
diffuseLighting = GTAOMultiBounce(specularOcclusion, bsdfData.fresnel0);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
case DEBUGLIGHTINGMODE_INDIRECT_DIFFUSE_GTAO_FROM_SSAO:
diffuseLighting = GTAOMultiBounce(indirectAmbientOcclusion, bsdfData.diffuseColor);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
break;
case DEBUGLIGHTINGMODE_INDIRECT_SPECULAR_GTAO_FROM_SSAO:
diffuseLighting = GTAOMultiBounce(specularOcclusion, bsdfData.fresnel0);
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
break;
else if (_DebugMipMapMode != DEBUGMIPMAPMODE_NONE)
{
diffuseLighting = bsdfData.diffuseColor;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
case DEBUGMIPMAPMODE_NONE:
diffuseLighting = bsdfData.diffuseColor;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
break;
case DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION:
if (_DebugLightingSubMode != DEBUGSCREENSPACETRACING_COLOR)
{
diffuseLighting = lighting.indirect.specularTransmitted;
specularLighting = float3(0.0, 0.0, 0.0); // Disable specular lighting
}
break;
}
#endif
}

35
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ScreenSpaceRefractionVolumeEditor.cs


using System.Collections;
using UnityEngine;
using UnityEditor;
using UnityEditor.Experimental.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[CanEditMultipleObjects]
[VolumeComponentEditor(typeof(ScreenSpaceRefractionVolume))]
public class ScreenSpaceRefractionVolumeEditor : VolumeComponentEditor
{
SerializedDataParameter m_RayMinLevel;
SerializedDataParameter m_RayMaxLevel;
SerializedDataParameter m_RayMaxIterations;
SerializedDataParameter m_RayDepthSuccessBias;
public override void OnEnable()
{
var o = new PropertyFetcher<ScreenSpaceRefractionVolume>(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));
}
public override void OnInspectorGUI()
{
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"));
}
}
}

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


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

22
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceRefractionVolume.cs


using System;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[Serializable]
public class ScreenSpaceRefractionVolume : VolumeComponent
{
public IntParameter rayMinLevel = new IntParameter(2);
public IntParameter rayMaxLevel = new IntParameter(6);
public IntParameter rayMaxIterations = new IntParameter(1024);
public FloatParameter rayDepthSuccessBias = new FloatParameter(0.1f);
public void PushShaderParameters(CommandBuffer cmd)
{
cmd.SetGlobalInt(HDShaderIDs._SSRefractionRayMinLevel, rayMinLevel.value);
cmd.SetGlobalInt(HDShaderIDs._SSRefractionRayMaxLevel, rayMaxLevel.value);
cmd.SetGlobalInt(HDShaderIDs._SSRefractionRayMaxIterations, rayMaxIterations.value);
cmd.SetGlobalFloat(HDShaderIDs._SSRefractionRayDepthSuccessBias, rayDepthSuccessBias.value);
}
}
}

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


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

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl.meta


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