浏览代码

Added linear raymarching in HiZ

Fixed HiZ reflection
/main
Frédéric Vauchelles 7 年前
当前提交
b222ccef
共有 13 个文件被更改,包括 251 次插入14 次删除
  1. 50
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs
  2. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs.hlsl
  3. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugFullScreen.shader
  4. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ScreenSpaceLightingEditor.cs
  5. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs
  6. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs.hlsl
  7. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceLighting.cs
  8. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceReflection.cs
  9. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceRefraction.cs
  10. 171
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl
  11. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs
  12. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.cs.hlsl
  13. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl

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


public static int[] debugScreenSpaceTracingProxyValues = null;
public static GUIContent[] debugScreenSpaceTracingHiZStrings = null;
public static int[] debugScreenSpaceTracingHiZValues = null;
public static GUIContent[] debuggedAlgorithmStrings = null;
public static int[] debuggedAlgorithmValues = null;
Lit.ProjectionModel m_LastProjectionModel = Lit.ProjectionModel.None;
ScreenSpaceTracingDebug m_ScreenSpaceTracingDebugData;

debugScreenSpaceTracingHiZValues = debugScreenSpaceTracingHiZValueList.ToArray();
debugScreenSpaceTracingProxyStrings = debugScreenSpaceTracingProxyStringsList.ToArray();
debugScreenSpaceTracingProxyValues = debugScreenSpaceTracingProxyValueList.ToArray();
debuggedAlgorithmStrings = Enum.GetNames(typeof(Lit.ProjectionModel))
.Select(t => new GUIContent(t))
.ToArray();
debuggedAlgorithmValues = (int[])Enum.GetValues(typeof(Lit.ProjectionModel));
}
public int GetDebugMaterialIndex()

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 = 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.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);

case Lit.ProjectionModel.HiZ:
{
debugSettingsContainer.children.Insert(1, new DebugUI.Value { displayName = string.Empty, getter = () => "Press PageUp/PageDown to Increase/Decrease the HiZ step." });
debugSettingsContainer.children.Add(
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 }
);
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.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", getter = () => screenSpaceTracingDebugData.iterationLinearDepthBuffer },
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 },
}
}
);
break;
}
case Lit.ProjectionModel.Linear:
{
debugSettingsContainer.children.Add(
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 },

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


uint iterationCellSizeH;
int proxyShapeType;
float projectionDistance;
bool endHitSuccess;
int endHitSuccess;
float endLinearDepth;
uint endPositionSSX;
uint endPositionSSY;

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

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


float cellSDF = 0;
float debugLinearDepth = 0;
if (debug.tracingModel == PROJECTIONMODEL_HI_Z)
if (debug.tracingModel == PROJECTIONMODEL_HI_Z
|| debug.tracingModel == PROJECTIONMODEL_LINEAR)
{
const uint2 iterationCellSize = uint2(debug.iterationCellSizeW, debug.iterationCellSizeH);
const float hasData = iterationCellSize.x != 0 || iterationCellSize.y != 0;

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


{
public class ScreenSpaceLightingEditor : VolumeComponentEditor
{
SerializedDataParameter m_RayLevel;
SerializedDataParameter m_RayMaxLinearIterationsLevel;
SerializedDataParameter m_RayMinLevel;
SerializedDataParameter m_RayMaxLevel;
SerializedDataParameter m_RayMaxIterations;

{
var o = new PropertyFetcher<ScreenSpaceLighting>(serializedObject);
m_RayLevel = Unpack(o.Find(x => x.rayLevel));
m_RayMaxLinearIterationsLevel = Unpack(o.Find(x => x.rayMaxLinearIterationsLevel));
m_RayMinLevel = Unpack(o.Find(x => x.rayMinLevel));
m_RayMaxLevel = Unpack(o.Find(x => x.rayMaxLevel));
m_RayMaxIterations = Unpack(o.Find(x => x.rayMaxIterations));

protected virtual void OnHiZInspectorGUI()
{
EditorGUILayout.LabelField(CoreEditorUtils.GetContent("HiZ Settings"));
PropertyField(m_RayLevel, CoreEditorUtils.GetContent("Linear Ray Level"));
PropertyField(m_RayMaxLinearIterationsLevel, CoreEditorUtils.GetContent("Linear Iterations"));
PropertyField(m_RayMinLevel, CoreEditorUtils.GetContent("Ray Min Level"));
PropertyField(m_RayMaxLevel, CoreEditorUtils.GetContent("Ray Max Level"));
PropertyField(m_RayMaxIterations, CoreEditorUtils.GetContent("Ray Max Iterations"));

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs


Shader.PropertyToID("_SSSBufferTexture3"),
};
public static readonly int _SSRefractionRayLevel = Shader.PropertyToID("_SSRefractionRayLevel");
public static readonly int _SSRefractionRayMaxLinearIterations = Shader.PropertyToID("_SSRefractionRayMaxLinearIterations");
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 _SSReflectionRayMaxLinearIterations = Shader.PropertyToID("_SSReflectionRayMaxLinearIterations");
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");

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs.hlsl


#define TILE_SIZE_CLUSTERED (32)
#define NUM_FEATURE_VARIANTS (27)
#define LIGHT_FEATURE_MASK_FLAGS (16773120)
#define LIGHT_FEATURE_MASK_FLAGS_SSREFLECTION (262144)
#define LIGHT_FEATURE_MASK_FLAGS_OPAQUE (16642048)
#define LIGHT_FEATURE_MASK_FLAGS_TRANSPARENT (16510976)
#define MATERIAL_FEATURE_MASK_FLAGS (4095)

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


[Serializable]
public abstract class ScreenSpaceLighting : VolumeComponent
{
int m_RayLevelID;
int m_RayMaxLinearIterationsID;
int m_RayMinLevelID;
int m_RayMaxLevelID;
int m_RayMaxIterationsID;

public IntParameter rayLevel = new IntParameter(2);
public IntParameter rayMaxLinearIterationsLevel = new IntParameter(2);
public IntParameter rayMinLevel = new IntParameter(2);
public IntParameter rayMaxLevel = new IntParameter(6);
public IntParameter rayMaxIterations = new IntParameter(32);

public virtual void PushShaderParameters(CommandBuffer cmd)
{
cmd.SetGlobalInt(m_RayLevelID, rayLevel.value);
cmd.SetGlobalInt(m_RayMaxLinearIterationsID, rayMaxLinearIterationsLevel.value);
cmd.SetGlobalInt(m_RayMinLevelID, rayMinLevel.value);
cmd.SetGlobalInt(m_RayMaxLevelID, rayMaxLevel.value);
cmd.SetGlobalInt(m_RayMaxIterationsID, rayMaxIterations.value);

protected abstract void FetchIDs(
out int rayLevelID,
out int rayMaxLinearIterationsLevelID,
out int rayMinLevelID,
out int rayMaxLevelID,
out int rayMaxIterationsID,

void Awake()
{
FetchIDs(
out m_RayLevelID,
out m_RayMaxLinearIterationsID,
out m_RayMinLevelID,
out m_RayMaxLevelID,
out m_RayMaxIterationsID,

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


public LitProjectionModelParameter deferredProjectionModel = new LitProjectionModelParameter();
protected override void FetchIDs(
out int rayLevelID,
out int rayMaxLinearIterationsLevelID,
out int rayMinLevelID,
out int rayMaxLevelID,
out int rayMaxIterationsID,

{
rayLevelID = HDShaderIDs._SSReflectionRayLevel;
rayMaxLinearIterationsLevelID = HDShaderIDs._SSReflectionRayMaxLinearIterations;
rayMinLevelID = HDShaderIDs._SSReflectionRayMinLevel;
rayMaxLevelID = HDShaderIDs._SSReflectionRayMaxLevel;
rayMaxIterationsID = HDShaderIDs._SSReflectionRayMaxIterations;

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


}
protected override void FetchIDs(
out int rayLevelID,
out int rayMaxLinearIerationsID,
out int rayMinLevelID,
out int rayMaxLevelID,
out int rayMaxIterationsID,

{
rayLevelID = HDShaderIDs._SSRefractionRayLevel;
rayMaxLinearIerationsID = HDShaderIDs._SSRefractionRayMaxLinearIterations;
rayMinLevelID = HDShaderIDs._SSRefractionRayMinLevel;
rayMaxLevelID = HDShaderIDs._SSRefractionRayMaxLevel;
rayMaxIterationsID = HDShaderIDs._SSRefractionRayMaxIterations;

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


#endif
};
struct ScreenSpaceHiZRaymarchInput
struct ScreenSpaceRaymarchInput
{
float3 rayOriginWS; // Ray origin (WS)
float3 rayDirWS; // Ray direction (WS)

// Check whether the depth of the ray is above the sampled depth
// Arguments are inversed linear depth
bool IsPositionAboveDepth(float rayDepth, float invLinearDepth)
bool IsPositionAboveDepth(float invRayDepth, float invLinearDepth)
return rayDepth > invLinearDepth;
return invRayDepth > invLinearDepth;
}
// Sample the Depth buffer at a specific mip and linear depth

#define SSRT_FUNC(name, SSRTID) name ## SSRTID
CBUFFER_START(SSRT_FUNC(UnityScreenSpaceRaymarching, SSRTID))
int SSRT_SETTING(RayLevel, SSRTID);
int SSRT_SETTING(RayMaxLinearIterations, SSRTID);
#ifdef DEBUG_DISPLAY
int SSRT_SETTING(DebuggedAlgorithm, SSRTID);
#endif
CBUFFER_END
bool SSRT_FUNC(ScreenSpaceProxyRaycast, SSRTID)(

#ifdef DEBUG_DISPLAY
DebugComputeCommonOutput(input.rayDirWS, hitSuccessful, hit);
if (input.debug && _DebugScreenSpaceTracingData[0].tracingModel == -1)
if (input.debug
&& _DebugScreenSpaceTracingData[0].tracingModel == -1
&& SSRT_SETTING(DebuggedAlgorithm, SSRTID) == PROJECTIONMODEL_PROXY
)
{
ScreenSpaceTracingDebug debug;
ZERO_INITIALIZE(ScreenSpaceTracingDebug, debug);

}
// -------------------------------------------------
// 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 SSRT_FUNC(_ScreenSpaceLinearRaymarch, SSRTID)(
ScreenSpaceRaymarchInput input,
uint inputMaxIterations,
float3 startPositionSS,
float3 raySS,
uint2 bufferSize,
out ScreenSpaceRayHit hit
)
{
ZERO_INITIALIZE(ScreenSpaceRayHit, hit);
bool hitSuccessful = true;
uint iteration = 0u;
int mipLevel = min(max(SSRT_SETTING(RayLevel, SSRTID), 0), int(_DepthPyramidScale.z));
uint maxIterations = min(inputMaxIterations, uint(SSRT_SETTING(RayMaxIterations, SSRTID)));
float3 positionSS = startPositionSS;
raySS /= max(abs(raySS.x), abs(raySS.y));
raySS.xy *= int2(1, 1) << mipLevel;
// Offset by half a texel
positionSS += raySS * 0.5;
#ifdef DEBUG_DISPLAY
float3 debugIterationPositionSS = positionSS;
float debugIterationLinearDepthBuffer = 0;
uint debugIteration = iteration;
#endif
float invHiZDepth = 0;
for (iteration = 0u; iteration < maxIterations; ++iteration)
{
positionSS += raySS;
// Sampled as 1/Z so it interpolate properly in screen space.
invHiZDepth = LoadInvDepth(positionSS.xy, mipLevel);
#ifdef DEBUG_DISPLAY
// Fetch post iteration debug values
if (input.debug && _DebugStep >= iteration)
{
debugIterationPositionSS = positionSS;
debugIterationLinearDepthBuffer = 1 / invHiZDepth;
debugIteration = iteration;
}
#endif
if (!IsPositionAboveDepth(positionSS.z, invHiZDepth))
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);
#ifdef DEBUG_DISPLAY
DebugComputeCommonOutput(input.rayDirWS, hitSuccessful, hit);
if (input.debug
&& _DebugScreenSpaceTracingData[0].tracingModel == -1
&& SSRT_SETTING(DebuggedAlgorithm, SSRTID) == PROJECTIONMODEL_LINEAR
)
{
// Build debug structure
ScreenSpaceTracingDebug debug;
ZERO_INITIALIZE(ScreenSpaceTracingDebug, debug);
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.iterationLinearDepthBuffer = debugIterationLinearDepthBuffer;
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;
_DebugScreenSpaceTracingData[0] = debug;
}
#endif
return hitSuccessful;
}
bool SSRT_FUNC(ScreenSpaceLinearRaymarch, SSRTID)(
ScreenSpaceRaymarchInput input,
out ScreenSpaceRayHit hit
)
{
uint2 bufferSize = uint2(_DepthPyramidSize.xy);
float3 startPositionSS;
float3 raySS;
CalculateRaySS(
input.rayOriginWS,
input.rayDirWS,
bufferSize,
startPositionSS,
raySS
);
return SSRT_FUNC(_ScreenSpaceLinearRaymarch, SSRTID)(
input,
input.maxIterations,
startPositionSS,
raySS,
bufferSize,
hit
);
}
// -------------------------------------------------
// Algorithm: HiZ raymarching
// -------------------------------------------------

ScreenSpaceHiZRaymarchInput input,
ScreenSpaceRaymarchInput input,
out ScreenSpaceRayHit hit
)
{

startPositionSS,
raySS
);
if (SSRT_FUNC(_ScreenSpaceLinearRaymarch, SSRTID)(
input,
SSRT_SETTING(RayMaxLinearIterations, SSRTID),
startPositionSS,
raySS,
bufferSize,
hit
))
return true;
startPositionSS = float3(hit.positionSS, 1 / hit.linearDepth);
#ifdef DEBUG_DISPLAY
// Initialize debug variables

hit
);
if (input.debug && _DebugScreenSpaceTracingData[0].tracingModel == -1)
if (input.debug
&& _DebugScreenSpaceTracingData[0].tracingModel == -1
&& SSRT_SETTING(DebuggedAlgorithm, SSRTID) == PROJECTIONMODEL_HI_Z
)
{
// Build debug structure
ScreenSpaceTracingDebug debug;

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


{
None = 0,
Proxy = 1,
HiZ = 2
HiZ = 2,
Linear = 3
};
[GenerateHLSL]

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


#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

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


// -------------------------------
else if (projectionModel == PROJECTIONMODEL_HI_Z)
{
ScreenSpaceHiZRaymarchInput ssRayInput;
ZERO_INITIALIZE(ScreenSpaceHiZRaymarchInput, ssRayInput);
ScreenSpaceRaymarchInput ssRayInput;
ZERO_INITIALIZE(ScreenSpaceRaymarchInput, ssRayInput);
ssRayInput.rayOriginWS = rayOriginWS;
ssRayInput.rayDirWS = rayDirWS;

正在加载...
取消
保存