浏览代码

Removed linear raymarch before HiZ, replaced with call intersection

/main
Frédéric Vauchelles 6 年前
当前提交
c0482898
共有 6 个文件被更改,包括 39 次插入62 次删除
  1. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ScreenSpaceLightingEditor.cs
  2. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs
  3. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceLighting.cs
  4. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceReflection.cs
  5. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceRefraction.cs
  6. 84
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl

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


public class ScreenSpaceLightingEditor : VolumeComponentEditor
{
protected SerializedDataParameter m_RayLevel;
protected SerializedDataParameter m_RayMaxLinearIterationsLevel;
protected SerializedDataParameter m_RayMinLevel;
protected SerializedDataParameter m_RayMaxLevel;
protected 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"));

m_RayLevel.value.intValue = Mathf.Max(0, m_RayLevel.value.intValue);
m_RayMaxLinearIterationsLevel.value.intValue = Mathf.Max(0, m_RayMaxLinearIterationsLevel.value.intValue);
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);

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs


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 _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 _SSReflectionRayMaxScreenDistance = Shader.PropertyToID("_SSReflectionRayMaxScreenDistance");
public static readonly int _SSReflectionRayBlendScreenDistance = Shader.PropertyToID("_SSReflectionRayBlendScreenDistance");
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");

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


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

int m_RayBlendScreenDistanceID;
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,

{
FetchIDs(
out m_RayLevelID,
out m_RayMaxLinearIterationsID,
out m_RayMinLevelID,
out m_RayMaxLevelID,
out m_RayMaxIterationsID,

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


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;

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


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

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

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


return positionSS + raySS * t;
}
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))
)
{
// Planes to check
int2 planes = (cellId + cellPlanes) * cellSize;
// Hit distance to each planes
float2 distanceToCellAxes = float2(planes - positionSS.xy) * invRaySS; // (distance to x axis, distance to y axis)
return distanceToCellAxes;
}
// Calculate intersection between a ray and a cell
float3 IntersectCellPlanes(
float3 positionSS, // Ray Origin (Screen Space, 1/LinearDepth)

float2 crossOffset // Offset to use to ensure cell boundary crossing
)
{
// Planes to check
int2 planes = (cellId + cellPlanes) * cellSize;
// Hit distance to each planes
float2 distanceToCellAxes = float2(planes - positionSS.xy) * invRaySS; // (distance to x axis, distance to y axis)
float2 distanceToCellAxes = CalculateDistanceToCellPlanes(
positionSS,
invRaySS,
cellId,
cellSize,
cellPlanes
);
float t = min(distanceToCellAxes.x, distanceToCellAxes.y)
// Offset to ensure cell crossing
// This assume that length(raySS.xy) == 1;

// 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.
//
// NB: Maximum of depth samples = settingsRayMaxIterations + settingsRayMaxLinearIterations
uint settingsRayLevel, // Mip level to use for linear ray marching in depth buffer
uint settingsRayMaxLinearIterations, // Maximum number of iteration for the linear raymarching (= number of depth sample for linear)
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

rayEndDepth
);
// We perform first a linear raymarching
// It is more performant for short distance than HiZ raymarching
if (ScreenSpaceLinearRaymarch(
input,
// settings
settingsRayLevel,
settingsRayMaxLinearIterations,
settingsDepthBufferThickness,
settingsRayMaxScreenDistance,
settingsRayBlendScreenDistance,
settingsDebuggedAlgorithm,
// precomputed
startPositionSS,
raySS,
rayEndDepth,
bufferSize,
// out
hit,
hitWeight,
iteration
))
return true;
startPositionSS = float3(hit.positionSS, 1 / hit.linearDepth);
#ifdef DEBUG_DISPLAY
// Initialize debug variables
int debugLoopMipMaxUsedLevel = minMipLevel;

float minLinearDepth = 0;
float minLinearDepthWithThickness = 0;
positionSS = IntersectCellPlanes(
positionSS,
raySS,
invRaySS,
int2(positionSS.xy) / cellSize,
cellSize,
cellPlanes,
crossOffset
);
// 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;
}
while (currentLevel >= minMipLevel)
{

int SSRT_SETTING(RayLevel, SSRTID);
int SSRT_SETTING(RayMinLevel, SSRTID);
int SSRT_SETTING(RayMaxLevel, SSRTID);
int SSRT_SETTING(RayMaxLinearIterations, SSRTID);
int SSRT_SETTING(RayMaxIterations, SSRTID);
float SSRT_SETTING(DepthBufferThickness, SSRTID);
float SSRT_SETTING(RayMaxScreenDistance, SSRTID);

return ScreenSpaceHiZRaymarch(
input,
// Settings
SSRT_SETTING(RayLevel, SSRTID),
SSRT_SETTING(RayMaxLinearIterations, SSRTID),
max(0.01, SSRT_SETTING(DepthBufferThickness, SSRTID)),
SSRT_SETTING(RayMaxScreenDistance, SSRTID),
SSRT_SETTING(RayBlendScreenDistance, SSRTID),

正在加载...
取消
保存