浏览代码

Renamed properly variables

/feature-ScreenSpaceProjection
Frédéric Vauchelles 6 年前
当前提交
26ba0cae
共有 4 个文件被更改,包括 193 次插入138 次删除
  1. 227
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/ScreenSpaceRaymarching.hlsl
  2. 75
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs
  3. 27
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs.hlsl
  4. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugFullScreen.shader

227
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/ScreenSpaceRaymarching.hlsl


struct ScreenSpaceRayHit
{
float distance; // Distance raymarched
float distanceSS; // Distance raymarched (SS)
float linearDepth; // Linear depth of the hit point
uint2 positionSS; // Position of the hit point (SS)
float2 positionNDC; // Position of the hit point (NDC)

// Utilities
// -------------------------------------------------
// Calculate the ray origin and direction in TXS
// out positionTXS : (x, y, 1/depth)
// out rayTXS : (x, y, 1/depth)
void CalculateRayTXS(
// Calculate the ray origin and direction in SS
// out positionSS : (x, y, 1/depth)
// out raySS : (x, y, 1/depth)
void CalculateRaySS(
out float3 positionTXS,
out float3 rayTXS)
out float3 positionSS,
out float3 raySS)
{
float3 positionVS = rayOriginVS;
float3 rayEndVS = rayOriginVS + rayDirVS * 10;

float2 positionNDC = ComputeNormalizedDeviceCoordinates(positionVS, projectionMatrix);
float2 rayEndNDC = ComputeNormalizedDeviceCoordinates(rayEndVS, projectionMatrix);
float3 rayStartTXS = float3(
float3 rayStartSS = float3(
float3 rayEndTXS = float3(
float3 rayEndSS = float3(
positionTXS = rayStartTXS;
rayTXS = rayEndTXS - rayStartTXS;
positionSS = rayStartSS;
raySS = rayEndSS - rayStartSS;
}
// Check whether the depth of the ray is above the sampled depth

}
// Sample the Depth buffer at a specific mip and linear depth
float LoadDepth(float2 positionTXS, int level)
float LoadDepth(float2 positionSS, int level)
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, int2(positionTXS.xy) >> level, level).r;
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, int2(positionSS.xy) >> level, level).r;
float LoadInvDepth(float2 positionTXS, int level)
float LoadInvDepth(float2 positionSS, int level)
float linearDepth = LoadDepth(positionTXS, level);
float linearDepth = LoadDepth(positionSS, level);
float invLinearDepth = 1 / linearDepth;
return invLinearDepth;
}

}
// Calculate intersection between the ray and the depth plane
// positionTXS.z is 1/depth
// rayTXS.z is 1/depth
float3 IntersectDepthPlane(float3 positionTXS, float3 rayTXS, float invDepth, out float distance)
// positionSS.z is 1/depth
// raySS.z is 1/depth
float3 IntersectDepthPlane(float3 positionSS, float3 raySS, float invDepth, out float distanceSS)
// The depth of the intersection with the depth plane is: positionTXS.z + rayTXS.z * t = invDepth
distance = (invDepth - positionTXS.z) / rayTXS.z;
// The depth of the intersection with the depth plane is: positionSS.z + raySS.z * t = invDepth
distanceSS = (invDepth - positionSS.z) / raySS.z;
distance = distance >= 0.0f ? (distance + EPSILON) : 1E5;
distanceSS = distanceSS >= 0.0f ? (distanceSS + EPSILON) : 1E5;
return positionTXS + rayTXS * distance;
return positionSS + raySS * distanceSS;
float3 positionTXS,
float3 rayTXS,
float2 invRayTXS,
float3 positionSS,
float3 raySS,
float2 invRaySS,
out float distance)
out float distanceSS)
float2 distanceToCellAxes = float2(planes - positionTXS.xy) * invRayTXS; // (distance to x axis, distance to y axis)
distance = min(distanceToCellAxes.x, distanceToCellAxes.y);
float2 distanceToCellAxes = float2(planes - positionSS.xy) * invRaySS; // (distance to x axis, distance to y axis)
distanceSS = min(distanceToCellAxes.x, distanceToCellAxes.y);
float3 testHitPositionTXS = positionTXS + rayTXS * distance;
float3 testHitPositionSS = positionSS + raySS * distanceSS;
testHitPositionTXS.xy += (distanceToCellAxes.x < distanceToCellAxes.y)
testHitPositionSS.xy += (distanceToCellAxes.x < distanceToCellAxes.y)
return testHitPositionTXS;
return testHitPositionSS;
}
#ifdef DEBUG_DISPLAY

void FillScreenSpaceRaymarchingHitDebug(
uint2 bufferSize,
float3 rayDirVS,
float3 rayTXS,
float3 startPositionTXS,
float3 raySS,
float3 startPositionSS,
bool hitSuccessful,
int iteration,
int maxIterations,

switch (_DebugLightingSubMode)
{
case DEBUGSCREENSPACETRACING_POSITION_NDC:
debugOutput = float3(float2(startPositionTXS.xy) / bufferSize, 0);
debugOutput = float3(float2(startPositionSS.xy) / bufferSize, 0);
debugOutput = float3(rayTXS.xy * 0.5 + 0.5, frac(0.1 / rayTXS.z));
debugOutput = float3(raySS.xy * 0.5 + 0.5, frac(0.1 / raySS.z));
debugOutput = frac(hit.distance * 0.1);
debugOutput = frac(hit.distanceSS * 0.1);
break;
case DEBUGSCREENSPACETRACING_HIT_DEPTH:
debugOutput = frac(hit.linearDepth * 0.1);

}
void FillScreenSpaceRaymarchingPreLoopDebug(
float3 startPositionTXS,
float3 startPositionSS,
debug.startPositionSSX = uint(startPositionTXS.x);
debug.startPositionSSY = uint(startPositionTXS.y);
debug.startLinearDepth = 1 / startPositionTXS.z;
debug.startPositionSSX = uint(startPositionSS.x);
debug.startPositionSSY = uint(startPositionSS.y);
debug.startLinearDepth = 1 / startPositionSS.z;
float3 rayTXS,
float3 raySS,
debug.hitDistance = hit.distance;
debug.rayTXS = rayTXS;
debug.raySS = raySS;
debug.resultHitDepth = hit.linearDepth;
}
void FillScreenSpaceRaymarchingPreIterationDebug(

void FillScreenSpaceRaymarchingPostIterationDebug(
int iteration,
uint2 cellSize,
float3 positionTXS,
float3 positionSS,
float hitDistanceSS,
float invHiZDepth,
inout ScreenSpaceTracingDebug debug)
{

debug.cellSizeH = cellSize.y;
debug.positionTXS = positionTXS;
debug.hitLinearDepth = 1 / positionTXS.z;
debug.hitPositionSS = uint2(positionTXS.xy);
debug.positionSS = positionSS;
debug.hitLinearDepth = 1 / positionSS.z;
debug.hitPositionSS = uint2(positionSS.xy);
debug.hitDistanceSS = hitDistanceSS;
debug.hiZLinearDepth = 1 / invHiZDepth;
}
}

{
uint mipLevel = clamp(_SSRayMinLevel, 0, int(_PyramidDepthMipSize.z));
uint2 bufferSize = uint2(_PyramidDepthMipSize.xy);
uint2 referencePositionSS = input.referencePositionNDC * bufferSize;
float depth = LoadDepth(input.referencePositionNDC * (bufferSize >> mipLevel), mipLevel);
float depth = LoadDepth(referencePositionSS >> mipLevel, mipLevel);
// Calculate projected distance from the ray origin to the depth plane
float depthFromReference = depth - input.referenceLinearDepth;

float hitDistance = depthFromRayOrigin / dot(input.depthNormalWS, input.rayDirWS);
float3 hitPositionWS = input.rayOriginWS + input.rayDirWS * hitDistance;
hit.distance = hitDistance;
hit.distanceSS = length(hit.positionSS - referencePositionSS);
#ifdef DEBUG_DISPLAY

float3(0, 0, 0), // rayTXS
float3(0, 0, 0), // startPositionTXS
float3(0, 0, 0), // raySS
float3(0, 0, 0), // startPositionSS
true, // hitSuccessful
1, // iteration
1, // iterationMax

FillScreenSpaceRaymarchingPostIterationDebug(
1, // iteration
uint2(1, 1), // cellSize
float3(0, 0, 0), // positionTXS
float3(0, 0, 0), // positionSS
hit.distanceSS, // hitDistanceSS
float3(0, 0, 0), // rayTXS
float3(0, 0, 0), // raySS
hit,
debug);
_DebugScreenSpaceTracingData[0] = debug;

int maxMipLevel = min(_SSRayMaxLevel, int(_PyramidDepthMipSize.z));
uint2 bufferSize = uint2(_PyramidDepthMipSize.xy);
float3 startPositionTXS;
float3 rayTXS;
CalculateRayTXS(
float3 startPositionSS;
float3 raySS;
CalculateRaySS(
startPositionTXS,
rayTXS);
startPositionSS,
raySS);
FillScreenSpaceRaymarchingPreLoopDebug(startPositionTXS, debug);
FillScreenSpaceRaymarchingPreLoopDebug(startPositionSS, debug);
float2 invRayTXS = float2(1, 1) / rayTXS.xy;
float2 invRaySS = float2(1, 1) / raySS.xy;
int2 cellPlanes = sign(rayTXS.xy);
int2 cellPlanes = sign(raySS.xy);
float2 crossOffset = CROSS_OFFSET * cellPlanes;
cellPlanes = clamp(cellPlanes, 0, 1);

float3 positionTXS = startPositionTXS;
float3 positionSS = startPositionSS;
while (currentLevel >= minMipLevel)
{

int mipLevelDelta = -1;
// Sampled as 1/Z so it interpolate properly in screen space.
const float invHiZDepth = LoadInvDepth(positionTXS.xy, currentLevel);
float iterationDistance = 0;
const float invHiZDepth = LoadInvDepth(positionSS.xy, currentLevel);
float iterationDistanceSS = 0;
if (IsPositionAboveDepth(positionTXS.z, invHiZDepth))
if (IsPositionAboveDepth(positionSS.z, invHiZDepth))
float3 candidatePositionTXS = IntersectDepthPlane(positionTXS, rayTXS, invHiZDepth, iterationDistance);
float3 candidatePositionSS = IntersectDepthPlane(positionSS, raySS, invHiZDepth, iterationDistanceSS);
const int2 cellId = int2(positionTXS.xy) / cellSize;
const int2 candidateCellId = int2(candidatePositionTXS.xy) / cellSize;
const int2 cellId = int2(positionSS.xy) / cellSize;
const int2 candidateCellId = int2(candidatePositionSS.xy) / cellSize;
candidatePositionTXS = IntersectCellPlanes(
positionTXS,
rayTXS,
invRayTXS,
candidatePositionSS = IntersectCellPlanes(
positionSS,
raySS,
invRaySS,
iterationDistance);
iterationDistanceSS);
positionTXS = candidatePositionTXS;
positionSS = candidatePositionSS;
hit.distance += iterationDistance;
hit.distanceSS += iterationDistanceSS;
currentLevel = min(currentLevel + mipLevelDelta, maxMipLevel);

iteration,
cellSize,
positionTXS,
iterationDistance,
positionSS,
iterationDistanceSS,
hit.distanceSS,
if (any(int2(positionTXS.xy) > bufferSize)
|| any(positionTXS.xy < 0))
if (any(int2(positionSS.xy) > bufferSize)
|| any(positionSS.xy < 0))
{
hitSuccessful = false;
break;

}
hit.linearDepth = 1 / positionTXS.z;
hit.positionNDC = float2(positionTXS.xy) / float2(bufferSize);
hit.positionSS = uint2(positionTXS.xy);
hit.linearDepth = 1 / positionSS.z;
hit.positionNDC = float2(positionSS.xy) / float2(bufferSize);
hit.positionSS = uint2(positionSS.xy);
}
#ifdef DEBUG_DISPLAY

rayTXS,
raySS,
bufferSize, input.rayDirVS, rayTXS, startPositionTXS, hitSuccessful, iteration, MAX_ITERATIONS, maxMipLevel, maxUsedLevel,
bufferSize, input.rayDirVS, raySS, startPositionSS, hitSuccessful, iteration, MAX_ITERATIONS, maxMipLevel, maxUsedLevel,
hit);
if (input.writeStepDebug)
_DebugScreenSpaceTracingData[0] = debug;

int level = clamp(_SSRayMinLevel, 0, int(_PyramidDepthMipSize.z));
uint2 bufferSize = uint2(_PyramidDepthMipSize.xy);
float3 startPositionTXS;
float3 rayTXS;
CalculateRayTXS(
float3 startPositionSS;
float3 raySS;
CalculateRaySS(
startPositionTXS,
rayTXS);
startPositionSS,
raySS);
FillScreenSpaceRaymarchingPreLoopDebug(startPositionTXS, debug);
FillScreenSpaceRaymarchingPreLoopDebug(startPositionSS, debug);
float maxAbsAxis = max(abs(rayTXS.x), abs(rayTXS.y));
float maxAbsAxis = max(abs(raySS.x), abs(raySS.y));
hit.distance = 1 / startPositionTXS.z;
hit.linearDepth = 1 / startPositionTXS.z;
hit.positionSS = uint2(startPositionTXS.xy);
hit.distanceSS = 1 / startPositionSS.z;
hit.linearDepth = 1 / startPositionSS.z;
hit.positionSS = uint2(startPositionSS.xy);
rayTXS /= max(abs(rayTXS.x), abs(rayTXS.y));
rayTXS *= _SSRayMinLevel;
raySS /= max(abs(raySS.x), abs(raySS.y));
raySS *= _SSRayMinLevel;
float3 positionTXS = startPositionTXS;
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 < MAX_ITERATIONS)
{

positionTXS += rayTXS;
float invHiZDepth = LoadInvDepth(positionTXS.xy, _SSRayMinLevel);
positionSS += raySS;
hit.distanceSS += distanceStepSS;
float invHiZDepth = LoadInvDepth(positionSS.xy, _SSRayMinLevel);
positionTXS,
1 / rayTXS.z,
positionSS,
1 / raySS.z,
hit.distanceSS,
if (!IsPositionAboveDepth(positionTXS.z, invHiZDepth))
if (!IsPositionAboveDepth(positionSS.z, invHiZDepth))
{
hitSuccessful = true;
break;

if (any(int2(positionTXS.xy) > bufferSize)
|| any(positionTXS.xy < 0))
if (any(int2(positionSS.xy) > bufferSize)
|| any(positionSS.xy < 0))
{
hitSuccessful = false;
break;

}
hit.linearDepth = 1 / positionTXS.z;
hit.positionNDC = float2(positionTXS.xy) / float2(bufferSize);
hit.positionSS = uint2(positionTXS.xy);
hit.linearDepth = 1 / positionSS.z;
hit.positionNDC = float2(positionSS.xy) / float2(bufferSize);
hit.positionSS = uint2(positionSS.xy);
}
#ifdef DEBUG_DISPLAY

rayTXS,
raySS,
bufferSize, input.rayDirVS, rayTXS, startPositionTXS, hitSuccessful, iteration, MAX_ITERATIONS, 0, 0,
bufferSize, input.rayDirVS, raySS, startPositionSS, hitSuccessful, iteration, MAX_ITERATIONS, 0, 0,
hit);
if (input.writeStepDebug)
_DebugScreenSpaceTracingData[0] = debug;

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


public uint cellSizeW;
public uint cellSizeH;
public Vector3 positionTXS;
public Vector3 positionSS;
public float startLinearDepth;
public uint level;

public float hitDistance;
public float hitDistanceSS;
public Vector3 rayTXS;
public Vector3 raySS;
public Vector3 unused00;
public float resultHitDepth;
public Vector2 unused00;
}
public class DebugDisplaySettings

void RegisterStatisticsDebug()
{
var list = new List<DebugUI.Widget>();
var list = new List<DebugUI.Container>();
new DebugUI.BoolField { displayName = "Debug Iterations", getter = IsScreenSpaceTracingIterationDebugEnabled, setter = SetScreenSpaceTracingIterationDebugEnabled },
new DebugUI.EnumField { displayName = "Debug Mode", getter = GetDebugLightingSubMode, setter = SetScreenSpaceTracingDebugMode, enumNames = debugScreenSpaceTracingStrings, enumValues = debugScreenSpaceTracingValues },
new DebugUI.Value { displayName = "Cell Size", getter = () => string.Format("({0}, {1}) 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, screenSpaceTracingDebugData.iterationMax) },
new DebugUI.Value { displayName = "Start Depth", getter = () => string.Format("{0:F7} m", screenSpaceTracingDebugData.startLinearDepth) },
new DebugUI.Value { displayName = "Hit 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 = "Hit Distance", getter = () => string.Format("{0:F7} m", screenSpaceTracingDebugData.hitDistance) },
new DebugUI.Value { displayName = "Iteration Distance", getter = () => string.Format("{0:F7} m", screenSpaceTracingDebugData.iterationDistance) },
new DebugUI.Value { displayName = "Ray TXS", getter = () => string.Format("({0:F7}, {1:F7}) px", screenSpaceTracingDebugData.rayTXS.x, screenSpaceTracingDebugData.rayTXS.y) },
new DebugUI.Value { displayName = "Ray TXS Depth", getter = () => string.Format("({0:F7}) m", 1f / screenSpaceTracingDebugData.rayTXS.z) },
new DebugUI.Container
{
displayName = "Configuration",
children =
{
new DebugUI.BoolField { displayName = "Debug Iterations", getter = IsScreenSpaceTracingIterationDebugEnabled, setter = SetScreenSpaceTracingIterationDebugEnabled, onValueChanged = RefreshStatisticsDebug },
new DebugUI.EnumField { displayName = "Debug Mode", getter = GetDebugLightingSubMode, setter = SetScreenSpaceTracingDebugMode, enumNames = debugScreenSpaceTracingStrings, enumValues = debugScreenSpaceTracingValues, onValueChanged = RefreshStatisticsDebug },
}
}
if (IsScreenSpaceTracingIterationDebugEnabled() || GetDebugLightingSubMode() != 0)
{
list[list.Count - 1].children.Add(new DebugUI.Container
{
displayName = "Loop Information",
children =
{
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) },
}
});
list[list.Count - 1].children.Add(
new DebugUI.Container
{
displayName = "Iteration Information",
children =
{
new DebugUI.Value { displayName = "Cell Size", getter = () => string.Format("({0}, {1}) 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, screenSpaceTracingDebugData.iterationMax) },
new DebugUI.Value { displayName = "Hit 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 = "Hit Distance", getter = () => string.Format("{0:F7} px", screenSpaceTracingDebugData.hitDistanceSS) },
new DebugUI.Value { displayName = "Iteration Distance", getter = () => string.Format("{0:F7} m", screenSpaceTracingDebugData.iterationDistance) },
}
});
list[list.Count - 1].children.Add( new DebugUI.Container
{
displayName = "Result Information",
children =
{
new DebugUI.Value { displayName = "Hit Depth", getter = () => string.Format("{0:F7} m", screenSpaceTracingDebugData.resultHitDepth) },
}
});
}
m_DebugStatisticsItems = list.ToArray();
var panel = DebugManager.instance.GetPanel(k_PanelStatistics, true);
panel.flags |= DebugUI.Flags.ForceUpdate;

{
UnregisterDebugItems(k_PanelLighting, m_DebugLightingItems);
RegisterLightingDebug();
}
void RefreshStatisticsDebug<T>(DebugUI.Field<T> field, T value)
{
UnregisterDebugItems(k_PanelStatistics, m_DebugStatisticsItems);
RegisterStatisticsDebug();
}
public void RegisterLightingDebug()

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


uint startPositionSSY;
uint cellSizeW;
uint cellSizeH;
float3 positionTXS;
float3 positionSS;
float hitDistance;
float hitDistanceSS;
float3 rayTXS;
float3 raySS;
float3 unused00;
float resultHitDepth;
float2 unused00;
};
//

{
return value.cellSizeH;
}
float3 GetPositionTXS(ScreenSpaceTracingDebug value)
float3 GetPositionSS(ScreenSpaceTracingDebug value)
return value.positionTXS;
return value.positionSS;
}
float GetStartLinearDepth(ScreenSpaceTracingDebug value)
{

{
return value.iterationMax;
}
float GetHitDistance(ScreenSpaceTracingDebug value)
float GetHitDistanceSS(ScreenSpaceTracingDebug value)
return value.hitDistance;
return value.hitDistanceSS;
}
float GetHitLinearDepth(ScreenSpaceTracingDebug value)
{

{
return value.hiZLinearDepth;
}
float3 GetRayTXS(ScreenSpaceTracingDebug value)
float3 GetRaySS(ScreenSpaceTracingDebug value)
return value.rayTXS;
return value.raySS;
float3 GetUnused00(ScreenSpaceTracingDebug value)
float GetResultHitDepth(ScreenSpaceTracingDebug value)
{
return value.resultHitDepth;
}
float2 GetUnused00(ScreenSpaceTracingDebug value)
{
return value.unused00;
}

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


const float cellSDF = max(distanceToCell.x, distanceToCell.y);
// Position dot rendering
const float distanceToPosition = length(int2(posInput.positionSS) - int2(debug.positionTXS.xy));
const float distanceToPosition = length(int2(posInput.positionSS) - int2(debug.positionSS.xy));
const float positionSDF = clamp(circleRadius - distanceToPosition, 0, 1);
// Start position dot rendering

正在加载...
取消
保存