浏览代码

Added bruteforce screen space tracing

/feature-ScreenSpaceProjection
Frédéric Vauchelles 6 年前
当前提交
c2126e91
共有 11 个文件被更改,包括 491 次插入205 次删除
  1. 2
      ScriptableRenderPipeline/Core/CoreRP/MousePositionDebug.cs
  2. 486
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/ScreenSpaceRaymarching.hlsl
  3. 26
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs
  4. 20
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugDisplay.cs.hlsl
  5. 119
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Debug/DebugFullScreen.shader
  6. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/RenderPipelineSettingsUI.cs
  7. 7
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedRenderPipelineSettings.cs
  8. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  9. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs
  10. 22
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  11. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipeline/RenderPipelineSettings.cs

2
ScriptableRenderPipeline/Core/CoreRP/MousePositionDebug.cs


{
case KeyCode.PageUp:
++m_DebugStep;
Debug.LogFormat("DebugStep: {0}", m_DebugStep);
Debug.LogFormat("DebugStep: {0}", m_DebugStep);
break;
}
break;

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


#ifndef UNITY_SCREEN_SPACE_RAYMARCHING_INCLUDED
#ifndef UNITY_SCREEN_SPACE_RAYMARCHING_INCLUDED
struct ScreenSpaceRaymarchInput
CBUFFER_START(ScreenSpaceRaymarching)
int _SSRayMinLevel;
int _SSRayMaxLevel;
CBUFFER_END
struct ScreenSpaceHiZRaymarchInput
{
float3 startPositionVS;
float startLinearDepth;

#ifdef DEBUG_DISPLAY
bool writeStepDebug;
uint2 sourcePositionSS;
float sourceDepth;
#endif
};
struct ScreenSpaceLinearRaymarchInput
{
float3 startPositionVS;
float startLinearDepth;
float3 dirVS;
float4x4 projectionMatrix;
int2 bufferSize;
#ifdef DEBUG_DISPLAY
bool writeStepDebug;
#endif
};

float linearDepth;
float2 positionSS;
uint2 positionSS;
float2 positionNDC;
#ifdef DEBUG_DISPLAY
float3 debugOutput;

float _SSTCrossingOffset = 1;
void CalculateRayTXS(ScreenSpaceRaymarchInput input, out float3 positionTXS, out float3 rayTXS)
void CalculateRayTXS(
float3 startPositionVS,
float3 dirVS,
float4x4 projectionMatrix,
uint2 bufferSize,
out float3 positionTXS,
out float3 rayTXS)
float3 positionVS = input.startPositionVS;
float3 rayEndVS = input.startPositionVS + input.dirVS * 10;
float3 positionVS = startPositionVS;
float3 rayEndVS = startPositionVS + dirVS * 10;
float4 positionCS = ComputeClipSpacePosition(positionVS, input.projectionMatrix);
float4 rayEndCS = ComputeClipSpacePosition(rayEndVS, input.projectionMatrix);
float4 positionCS = ComputeClipSpacePosition(positionVS, projectionMatrix);
float4 rayEndCS = ComputeClipSpacePosition(rayEndVS, projectionMatrix);
float2 positionNDC = ComputeNormalizedDeviceCoordinates(positionVS, input.projectionMatrix);
float2 rayEndNDC = ComputeNormalizedDeviceCoordinates(rayEndVS, input.projectionMatrix);
float2 positionNDC = ComputeNormalizedDeviceCoordinates(positionVS, projectionMatrix);
float2 rayEndNDC = ComputeNormalizedDeviceCoordinates(rayEndVS, projectionMatrix);
positionNDC.xy * input.bufferSize,
positionNDC.xy * bufferSize,
rayEndNDC.xy * input.bufferSize,
rayEndNDC.xy * bufferSize,
1.0 / rayEndCS.w); // Screen space depth interpolate properly in 1/z
positionTXS = rayStartTXS;

return rayDepth > invLinearDepth;
}
bool ScreenSpaceRaymarch(
ScreenSpaceRaymarchInput input,
float SampleHiZDepth(float2 positionTXS, int level)
{
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, int2(positionTXS.xy) >> level, level).r;
float hiZLinearDepth = LinearEyeDepth(pyramidDepth, _ZBufferParams);
float invHiZLinearDepth = 1 / hiZLinearDepth;
return invHiZLinearDepth;
}
// positionTXS.z is 1/depth
// rayTXS.z is 1/depth
float3 IntersectDepthPlane(float3 positionTXS, float3 rayTXS, float invDepth, out float distance)
{
const float EPSILON = 1E-5;
// The depth of the intersection with the depth plane is: positionTXS.z + rayTXS.z * t = invDepth
distance = (invDepth - positionTXS.z) / rayTXS.z;
// (t<0) When the ray is going away from the depth plane,
// put the intersection away.
// Instead the intersection with the next tile will be used.
// (t>=0) Add a small distance to go through the depth plane.
distance = distance >= 0.0f ? (distance + EPSILON) : 1E5;
// Return the point on the ray
return positionTXS + rayTXS * distance;
}
bool CellAreEquals(int2 cellA, int2 cellB)
{
return cellA.x == cellB.x && cellA.y == cellB.y;
}
float3 IntersectCellPlanes(
float3 positionTXS,
float3 rayTXS,
float2 invRayTXS,
int2 cellId,
uint2 cellSize,
int2 cellPlanes,
float2 crossOffset,
out float distance)
{
// Planes to check
int2 planes = (cellId + cellPlanes) * cellSize;
// Hit distance to each planes
float2 distanceToCellAxes = float2(planes - positionTXS.xy) * invRayTXS; // (distance to x axis, distance to y axis)
distance = min(distanceToCellAxes.x, distanceToCellAxes.y);
// Interpolate screen space to get next test point
float3 testHitPositionTXS = positionTXS + rayTXS * distance;
// Offset the proper axis to enforce cell crossing
// https://gamedev.autodesk.com/blogs/1/post/5866685274515295601
testHitPositionTXS.xy += (distanceToCellAxes.x < distanceToCellAxes.y)
? float2(crossOffset.x, 0)
: float2(0, crossOffset.y);
return testHitPositionTXS;
}
#ifdef DEBUG_DISPLAY
void FillScreenSpaceRaymarchingHitDebug(
uint2 bufferSize,
float3 dirVS,
float3 rayTXS,
float3 startPositionTXS,
bool hitSuccessful,
int iteration,
int maxIterations,
int maxUsedLevel,
int maxLevel,
inout ScreenSpaceRayHit hit)
{
float3 debugOutput = float3(0, 0, 0);
if (_DebugLightingMode == DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION)
{
switch (_DebugLightingSubMode)
{
case DEBUGSCREENSPACETRACING_POSITION_NDC:
debugOutput = float3(float2(startPositionTXS.xy) / bufferSize, 0);
break;
case DEBUGSCREENSPACETRACING_DIR_VS:
debugOutput = dirVS * 0.5 + 0.5;
break;
case DEBUGSCREENSPACETRACING_DIR_NDC:
debugOutput = float3(rayTXS.xy * 0.5 + 0.5, frac(0.1 / rayTXS.z));
break;
case DEBUGSCREENSPACETRACING_HIT_DISTANCE:
debugOutput = frac(hit.distance * 0.1);
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(maxLevel);
break;
}
}
hit.debugOutput = debugOutput;
}
void FillScreenSpaceRaymarchingPreLoopDebug(
float3 startPositionTXS,
inout ScreenSpaceTracingDebug debug)
{
debug.startPositionSSX = uint(startPositionTXS.x);
debug.startPositionSSY = uint(startPositionTXS.y);
debug.startLinearDepth = 1 / startPositionTXS.z;
}
void FillScreenSpaceRaymarchingPostLoopDebug(
int maxUsedLevel,
int iteration,
ScreenSpaceRayHit hit,
inout ScreenSpaceTracingDebug debug)
{
debug.levelMax = maxUsedLevel;
debug.iterationMax = iteration;
debug.hitDistance = hit.distance;
}
void FillScreenSpaceRaymarchingPreIterationDebug(
int iteration,
int currentLevel,
inout ScreenSpaceTracingDebug debug)
{
if (_DebugStep == iteration)
debug.level = currentLevel;
}
void FillScreenSpaceRaymarchingPostIterationDebug(
int iteration,
uint2 cellSize,
float3 positionTXS,
float iterationDistance,
float invHiZDepth,
inout ScreenSpaceTracingDebug debug)
{
if (_DebugStep == iteration)
{
debug.cellSizeW = cellSize.x;
debug.cellSizeH = cellSize.y;
debug.positionTXS = positionTXS;
debug.hitLinearDepth = 1 / positionTXS.z;
debug.hitPositionSS = uint2(positionTXS.xy);
debug.iteration = iteration;
debug.iterationDistance = iterationDistance;
debug.hiZLinearDepth = 1 / invHiZDepth;
}
}
#endif
bool ScreenSpaceHiZRaymarch(
ScreenSpaceHiZRaymarchInput input,
// Initialize loop
bool hitSuccessful = true;
int iteration = 0;
int minLevel = max(input.minLevel, _SSRayMinLevel);
int maxLevel = min(input.maxLevel, _SSRayMaxLevel);
// Caclulate TXS ray
CalculateRayTXS(input, startPositionTXS, rayTXS);
CalculateRayTXS(
input.startPositionVS,
input.dirVS,
input.projectionMatrix,
input.bufferSize,
startPositionTXS,
rayTXS);
debug.startPositionSSX = uint(startPositionTXS.x);
debug.startPositionSSY = uint(startPositionTXS.y);
debug.startLinearDepth = 1 / startPositionTXS.z;
FillScreenSpaceRaymarchingPreLoopDebug(startPositionTXS, debug);
bool hitSuccessful = true;
int iteration = 0;
// No need to raymarch if the ray is along camera's foward
if (!any(rayTXS.xy))
{
hit.distance = 1 / startPositionTXS.z;

else
{
// Initialize raymarching
float2 crossOffset = CROSS_OFFSET * cellPlanes * _SSTCrossingOffset;
float2 crossOffset = CROSS_OFFSET * cellPlanes;
// Initialize loop
int currentLevel = input.minLevel;
int currentLevel = minLevel;
while (currentLevel >= input.minLevel)
// Goes to the intersection with the first cell
{
float2 absInvRayTXS = abs(invRayTXS);
positionTXS += rayTXS * min(absInvRayTXS.x, absInvRayTXS.y);
}
while (currentLevel >= minLevel)
{
if (iteration >= MAX_ITERATIONS)
{

cellCount = input.bufferSize >> currentLevel;
cellSize = uint2(1, 1) << currentLevel;
if (_DebugStep == iteration)
{
debug.cellSizeW = cellSize.x;
debug.cellSizeH = cellSize.y;
debug.positionTXS = positionTXS;
debug.hitLinearDepth = 1 / positionTXS.z;
debug.hitPositionSS = uint2(positionTXS.xy);
debug.iteration = iteration;
debug.level = currentLevel;
}
FillScreenSpaceRaymarchingPreIterationDebug(iteration, currentLevel, debug);
// 1. Calculate hit in this HiZ cell
int2 cellId = int2(positionTXS.xy) / cellSize;
// Go down in HiZ levels by default
int mipLevelDelta = -1;
// Sampled as 1/Z so it interpolate properly in screen space.
const float invHiZDepth = SampleHiZDepth(positionTXS.xy, currentLevel);
float iterationDistance = 0;
// Planes to check
int2 planes = (cellId + cellPlanes) * cellSize;
// Hit distance to each planes
float2 distanceToCellAxes = float2(planes - positionTXS.xy) * invRayTXS; // (distance to x axis, distance to y axis)
float distanceToCell = min(distanceToCellAxes.x, distanceToCellAxes.y);
// Interpolate screen space to get next test point
float3 testHitPositionTXS = positionTXS + rayTXS * distanceToCell;
if (IsPositionAboveDepth(positionTXS.z, invHiZDepth))
{
float3 candidatePositionTXS = IntersectDepthPlane(positionTXS, rayTXS, invHiZDepth, iterationDistance);
// Offset the proper axis to enforce cell crossing
// https://gamedev.autodesk.com/blogs/1/post/5866685274515295601
testHitPositionTXS.xy += (distanceToCellAxes.x < distanceToCellAxes.y)
? float2(crossOffset.x, 0)
: float2(0, crossOffset.y);
const int2 cellId = int2(positionTXS.xy) / cellSize;
const int2 candidateCellId = int2(candidatePositionTXS.xy) / cellSize;
// Check if we are out of the buffer
if (any(testHitPositionTXS.xy > input.bufferSize)
|| any(testHitPositionTXS.xy < 0))
{
hitSuccessful = false;
break;
// If we crossed the current cell
if (!CellAreEquals(cellId, candidateCellId))
{
candidatePositionTXS = IntersectCellPlanes(
positionTXS,
rayTXS,
invRayTXS,
cellId,
cellSize,
cellPlanes,
crossOffset,
iterationDistance);
// Go up a level to go faster
mipLevelDelta = 1;
}
positionTXS = candidatePositionTXS;
// 2. Sample the HiZ cell
float pyramidDepth = LOAD_TEXTURE2D_LOD(_PyramidDepthTexture, int2(testHitPositionTXS.xy) >> currentLevel, currentLevel).r;
float hiZLinearDepth = LinearEyeDepth(pyramidDepth, _ZBufferParams);
float invHiZLinearDepth = 1 / hiZLinearDepth;
hit.distance += iterationDistance;
if (IsPositionAboveDepth(testHitPositionTXS.z, invHiZLinearDepth))
{
currentLevel = min(input.maxLevel, currentLevel + 1);
currentLevel = min(currentLevel + mipLevelDelta, maxLevel);
maxUsedLevel = max(maxUsedLevel, currentLevel);
maxUsedLevel = max(maxUsedLevel, currentLevel);
FillScreenSpaceRaymarchingPostIterationDebug(
iteration,
cellSize,
positionTXS,
iterationDistance,
invHiZDepth,
debug);
positionTXS = testHitPositionTXS;
hit.distance += distanceToCell;
}
else
// Check if we are out of the buffer
if (any(positionTXS.xy > input.bufferSize)
|| any(positionTXS.xy < 0))
float rayOffsetLength = (invHiZLinearDepth - positionTXS.z) / rayTXS.z;
positionTXS += rayTXS * rayOffsetLength;
hit.distance += rayOffsetLength;
--currentLevel;
hitSuccessful = false;
break;
cellCount = input.bufferSize >> currentLevel;
cellSize = uint2(1, 1) << currentLevel;
hit.positionSS = float2(positionTXS.xy) / float2(input.bufferSize);
hit.positionNDC = float2(positionTXS.xy) / float2(input.bufferSize);
hit.positionSS = uint2(positionTXS.xy);
debug.levelMax = maxUsedLevel;
debug.iterationMax = iteration;
debug.hitDistance = hit.distance;
FillScreenSpaceRaymarchingPostLoopDebug(
maxUsedLevel,
iteration,
hit,
debug);
FillScreenSpaceRaymarchingHitDebug(
input.bufferSize, input.dirVS, rayTXS, startPositionTXS, hitSuccessful, iteration, MAX_ITERATIONS, maxLevel, maxUsedLevel,
hit);
if (input.writeStepDebug)
_DebugScreenSpaceTracingData[0] = debug;
#endif
return hitSuccessful;
}
// Based on DDA
bool ScreenSpaceLinearRaymarch(
ScreenSpaceLinearRaymarchInput input,
out ScreenSpaceRayHit hit)
{
const float2 CROSS_OFFSET = float2(1, 1);
const int MAX_ITERATIONS = 1024;
// Initialize loop
ZERO_INITIALIZE(ScreenSpaceRayHit, hit);
bool hitSuccessful = true;
int iteration = 0;
float3 startPositionTXS;
float3 rayTXS;
CalculateRayTXS(
input.startPositionVS,
input.dirVS,
input.projectionMatrix,
input.bufferSize,
startPositionTXS,
rayTXS);
#ifdef DEBUG_DISPLAY
ScreenSpaceTracingDebug debug;
ZERO_INITIALIZE(ScreenSpaceTracingDebug, debug);
FillScreenSpaceRaymarchingPreLoopDebug(startPositionTXS, debug);
#endif
if (input.writeStepDebug)
// No need to raymarch if the ray is along camera's foward
if (!any(rayTXS.xy))
_DebugScreenSpaceTracingData[0] = debug;
hit.distance = 1 / startPositionTXS.z;
hit.linearDepth = 1 / startPositionTXS.z;
hit.positionSS = uint2(startPositionTXS.xy);
if (_DebugLightingMode == DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION)
else
switch (_DebugLightingSubMode)
if (abs(rayTXS.x) < abs(rayTXS.y))
// rayTXS.y is not null here
rayTXS /= abs(rayTXS.y);
else
// rayTXS.x is not null here
rayTXS /= abs(rayTXS.x);
float3 positionTXS = startPositionTXS;
while (iteration < MAX_ITERATIONS)
case DEBUGSCREENSPACETRACING_POSITION_NDC:
hit.debugOutput = float3(float2(startPositionTXS.xy) / input.bufferSize, 0);
break;
case DEBUGSCREENSPACETRACING_DIR_VS:
hit.debugOutput = input.dirVS * 0.5 + 0.5;
break;
case DEBUGSCREENSPACETRACING_DIR_NDC:
hit.debugOutput = float3(rayTXS.xy * 0.5 + 0.5, frac(0.1 / rayTXS.z));
break;
case DEBUGSCREENSPACETRACING_HIT_DISTANCE:
hit.debugOutput = frac(hit.distance * 0.1);
break;
case DEBUGSCREENSPACETRACING_HIT_DEPTH:
hit.debugOutput = frac(hit.linearDepth * 0.1);
break;
case DEBUGSCREENSPACETRACING_HIT_SUCCESS:
hit.debugOutput = hitSuccessful;
break;
case DEBUGSCREENSPACETRACING_ITERATION_COUNT:
hit.debugOutput = float(iteration) / float(MAX_ITERATIONS);
#ifdef DEBUG_DISPLAY
FillScreenSpaceRaymarchingPreIterationDebug(iteration, 0, debug);
#endif
positionTXS += rayTXS;
float invHiZDepth = SampleHiZDepth(positionTXS.xy, 0);
#ifdef DEBUG_DISPLAY
FillScreenSpaceRaymarchingPostIterationDebug(
iteration,
uint2(0, 0),
positionTXS,
1 / rayTXS.z,
invHiZDepth,
debug);
#endif
if (!IsPositionAboveDepth(positionTXS.z, invHiZDepth))
{
hitSuccessful = true;
case DEBUGSCREENSPACETRACING_MAX_USED_LEVEL:
hit.debugOutput = float(maxUsedLevel) / float(input.maxLevel);
}
// Check if we are out of the buffer
if (any(positionTXS.xy > input.bufferSize)
|| any(positionTXS.xy < 0))
{
hitSuccessful = false;
}
++iteration;
hit.linearDepth = 1 / positionTXS.z;
hit.positionNDC = float2(positionTXS.xy) / float2(input.bufferSize);
hit.positionSS = uint2(positionTXS.xy);
#ifdef DEBUG_DISPLAY
FillScreenSpaceRaymarchingPostLoopDebug(
0,
iteration,
hit,
debug);
FillScreenSpaceRaymarchingHitDebug(
input.bufferSize, input.dirVS, rayTXS, startPositionTXS, hitSuccessful, iteration, MAX_ITERATIONS, 0, 0,
hit);
if (input.writeStepDebug)
_DebugScreenSpaceTracingData[0] = debug;
#endif
return hitSuccessful;

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


public float hitLinearDepth;
public Vector2 hitPositionSS;
public override string ToString()
{
return string.Format(
@"startPositionSS : ({0}, {1})
positionTXS : ({2}, {3})
positionDepth : {4}
cellSize : ({5}, {6})
level : {7}
levelMax : {8}
iteration : {9}
iterationMax : {10}
",
startPositionSSX, startPositionSSY,
positionTXS.x, positionTXS.y,
positionTXS.z,
cellSizeW, cellSizeH,
level,
levelMax,
iteration,
iterationMax
);
}
public float iterationDistance;
public float hiZLinearDepth;
public float unused01;
public float unused02;
}
public class DebugDisplaySettings

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


float hitDistance;
float hitLinearDepth;
float2 hitPositionSS;
float iterationDistance;
float hiZLinearDepth;
float unused01;
float unused02;
};
//

float2 GetHitPositionSS(ScreenSpaceTracingDebug value)
{
return value.hitPositionSS;
}
float GetIterationDistance(ScreenSpaceTracingDebug value)
{
return value.iterationDistance;
}
float GetHiZLinearDepth(ScreenSpaceTracingDebug value)
{
return value.hiZLinearDepth;
}
float GetUnused01(ScreenSpaceTracingDebug value)
{
return value.unused01;
}
float GetUnused02(ScreenSpaceTracingDebug value)
{
return value.unused02;
}

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


return output;
}
// String debug utilities
bool SampleFloatValue(uint2 pixelSS, uint2 positionSS, uint stringVal[16], float value)
{
bool isValid = false;
SAMPLE_DEBUG_STRING(pixelSS - positionSS, stringVal, isValid);
if (!isValid)
isValid = SampleDebugFloatNumber(pixelSS - positionSS - uint2(100, 00), value);
return isValid;
}
bool SampleIntOverIntValue(uint2 pixelSS, uint2 positionSS, uint stringVal[16], int valueA, int valueB)
{
bool isValid = false;
SAMPLE_DEBUG_STRING(pixelSS - positionSS, stringVal, isValid);
if (!isValid)
isValid = SampleDebugFontNumber(pixelSS - positionSS - uint2(100, 00), valueA);
if (!isValid)
isValid = SampleDebugLetter(pixelSS - positionSS - uint2(112, 00), '/');
if (!isValid)
isValid = SampleDebugFontNumber(pixelSS - positionSS - uint2(124, 00), valueB);
return isValid;
}
//
// Motion vector debug utilities
float DistanceToLine(float2 p, float2 p1, float2 p2)
{

{
const float circleRadius = 3.5;
const float ringSize = 1.5;
float4 color = SAMPLE_TEXTURE2D(_DebugFullScreenTexture, s_point_clamp_sampler, input.texcoord);
const float4 color = SAMPLE_TEXTURE2D(_DebugFullScreenTexture, s_point_clamp_sampler, input.texcoord);
uint4 v01 = LOAD_TEXTURE2D(_DebugScreenSpaceTracing, uint2(0, 0));
uint4 v02 = LOAD_TEXTURE2D(_DebugScreenSpaceTracing, uint2(1, 0));
uint4 v03 = LOAD_TEXTURE2D(_DebugScreenSpaceTracing, uint2(0, 1));
const uint4 v01 = LOAD_TEXTURE2D(_DebugScreenSpaceTracing, uint2(0, 0));
const uint4 v02 = LOAD_TEXTURE2D(_DebugScreenSpaceTracing, uint2(1, 0));
const uint4 v03 = LOAD_TEXTURE2D(_DebugScreenSpaceTracing, uint2(0, 1));
uint2 startPositionSS = uint2(debug.startPositionSSX, debug.startPositionSSY);
const uint2 startPositionSS = uint2(debug.startPositionSSX, debug.startPositionSSY);
uint2 cellSize = uint2(debug.cellSizeW, debug.cellSizeH);
const uint2 cellSize = uint2(debug.cellSizeW, debug.cellSizeH);
float cellSDF = max(distanceToCell.x, distanceToCell.y);
const float cellSDF = max(distanceToCell.x, distanceToCell.y);
float distanceToPosition = length(int2(posInput.positionSS) - int2(debug.positionTXS.xy));
float positionSDF = clamp(circleRadius - distanceToPosition, 0, 1);
const float distanceToPosition = length(int2(posInput.positionSS) - int2(debug.positionTXS.xy));
const float positionSDF = clamp(circleRadius - distanceToPosition, 0, 1);
float distanceToStartPosition = length(int2(posInput.positionSS) - int2(startPositionSS));
float startPositionSDF = clamp(circleRadius - distanceToStartPosition, 0, 1);
const float distanceToStartPosition = length(int2(posInput.positionSS) - int2(startPositionSS));
const float startPositionSDF = clamp(circleRadius - distanceToStartPosition, 0, 1);
float3 debugColor = float3(
const float3 debugColor = float3(
startPositionSDF,
positionSDF,
cellSDF

float4 col = float4(debugColor * 0.5 + color.rgb * 0.5, 1);
// Calculate SDF to draw a ring on both dots
float startPositionRingDistance = abs(distanceToStartPosition - circleRadius);
float startPositionRingSDF = clamp(ringSize - startPositionRingDistance, 0, 1);
float positionRingDistance = abs(distanceToPosition - circleRadius);
float positionRingSDF = clamp(ringSize - positionRingDistance, 0, 1);
float w = clamp(1 - startPositionRingSDF - positionRingSDF, 0, 1);
const float startPositionRingDistance = abs(distanceToStartPosition - circleRadius);
const float startPositionRingSDF = clamp(ringSize - startPositionRingDistance, 0, 1);
const float positionRingDistance = abs(distanceToPosition - circleRadius);
const float positionRingSDF = clamp(ringSize - positionRingDistance, 0, 1);
const float w = clamp(1 - startPositionRingSDF - positionRingSDF, 0, 1);
const uint kStartDepthString[] = { 'S', 't', 'a', 'r', 't', ' ', 'D', 'e', 'p', 't', 'h', ':', ' ', 0u };
const uint kDepthString[] = { 'D', 'e', 'p', 't', 'h', ':', ' ', 0u };
const uint kLevelString[] = { 'L', 'e', 'v', 'e', 'l', ':', ' ', 0u };
const uint kIterationString[] = { 'I', 't', 'e', 'r', 'a', 't', 'i', 'o', 'n', ':', ' ', 0u };
const uint kStrings1[16] = { 'S', 't', 'a', 'r', 't', ' ', 'D', 'e', 'p', 't', 'h', ':', ' ', 0u, ' ', ' ' };
const uint kStrings2[16] = { 'D', 'e', 'p', 't', 'h', ':', ' ', 0u, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };
const uint kStrings3[16] = { 'L', 'e', 'v', 'e', 'l', ':', ' ', 0u, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' };
const uint kStrings4[16] = { 'I', 't', 'e', 'r', 'a', 't', 'i', 'o', 'n', ':', ' ', 0u, ' ', ' ', ' ', ' ' };
const uint kStrings5[16] = { 'I', 't', '.', ' ', 'D', 'i', 's', 't', 'a', 'n', 'c', 'e', ':', ' ', 0u, ' ' };
const uint kStrings6[16] = { 'I', 't', '.', ' ', 'H', 'i', 'Z', ' ', 'D', 'e', 'p', 't', 'h', ':', ' ', 0u };
if (
// SampleFloatValue (posInput.positionSS, uint2(70, 10), kStrings1, debug.startLinearDepth)
SampleFloatValue (posInput.positionSS, uint2(70, 30), kStrings2, debug.hitLinearDepth)
//|| SampleIntOverIntValue(posInput.positionSS, uint2(70, 50), kStrings3, debug.level, debug.levelMax)
|| SampleIntOverIntValue(posInput.positionSS, uint2(70, 70), kStrings4, debug.iteration + 1, debug.iterationMax)
uint2 p = uint2(70, 10);
bool isValid = false;
SAMPLE_DEBUG_STRING(posInput.positionSS - p, kStartDepthString, isValid);
if (isValid)
col = float4(1, 1, 1, 1);
if (SampleDebugFloatNumber(posInput.positionSS - p - uint2(100, 00), debug.startLinearDepth))
|| SampleFloatValue (posInput.positionSS, uint2(300, 10), kStrings5, debug.iterationDistance)
|| SampleFloatValue (posInput.positionSS, uint2(300, 30), kStrings6, debug.hiZLinearDepth)
)
p += uint2(00, 20);
isValid = false;
SAMPLE_DEBUG_STRING(posInput.positionSS - p, kDepthString, isValid);
if (isValid)
col = float4(1, 1, 1, 1);
if (SampleDebugFloatNumber(posInput.positionSS - p - uint2(100, 00), debug.hitLinearDepth))
col = float4(1, 1, 1, 1);
p += uint2(00, 20);
isValid = false;
SAMPLE_DEBUG_STRING(posInput.positionSS - p, kLevelString, isValid);
if (isValid)
col = float4(1, 1, 1, 1);
if (SampleDebugFontNumber(posInput.positionSS - p - uint2(100, 00), debug.level))
col = float4(1, 1, 1, 1);
if (SampleDebugLetter(posInput.positionSS - p - uint2(112, 00), '/'))
col = float4(1, 1, 1, 1);
if (SampleDebugFontNumber(posInput.positionSS - p - uint2(124, 00), debug.levelMax))
col = float4(1, 1, 1, 1);
p += uint2(00, 20);
isValid = false;
SAMPLE_DEBUG_STRING(posInput.positionSS - p, kIterationString, isValid);
if (isValid)
col = float4(1, 1, 1, 1);
if (SampleDebugFontNumber(posInput.positionSS - p - uint2(100, 00), debug.iteration + 1))
col = float4(1, 1, 1, 1);
if (SampleDebugLetter(posInput.positionSS - p - uint2(112, 00), '/'))
col = float4(1, 1, 1, 1);
if (SampleDebugFontNumber(posInput.positionSS - p - uint2(124, 00), debug.iterationMax))
col = float4(1, 1, 1, 1);
p += uint2(00, 20);
}
return col;

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/RenderPipelineSettingsUI.cs


EditorGUILayout.PropertyField(d.supportMotionVectors, _.GetContent("Support Motion Vectors"));
EditorGUILayout.PropertyField(d.supportStereo, _.GetContent("Support Stereo Rendering"));
EditorGUILayout.PropertyField(d.enableUltraQualitySSS, _.GetContent("Increase SSS Sample Count"));
EditorGUILayout.PropertyField(d.ssRayMinLevel, _.GetContent("Screen Space Raymarching Min Level"));
EditorGUILayout.PropertyField(d.ssRayMaxLevel, _.GetContent("Screen Space Raymarching Max Level"));
--EditorGUI.indentLevel;
}
}

7
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedRenderPipelineSettings.cs


public SerializedProperty supportStereo;
public SerializedProperty enableUltraQualitySSS;
public SerializedProperty ssRayMinLevel;
public SerializedProperty ssRayMaxLevel;
public SerializedGlobalLightLoopSettings lightLoopSettings;
public SerializedShadowInitParameters shadowInitParams;
public SerializedGlobalDecalSettings decalSettings;

supportMotionVectors = root.Find((RenderPipelineSettings s) => s.supportMotionVectors);
supportStereo = root.Find((RenderPipelineSettings s) => s.supportStereo);
enableUltraQualitySSS = root.Find((RenderPipelineSettings s) => s.enableUltraQualitySSS);
ssRayMinLevel = root.Find((RenderPipelineSettings s) => s.ssRayMinLevel);
ssRayMaxLevel = root.Find((RenderPipelineSettings s) => s.ssRayMaxLevel);
lightLoopSettings = new SerializedGlobalLightLoopSettings(root.Find((RenderPipelineSettings s) => s.lightLoopSettings));
shadowInitParams = new SerializedShadowInitParameters(root.Find((RenderPipelineSettings s) => s.shadowInitParams));

4
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


m_DbufferManager.PushGlobalParams(cmd, m_FrameSettings);
m_VolumetricLightingModule.PushGlobalParams(hdCamera, cmd);
cmd.SetGlobalInt(HDShaderIDs._SSRayMinLevel, m_Asset.renderPipelineSettings.ssRayMinLevel);
cmd.SetGlobalInt(HDShaderIDs._SSRayMaxLevel, m_Asset.renderPipelineSettings.ssRayMaxLevel);
}
}

public void ApplyDebugDisplaySettings(HDCamera hdCamera, CommandBuffer cmd)
{
cmd.SetGlobalFloat("_SSTCrossingOffset", m_CurrentDebugDisplaySettings.lightingDebugSettings.sstCrossingOffset);
if (m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled() ||
m_CurrentDebugDisplaySettings.fullScreenDebugMode != FullScreenDebugMode.None ||
m_CurrentDebugDisplaySettings.colorPickerDebugSettings.colorPickerMode != ColorPickerDebugMode.None)

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs


public static readonly int _VBufferLightingHistory = Shader.PropertyToID("_VBufferLightingHistory");
public static readonly int _VBufferLightingFeedback = Shader.PropertyToID("_VBufferLightingFeedback");
public static readonly int _VBufferSampleOffset = Shader.PropertyToID("_VBufferSampleOffset");
public static readonly int _SSRayMinLevel = Shader.PropertyToID("_SSRayMinLevel");
public static readonly int _SSRayMaxLevel = Shader.PropertyToID("_SSRayMaxLevel");
}
}

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


// SurfaceData is define in Lit.cs which generate Lit.cs.hlsl
// SurfaceData is define in Lit.cs which generate Lit.cs.hlsl
#include "Lit.cs.hlsl"
#include "../SubsurfaceScattering/SubsurfaceScattering.hlsl"
#include "CoreRP/ShaderLibrary/VolumeRendering.hlsl"

uint2 depthSize = uint2(_PyramidDepthMipSize.xy);
ScreenSpaceRaymarchInput ssInput;
ZERO_INITIALIZE(ScreenSpaceRaymarchInput, ssInput);
ScreenSpaceLinearRaymarchInput ssInput;
ZERO_INITIALIZE(ScreenSpaceLinearRaymarchInput, ssInput);
//ScreenSpaceHiZRaymarchInput ssInput;
//ZERO_INITIALIZE(ScreenSpaceHiZRaymarchInput, ssInput);
ScreenSpaceRayHit hit;
ZERO_INITIALIZE(ScreenSpaceRayHit, hit);

ssInput.dirVS = transparentRefractVVS;
ssInput.projectionMatrix = UNITY_MATRIX_P;
ssInput.bufferSize = depthSize;
ssInput.minLevel = 2;
ssInput.maxLevel = int(_PyramidDepthMipSize.z);
//ssInput.minLevel = 0;
//ssInput.maxLevel = int(_PyramidDepthMipSize.z);
bool hitSuccessful = ScreenSpaceRaymarch(ssInput, hit);
bool hitSuccessful = ScreenSpaceLinearRaymarch(ssInput, hit);
#ifdef DEBUG_DISPLAY
if (_DebugLightingMode == DEBUGLIGHTINGMODE_SCREEN_SPACE_TRACING_REFRACTION)

// Exit if texel is out of color buffer
// Or if the texel is from an object in front of the object
if (hit.linearDepth < posInput.linearDepth
|| any(hit.positionSS < 0.0)
|| any(hit.positionSS > 1.0))
|| any(hit.positionNDC < 0.0)
|| any(hit.positionNDC > 1.0))
{
// Do nothing and don't update the hierarchy weight so we can fall back on refraction probe
return lighting;

lighting.specularTransmitted = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, hit.positionSS * _GaussianPyramidColorMipSize.xy, preLightData.transparentSSMipLevel).rgb;
lighting.specularTransmitted = SAMPLE_TEXTURE2D_LOD(_GaussianPyramidColorTexture, s_trilinear_clamp_sampler, hit.positionNDC * _GaussianPyramidColorMipSize.xy, preLightData.transparentSSMipLevel).rgb;
// Beer-Lamber law for absorption
lighting.specularTransmitted *= preLightData.transparentTransmittance;

// 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;
#else
// No refraction, no need to go further
hierarchyWeight = 1.0;

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipeline/RenderPipelineSettings.cs


public GlobalLightLoopSettings lightLoopSettings = new GlobalLightLoopSettings();
public ShadowInitParameters shadowInitParams = new ShadowInitParameters();
public GlobalDecalSettings decalSettings = new GlobalDecalSettings();
public int ssRayMinLevel = 2;
public int ssRayMaxLevel = 10;
}
}
正在加载...
取消
保存