浏览代码

Added hit weight when raymarched distance is too long

/main
Frédéric Vauchelles 7 年前
当前提交
edfe1df9
共有 2 个文件被更改,包括 72 次插入18 次删除
  1. 83
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Reflection/ScreenSpaceTracing.hlsl
  2. 7
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl

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


return testHitPositionSS;
}
float CalculateHitWeight(
ScreenSpaceRayHit hit,
float2 startPositionSS,
float invLinearDepth,
float settingsRayDepthSuccessBias
)
{
const float maxScreenDistance = 0.3;
const float blendedScreenDistance = 0.05;
// Blend when the hit is near the thickness of the object
float thicknessWeight = (1 + ((1 / invLinearDepth) - hit.linearDepth) / settingsRayDepthSuccessBias);
// Blend when the ray when the raymarched distance is too long
float2 screenDistanceNDC = abs(hit.positionSS.xy - startPositionSS) * _ScreenSize.zw;
float2 screenDistanceWeights = clamp((maxScreenDistance - screenDistanceNDC) / blendedScreenDistance, 0, 1);
float screenDistanceWeight = min(screenDistanceWeights.x, screenDistanceWeights.y);
return thicknessWeight * screenDistanceWeight;
}
bool IsRaymarchingTooFar(
float2 startPositionSS,
float2 positionSS
)
{
}
#ifdef DEBUG_DISPLAY
// -------------------------------------------------
// Debug Utilities

uint2 bufferSize, // Texture size of screen buffers
// Out
out ScreenSpaceRayHit hit,
out float hitWeight,
out uint iteration
)
{

hitWeight = 0;
int mipLevel = min(max(settingRayLevel, 0), int(_DepthPyramidScale.z));
uint maxIterations = settingsRayMaxIterations;

hit.positionNDC = float2(positionSS.xy) / float2(bufferSize);
hit.positionSS = uint2(positionSS.xy);
if (hit.linearDepth > (1 / invLinearDepth) + settingsRayDepthSuccessBias)
// Detect when we go behind an object given a thickness
hitWeight = CalculateHitWeight(
hit,
startPositionSS.xy,
invLinearDepth,
settingsRayDepthSuccessBias
);
if (hitWeight <= 0)
hitSuccessful = false;
#ifdef DEBUG_DISPLAY

);
uint iteration;
float hitWeight;
bool hitSuccessful = ScreenSpaceLinearRaymarch(
inputLinear,
// Settings

bufferSize,
// Out
hit,
hitWeight,
iteration
);

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
out ScreenSpaceRayHit hit,
out float hitWeight
)
{
const float2 CROSS_OFFSET = float2(1, 1);

hitWeight = 0;
bool hitSuccessful = false;
uint iteration = 0u;
int minMipLevel = max(settingsRayMinLevel, 0u);

bufferSize,
// out
hit,
hitWeight,
iteration
))
return true;

uint2 cellSize = uint2(1, 1) << currentLevel;
float3 positionSS = startPositionSS;
float invHiZDepth = 0;
float invLinearDepth = 0;
while (currentLevel >= minMipLevel)
{

int mipLevelDelta = -1;
// Sampled as 1/Z so it interpolate properly in screen space.
invHiZDepth = LoadInvDepth(positionSS.xy, currentLevel);
invLinearDepth = LoadInvDepth(positionSS.xy, currentLevel);
if (IsPositionAboveDepth(positionSS.z, invHiZDepth))
if (IsPositionAboveDepth(positionSS.z, invLinearDepth))
float3 candidatePositionSS = IntersectDepthPlane(positionSS, raySS, invHiZDepth);
float3 candidatePositionSS = IntersectDepthPlane(positionSS, raySS, invLinearDepth);
intersectionKind = HIZINTERSECTIONKIND_DEPTH;

{
debugLoopMipMaxUsedLevel = max(debugLoopMipMaxUsedLevel, currentLevel);
debugIterationPositionSS = positionSS;
debugIterationLinearDepthBuffer = 1 / invHiZDepth;
debugIterationLinearDepthBuffer = 1 / invLinearDepth;
debugIteration = iteration;
debugIterationIntersectionKind = intersectionKind;
debugIterationCellSize = cellSize;

// Check if we are out of the buffer
if (any(int2(positionSS.xy) > int2(bufferSize))
|| any(positionSS.xy < 0)
)
|| any(positionSS.xy < 0))
{
hitSuccessful = false;
break;

hit.positionNDC = float2(positionSS.xy) / float2(bufferSize);
hit.positionSS = uint2(positionSS.xy);
if (hit.linearDepth > (1 / invHiZDepth) + settingsRayDepthSuccessBias)
// Detect when we go behind an object given a thickness
hitWeight = CalculateHitWeight(
hit,
startPositionSS.xy,
invLinearDepth,
settingsRayDepthSuccessBias
);
if (hitWeight <= 0)
hitSuccessful = false;
#ifdef DEBUG_DISPLAY

// -------------------------------------------------
bool MERGE_NAME(ScreenSpaceLinearRaymarch, SSRTID)(
ScreenSpaceRaymarchInput input,
out ScreenSpaceRayHit hit
out ScreenSpaceRayHit hit,
out float hitWeight
)
{
uint2 bufferSize = uint2(_DepthPyramidSize.xy);

// settings
SSRT_SETTING(RayLevel, SSRTID),
SSRT_SETTING(RayMaxIterations, SSRTID),
SSRT_SETTING(RayDepthSuccessBias, SSRTID),
max(0.01, SSRT_SETTING(RayDepthSuccessBias, SSRTID)),
#ifdef DEBUG_DISPLAY
SSRT_SETTING(DebuggedAlgorithm, SSRTID),
#else

bufferSize,
// out
hit,
hitWeight,
iteration
);
}

// -------------------------------------------------
bool MERGE_NAME(ScreenSpaceHiZRaymarch, SSRTID)(
ScreenSpaceRaymarchInput input,
out ScreenSpaceRayHit hit
out ScreenSpaceRayHit hit,
out float hitWeight
)
{
return ScreenSpaceHiZRaymarch(

SSRT_SETTING(RayMaxLevel, SSRTID),
SSRT_SETTING(RayMaxIterations, SSRTID),
SSRT_SETTING(RayMaxLinearIterations, SSRTID),
SSRT_SETTING(RayDepthSuccessBias, SSRTID),
max(0.01, SSRT_SETTING(RayDepthSuccessBias, SSRTID)),
#ifdef DEBUG_DISPLAY
SSRT_SETTING(DebuggedAlgorithm, SSRTID),
#else

hit
hit,
hitWeight
);
}

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


ScreenSpaceRayHit hit;
ZERO_INITIALIZE(ScreenSpaceRayHit, hit);
bool hitSuccessful = false;
float hitWeight = 1;
// -------------------------------
// Proxy raycasting

#if HAS_REFRACTION
if (GPUImageBasedLightingType == GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION)
hitSuccessful = ScreenSpaceHiZRaymarchRefraction(ssRayInput, hit);
hitSuccessful = ScreenSpaceHiZRaymarchRefraction(ssRayInput, hit, hitWeight);
hitSuccessful = ScreenSpaceHiZRaymarchReflection(ssRayInput, hit);
hitSuccessful = ScreenSpaceHiZRaymarchReflection(ssRayInput, hit, hitWeight);
}
// Debug screen space tracing

// -------------------------------
float2 weightNDC = clamp(min(hit.positionNDC, 1 - hit.positionNDC) * invScreenWeightDistance, 0, 1);
weightNDC = weightNDC * weightNDC * (3 - 2 * weightNDC);
float weight = weightNDC.x * weightNDC.y;
float weight = weightNDC.x * weightNDC.y * hitWeight;
float hitDeviceDepth = LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, hit.positionSS, 0).r;
float hitLinearDepth = LinearEyeDepth(hitDeviceDepth, _ZBufferParams);

正在加载...
取消
保存