您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

193 行
6.4 KiB

Shader "Perception/KeypointDepthCheck"
{
Properties
{
_Positions("Positions", 2D) = "defaultTexture" {}
_KeypointCheckDepth("KeypointCheckDepth", 2D) = "defaultTexture" {}
_DepthTexture("Depth", 2DArray) = "defaultTexture" {}
}
HLSLINCLUDE
#pragma target 4.5
#pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
//enable GPU instancing support
#pragma multi_compile HDRP_DISABLED HDRP_ENABLED
#pragma multi_compile_instancing
ENDHLSL
SubShader
{
Pass
{
Tags { "LightMode" = "SRP" }
Name "KeypointDepthCheck"
ZWrite Off
ZTest Always
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
HLSLPROGRAM
#pragma only_renderers d3d11 vulkan metal
#pragma target 4.5
#pragma vertex Vert
#pragma fragment Frag
static const float2 checkOffsets[9] = {
float2( 0, 0),
float2(-1, -1),
float2( 0, -1),
float2( 1, -1),
float2(-1, 0),
float2( 1, 0),
float2(-1, 1),
float2( 0, 1),
float2( 1, 1)};
Texture2D _Positions;
Texture2D _KeypointCheckDepth;
#if HDRP_ENABLED
#pragma enable_d3d11_debug_symbols
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassCommon.hlsl"
float4 Frag(Varyings varyings) : SV_Target
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varyings);
float checkDepth = _KeypointCheckDepth.Load(float3(varyings.positionCS.xy, 0)).r;
float2 checkPosition = _Positions.Load(float3(varyings.positionCS.xy, 0)).xy;
checkPosition = float2(checkPosition.x, _ScreenSize.y - checkPosition.y);
float2 checkPositionResolved;
float depth;
for (int i = 0; i < 9; i++)
{
checkPositionResolved = checkPosition + checkOffsets[i];
depth = LoadCameraDepth(checkPositionResolved);
if (depth > 0)
break;
}
PositionInputs positionInputs = GetPositionInput(checkPosition, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
depth = positionInputs.linearDepth;
uint result = depth >= checkDepth ? 1 : 0;
return float4(result, result, result, 1);
}
#else
#include "UnityCG.cginc"
//copied from UnityInput.hlsl
float4x4 _InvViewProjMatrix;
float4x4 _InvProjMatrix;
//#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f Vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
bool IsPerspectiveProjection()
{
return unity_OrthoParams.w == 0;
}
float ViewSpaceDepth(float depth)
{
if (IsPerspectiveProjection())
return LinearEyeDepth(depth);
else
return _ProjectionParams.y + (_ProjectionParams.z - _ProjectionParams.y) * (1 - depth);
}
float EncodeAndDecodeDepth(float vsDepth)
{
if (IsPerspectiveProjection())
{
//derived from vsDepth = 1.0 / (_ZBufferParams.z * dtDepth + _ZBufferParams.w);
float dtDepth = (1.0 / vsDepth - _ZBufferParams.w) / _ZBufferParams.z;
dtDepth = dtDepth;
return LinearEyeDepth(dtDepth);
}
else //in orthographic projections depth is linear so there is no loss of precision.
return vsDepth;
}
Texture2D _CameraDepthTexture;
float LoadSceneDepth(uint2 uv)
{
return _CameraDepthTexture.Load(float3(uv, 0)).r;
}
float4 ComputeClipSpacePosition(float2 positionNDC, float deviceDepth)
{
float4 positionCS = float4(positionNDC * 2.0 - 1.0, deviceDepth, 1.0);
#if UNITY_UV_STARTS_AT_TOP
// Our world space, view space, screen space and NDC space are Y-up.
// Our clip space is flipped upside-down due to poor legacy Unity design.
// The flip is baked into the projection matrix, so we only have to flip
// manually when going from CS to NDC and back.
positionCS.y = -positionCS.y;
#endif
return positionCS;
}
float3 ComputeWorldSpacePosition(float2 positionNDC, float deviceDepth, float4x4 invViewProjMatrix)
{
float4 positionCS = ComputeClipSpacePosition(positionNDC, deviceDepth);
float4 hpositionWS = mul(invViewProjMatrix, positionCS);
return hpositionWS.xyz / hpositionWS.w;
}
fixed4 Frag (v2f i) : SV_Target
{
float depthVSToCheck = _KeypointCheckDepth.Load(float3(i.vertex.xy, 0)).r;
float2 checkPosition = _Positions.Load(float3(i.vertex.xy, 0)).xy;
checkPosition = float2(checkPosition.x, _ScreenParams.y - checkPosition.y);
float2 checkPositionResolved;
float depth;
for (int i = 0; i < 9; i++)
{
checkPositionResolved = checkPosition + checkOffsets[i];
depth = LoadSceneDepth(checkPositionResolved);
if (depth > 0)
break;
}
float depthVSActual = ViewSpaceDepth(depth);
uint result = depthVSActual >= depthVSToCheck ? 1 : 0;
return float4(result, result, result, 1);
}
#endif
ENDHLSL
}
}
Fallback Off
}