浏览代码

Refactoring and adding linear raymarch for Hiz and proxy

/main
Frédéric Vauchelles 7 年前
当前提交
7df2f723
共有 8 个文件被更改,包括 414 次插入166 次删除
  1. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs
  2. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/LightingDebug.cs
  3. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/LightingDebug.cs.hlsl
  4. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/HDScreenSpaceReflectionEditor.cs
  5. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Reflection/ScreenSpaceLightingEditor.cs
  6. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceReflection.cs
  7. 527
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl
  8. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl

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


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

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 = "Mip Level", getter = () => screenSpaceTracingDebugData.iterationMipLevel },
new DebugUI.Value { displayName = "Cell Id", getter = () => screenSpaceTracingDebugData.iterationCellId },
new DebugUI.Value { displayName = "Cell Size", getter = () => screenSpaceTracingDebugData.iterationCellSize },
}

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


RayDirWS,
HitDepth,
HitSuccess,
TracingModel,
HiZPositionNDC,
HiZRayDirNDC,
HiZIterationCount,

11
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)
#endif

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


EditorGUILayout.Separator();
OnHiZInspectorGUI();
break;
case Lit.ProjectionModel.Proxy:
EditorGUILayout.Separator();
PropertyField(m_RayLevel, CoreEditorUtils.GetContent("Linear Ray Level"));
PropertyField(m_RayMaxLinearIterationsLevel, CoreEditorUtils.GetContent("Linear Iterations"));
PropertyField(m_RayDepthSuccessBias, CoreEditorUtils.GetContent("Linear Ray Depth Success Bias"));
break;
}
}

14
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;
SerializedDataParameter m_RayDepthSuccessBias;
SerializedDataParameter m_ScreenWeightDistance;
protected SerializedDataParameter m_RayLevel;
protected SerializedDataParameter m_RayMaxLinearIterationsLevel;
protected SerializedDataParameter m_RayMinLevel;
protected SerializedDataParameter m_RayMaxLevel;
protected SerializedDataParameter m_RayMaxIterations;
protected SerializedDataParameter m_RayDepthSuccessBias;
protected SerializedDataParameter m_ScreenWeightDistance;
public override void OnEnable()
{

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


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[Serializable]
public sealed class LitProjectionModelParameter : VolumeParameter<Lit.ProjectionModel>
public sealed class LitProjectionModelParameter : VolumeParameter<ScreenSpaceReflection.AvailableProjectionModel>
public LitProjectionModelParameter() : base(Lit.ProjectionModel.Proxy, false) { }
public LitProjectionModelParameter() : base(ScreenSpaceReflection.AvailableProjectionModel.Proxy, false) { }
// 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
{

527
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(...)
// #################################################
// 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)
float3 positionWS; // Position of the hit point (WS)
float linearDepth; // Linear depth of the hit point
#ifdef DEBUG_DISPLAY
float3 debugOutput;

{
float3 rayOriginWS; // Ray origin (WS)
float3 rayDirWS; // Ray direction (WS)
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
)
{
float3 positionWS = rayOriginWS;

float2 positionNDC = ComputeNormalizedDeviceCoordinates(positionWS, GetWorldToHClipMatrix());
float2 rayEndNDC = ComputeNormalizedDeviceCoordinates(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
positionSS = rayStartSS;
raySS = rayEndSS - rayStartSS;

// Calculate intersection between a ray and a cell
float3 IntersectCellPlanes(
float3 positionSS,
float3 raySS,
float2 invRaySS,
int2 cellId,
uint2 cellSize,
int2 cellPlanes,
float2 crossOffset
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
)
{
const float SQRT_2 = sqrt(2);

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

case DEBUGSCREENSPACETRACING_HIT_SUCCESS:
hit.debugOutput = GetIndexColor(hitSuccessful ? 1 : 2);
break;
case DEBUGSCREENSPACETRACING_TRACING_MODEL:
hit.debugOutput = GetIndexColor(tracingModel);
break;
}
}

}
}
#endif
#endif
// Algorithm: Proxy raycast
// Algorithms
#ifdef SSRTID
#define SSRT_SETTING(name, SSRTID) _SS ## SSRTID ## name
#define SSRT_FUNC(name, SSRTID) name ## SSRTID
CBUFFER_START(SSRT_FUNC(UnityScreenSpaceRaymarching, SSRTID))
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(RayDepthSuccessBias, SSRTID);
#ifdef DEBUG_DISPLAY
int SSRT_SETTING(DebuggedAlgorithm, SSRTID);
#endif
CBUFFER_END
bool SSRT_FUNC(ScreenSpaceProxyRaycast, SSRTID)(
ScreenSpaceProxyRaycastInput input,
out ScreenSpaceRayHit hit
)
{
ZERO_INITIALIZE(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:
case ENVSHAPETYPE_SKY:
{
projectionDistance = IntersectSphereProxy(input.proxyData, rayDirPS, rayOriginPS);
break;
}
case ENVSHAPETYPE_BOX:
projectionDistance = IntersectBoxProxy(input.proxyData, rayDirPS, rayOriginPS);
break;
}
float3 hitPositionWS = input.rayOriginWS + input.rayDirWS * projectionDistance;
float4 hitPositionCS = ComputeClipSpacePosition(hitPositionWS, GetWorldToHClipMatrix());
float4 rayOriginCS = ComputeClipSpacePosition(input.rayOriginWS, GetWorldToHClipMatrix());
float2 hitPositionNDC = ComputeNormalizedDeviceCoordinates(hitPositionWS, GetWorldToHClipMatrix());
uint2 hitPositionSS = uint2(hitPositionNDC *_ScreenSize.xy);
float hitLinearDepth = hitPositionCS.w;
hit.positionNDC = hitPositionNDC;
hit.positionSS = hitPositionSS;
hit.linearDepth = hitLinearDepth;
bool hitSuccessful = hitLinearDepth > 0; // Negative means that the hit is behind the camera
#ifdef DEBUG_DISPLAY
DebugComputeCommonOutput(input.rayDirWS, hitSuccessful, hit);
if (input.debug
&& _DebugScreenSpaceTracingData[0].tracingModel == -1
&& SSRT_SETTING(DebuggedAlgorithm, SSRTID) == PROJECTIONMODEL_PROXY
)
{
ScreenSpaceTracingDebug debug;
ZERO_INITIALIZE(ScreenSpaceTracingDebug, debug);
float2 rayOriginNDC = ComputeNormalizedDeviceCoordinates(input.rayOriginWS, GetWorldToHClipMatrix());
uint2 rayOriginSS = uint2(rayOriginNDC * _ScreenSize.xy);
debug.tracingModel = PROJECTIONMODEL_PROXY;
debug.loopStartPositionSSX = rayOriginSS.x;
debug.loopStartPositionSSY = rayOriginSS.y;
debug.loopStartLinearDepth = rayOriginCS.w;
debug.endHitSuccess = hitSuccessful;
debug.endLinearDepth = hitLinearDepth;
debug.endPositionSSX = hitPositionSS.x;
debug.endPositionSSY = hitPositionSS.y;
debug.proxyShapeType = input.proxyData.influenceShapeType;
debug.projectionDistance = projectionDistance;
_DebugScreenSpaceTracingData[0] = debug;
}
#endif
return hitSuccessful;
}
//
bool SSRT_FUNC(_ScreenSpaceLinearRaymarch, SSRTID)(
// -------------------------------------------------
bool ScreenSpaceLinearRaymarch(
uint inputMaxIterations,
float3 startPositionSS,
float3 raySS,
uint2 bufferSize,
// Settings
int settingRayLevel, // Mip level to use to ray march depth buffer
uint settingsRayMaxIterations, // Maximum number of iterations (= max number of depth samples)
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
)
{

int mipLevel = min(max(SSRT_SETTING(RayLevel, SSRTID), 0), int(_DepthPyramidScale.z));
uint maxIterations = min(inputMaxIterations, uint(SSRT_SETTING(RayMaxIterations, SSRTID)));
int mipLevel = min(max(settingRayLevel, 0), int(_DepthPyramidScale.z));
uint maxIterations = settingsRayMaxIterations;
raySS.xy *= int2(1, 1) << mipLevel;
raySS *= 1 << mipLevel;
// Offset by half a texel
positionSS += raySS * 0.5;

uint debugIteration = iteration;
#endif
float invHiZDepth = 0;
float invLinearDepth = 0;
for (iteration = 0u; iteration < maxIterations; ++iteration)
{

invHiZDepth = LoadInvDepth(positionSS.xy, mipLevel);
invLinearDepth = LoadInvDepth(positionSS.xy, mipLevel);
#ifdef DEBUG_DISPLAY
// Fetch post iteration debug values

debugIterationLinearDepthBuffer = 1 / invHiZDepth;
debugIterationLinearDepthBuffer = 1 / invLinearDepth;
if (!IsPositionAboveDepth(positionSS.z, invHiZDepth))
if (!IsPositionAboveDepth(positionSS.z, invLinearDepth))
break;
// Check if we are out of the buffer

hit.linearDepth = 1 / positionSS.z;
hit.positionNDC = float2(positionSS.xy) / float2(bufferSize);
hit.positionSS = uint2(positionSS.xy);
float worldInterpolationFactor = (hit.linearDepth - rcp(startPositionSS.z)) / (rayEndDepth - rcp(startPositionSS.z));
hit.positionWS = input.rayOriginWS + input.rayDirWS * worldInterpolationFactor;
DebugComputeCommonOutput(input.rayDirWS, hitSuccessful, hit);
DebugComputeCommonOutput(input.rayDirWS, hitSuccessful, PROJECTIONMODEL_LINEAR, hit);
&& SSRT_SETTING(DebuggedAlgorithm, SSRTID) == PROJECTIONMODEL_LINEAR
&& settingsDebuggedAlgorithm == PROJECTIONMODEL_LINEAR
)
{
// Build debug structure

return hitSuccessful;
}
bool SSRT_FUNC(ScreenSpaceLinearRaymarch, SSRTID)(
ScreenSpaceRaymarchInput input,
// -------------------------------------------------
// 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(
ScreenSpaceProxyRaycastInput input,
// Settings
int settingsDebuggedAlgorithm, // currently debugged algorithm (see PROJECTIONMODEL defines)
// Out
out ScreenSpaceRayHit hit
)
{
// Initialize loop
ZERO_INITIALIZE(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:
case ENVSHAPETYPE_SKY:
{
projectionDistance = IntersectSphereProxy(input.proxyData, rayDirPS, rayOriginPS);
break;
}
case ENVSHAPETYPE_BOX:
projectionDistance = IntersectBoxProxy(input.proxyData, rayDirPS, rayOriginPS);
break;
}
float3 hitPositionWS = input.rayOriginWS + input.rayDirWS * projectionDistance;
float4 hitPositionCS = ComputeClipSpacePosition(hitPositionWS, GetWorldToHClipMatrix());
float4 rayOriginCS = ComputeClipSpacePosition(input.rayOriginWS, GetWorldToHClipMatrix());
float2 hitPositionNDC = ComputeNormalizedDeviceCoordinates(hitPositionWS, GetWorldToHClipMatrix());
uint2 hitPositionSS = uint2(hitPositionNDC *_ScreenSize.xy);
float hitLinearDepth = hitPositionCS.w;
hit.positionNDC = hitPositionNDC;
hit.positionSS = hitPositionSS;
hit.linearDepth = hitLinearDepth;
hit.positionWS = hitPositionWS;
bool hitSuccessful = hitLinearDepth > 0; // Negative means that the hit is behind the camera
#ifdef DEBUG_DISPLAY
DebugComputeCommonOutput(input.rayDirWS, hitSuccessful, PROJECTIONMODEL_PROXY, hit);
if (input.debug
&& _DebugScreenSpaceTracingData[0].tracingModel == -1
&& settingsDebuggedAlgorithm == PROJECTIONMODEL_PROXY
)
{
ScreenSpaceTracingDebug debug;
ZERO_INITIALIZE(ScreenSpaceTracingDebug, debug);
float2 rayOriginNDC = ComputeNormalizedDeviceCoordinates(input.rayOriginWS, GetWorldToHClipMatrix());
uint2 rayOriginSS = uint2(rayOriginNDC * _ScreenSize.xy);
debug.tracingModel = PROJECTIONMODEL_PROXY;
debug.loopStartPositionSSX = rayOriginSS.x;
debug.loopStartPositionSSY = rayOriginSS.y;
debug.loopStartLinearDepth = rayOriginCS.w;
debug.endHitSuccess = hitSuccessful;
debug.endLinearDepth = hitLinearDepth;
debug.endPositionSSX = hitPositionSS.x;
debug.endPositionSSY = hitPositionSS.y;
debug.proxyShapeType = input.proxyData.influenceShapeType;
debug.projectionDistance = projectionDistance;
_DebugScreenSpaceTracingData[0] = debug;
}
#endif
return hitSuccessful;
}
// -------------------------------------------------
// 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)
// Settings (common)
int settingsDebuggedAlgorithm, // currently debugged algorithm (see PROJECTIONMODEL defines)
// Out
// Perform linear raymarch
ScreenSpaceRaymarchInput inputLinear;
inputLinear.rayOriginWS = input.rayOriginWS;
inputLinear.rayDirWS = input.rayDirWS;
#ifdef DEBUG_DISPLAY
inputLinear.debug = input.debug;
#endif
// Compute properties for linear raymarch
float rayEndDepth;
raySS
raySS,
rayEndDepth
return SSRT_FUNC(_ScreenSpaceLinearRaymarch, SSRTID)(
input,
input.maxIterations,
bool hitSuccessful = ScreenSpaceLinearRaymarch(
inputLinear,
// Settings
settingRayLevel,
settingsRayMaxIterations,
settingsDebuggedAlgorithm,
// Precomputed properties
rayEndDepth,
// Out
if (!hitSuccessful)
{
hitSuccessful = ScreenSpaceProxyRaycast(
input,
// Settings
settingsDebuggedAlgorithm,
// Out
hit
);
}
return hitSuccessful;
bool SSRT_FUNC(ScreenSpaceHiZRaymarch, SSRTID)(
//
// 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.
//
// NB: Maximum of depth samples = settingsRayMaxIterations + settingsRayMaxLinearIterations
// -------------------------------------------------
bool ScreenSpaceHiZRaymarch(
// Settings
uint settingsRayLevel, // Mip level to use for linear ray marching in depth buffer
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)
uint settingsRayMaxLinearIterations, // Maximum number of iteration for the linear raymarching (= number of depth sample for linear)
float settingsRayDepthSuccessBias, // Bias to use when trying to detect whenever we raymarch behind a surface
int settingsDebuggedAlgorithm, // currently debugged algorithm (see PROJECTIONMODEL defines)
// out
out ScreenSpaceRayHit hit
)
{

ZERO_INITIALIZE(ScreenSpaceRayHit, hit);
bool hitSuccessful = true;
uint iteration = 0u;
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, uint(SSRT_SETTING(RayMaxIterations, SSRTID)));
uint maxIterations = settingsRayMaxIterations;
float rayEndDepth;
raySS
raySS,
rayEndDepth
if (SSRT_FUNC(_ScreenSpaceLinearRaymarch, SSRTID)(
// We perform first a linear raymarching
// It is more performant for short distance than HiZ raymarching
if (ScreenSpaceLinearRaymarch(
SSRT_SETTING(RayMaxLinearIterations, SSRTID),
// settings
settingsRayLevel,
settingsRayMaxLinearIterations,
#ifdef DEBUG_DISPLAY
settingsDebuggedAlgorithm,
#else
PROJECTIONMODEL_NONE,
#endif
// precomputed
rayEndDepth,
// out
hit
))
return true;

hit.linearDepth = 1 / positionSS.z;
hit.positionNDC = float2(positionSS.xy) / float2(bufferSize);
hit.positionSS = uint2(positionSS.xy);
float worldInterpolationFactor = (hit.linearDepth - rcp(startPositionSS.z)) / (rayEndDepth - rcp(startPositionSS.z));
hit.positionWS = input.rayOriginWS + input.rayDirWS * worldInterpolationFactor;
if (hit.linearDepth > (1 / invHiZDepth) + SSRT_SETTING(RayDepthSuccessBias, SSRTID))
if (hit.linearDepth > (1 / invHiZDepth) + settingsRayDepthSuccessBias)
DebugComputeCommonOutput(input.rayDirWS, hitSuccessful, hit);
DebugComputeCommonOutput(input.rayDirWS, hitSuccessful, PROJECTIONMODEL_HI_Z, hit);
SSRT_SETTING(RayMaxIterations, SSRTID),
settingsRayMaxIterations,
debugLoopMipMaxUsedLevel,
maxMipLevel,
intersectionKind,

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

return hitSuccessful;
}
#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(RayMaxLinearIterations, SSRTID);
int SSRT_SETTING(RayMaxIterations, SSRTID);
float SSRT_SETTING(RayDepthSuccessBias, 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
)
{
uint2 bufferSize = uint2(_DepthPyramidSize.xy);
float3 startPositionSS;
float3 raySS;
float rayEndDepth;
CalculateRaySS(
input.rayOriginWS,
input.rayDirWS,
bufferSize,
startPositionSS,
raySS,
rayEndDepth
);
return ScreenSpaceLinearRaymarch(
input,
// settings
SSRT_SETTING(RayLevel, SSRTID),
SSRT_SETTING(RayMaxIterations, SSRTID),
#ifdef DEBUG_DISPLAY
SSRT_SETTING(DebuggedAlgorithm, SSRTID),
#else
PROJECTIONMODEL_NONE,
#endif
// precomputed properties
startPositionSS,
raySS,
rayEndDepth,
bufferSize,
// out
hit
);
}
// -------------------------------------------------
// Algorithm: Scene Proxy Raycasting
// -------------------------------------------------
bool MERGE_NAME(ScreenSpaceProxyRaycast, SSRTID)(
ScreenSpaceProxyRaycastInput input,
out ScreenSpaceRayHit hit
)
{
return ScreenSpaceLinearProxyRaycast(
input,
// Settings (linear)
SSRT_SETTING(RayLevel, SSRTID),
SSRT_SETTING(RayMaxIterations, SSRTID),
// Settings (common)
#if DEBUG_DISPLAY
SSRT_SETTING(DebuggedAlgorithm, SSRTID),
#else
uint(PROJECTIONMODEL_NONE),
#endif
// Out
hit
);
}
// -------------------------------------------------
// Algorithm: HiZ raymarching
// -------------------------------------------------
bool MERGE_NAME(ScreenSpaceHiZRaymarch, SSRTID)(
ScreenSpaceRaymarchInput input,
out ScreenSpaceRayHit hit
)
{
return ScreenSpaceHiZRaymarch(
input,
// Settings
SSRT_SETTING(RayLevel, SSRTID),
SSRT_SETTING(RayMinLevel, SSRTID),
SSRT_SETTING(RayMaxLevel, SSRTID),
SSRT_SETTING(RayMaxIterations, SSRTID),
SSRT_SETTING(RayMaxLinearIterations, SSRTID),
SSRT_SETTING(RayDepthSuccessBias, SSRTID),
#ifdef DEBUG_DISPLAY
SSRT_SETTING(DebuggedAlgorithm, SSRTID),
#else
PROJECTIONMODEL_NONE,
#endif
// out
hit
);
}
// -------------------------------------------------
// Cleaning
// -------------------------------------------------
#undef SSRT_FUNC
#endif

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


// -------------------------------
if (projectionModel == PROJECTIONMODEL_PROXY)
{
// Perform a linear raymarch to detect close range collisions
ssRayInput.rayOriginWS = rayOriginWS;
ssRayInput.rayOriginWS = hit.positionWS;
ssRayInput.rayDirWS = rayDirWS;
#if DEBUG_DISPLAY
ssRayInput.debug = debug;

#if DEBUG_DISPLAY
ssRayInput.debug = debug;
#endif
ssRayInput.maxIterations = uint(-1);
#if HAS_REFRACTION
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)

正在加载...
取消
保存