ElectricityBusinessHall_Dig.../Assets/ShinySSRR/Runtime/Resources/SSR/SSR_Common.hlsl

177 lines
4.6 KiB
HLSL

#ifndef SSR_COMMON
#define SSR_COMMON
struct VertexPositionInputs
{
float3 positionWS; // World space position
float3 positionVS; // View space position
float4 positionCS; // Homogeneous clip space position
float4 positionNDC;// Homogeneous normalized device coordinates
};
struct VertexNormalInputs
{
float3 tangentWS;
float3 bitangentWS;
float3 normalWS;
};
#define FLT_MIN 1.175494351e-38 // Minimum normalized positive floating-point number
// Normalize that account for vectors with zero length
float3 SafeNormalize(float3 inVec)
{
float dp3 = max(FLT_MIN, dot(inVec, inVec));
return inVec * rsqrt(dp3);
}
float4x4 GetObjectToWorldMatrix()
{
return UNITY_MATRIX_M;
}
float4x4 GetWorldToObjectMatrix()
{
return unity_WorldToObject;
}
float4x4 GetWorldToViewMatrix()
{
return UNITY_MATRIX_V;
}
float4x4 GetWorldToHClipMatrix()
{
return UNITY_MATRIX_VP;
}
float3 GetCameraPositionWS()
{
return _WorldSpaceCameraPos;
}
float3 TransformObjectToWorld(float3 positionOS)
{
return mul(GetObjectToWorldMatrix(), float4(positionOS, 1.0)).xyz;
}
float3 TransformWorldToView(float3 positionWS)
{
return mul(GetWorldToViewMatrix(), float4(positionWS, 1.0)).xyz;
}
float3 TransformObjectToWorldDir(float3 dirOS)
{
// Normalize to support uniform scaling
return SafeNormalize(mul((float3x3)GetObjectToWorldMatrix(), dirOS));
}
float3 TransformWorldToViewDir(float3 dirWS)
{
return mul((float3x3)GetWorldToViewMatrix(), dirWS).xyz;
}
float4 TransformObjectToHClip(float3 positionOS)
{
// More efficient than computing M*VP matrix product
return mul(GetWorldToHClipMatrix(), mul(GetObjectToWorldMatrix(), float4(positionOS, 1.0)));
}
float4 TransformWorldToHClip(float3 positionWS)
{
return mul(GetWorldToHClipMatrix(), float4(positionWS, 1.0));
}
float3 TransformTangentToWorld(float3 dirTS, float3x3 tangentToWorld)
{
// Note matrix is in row major convention with left multiplication as it is build on the fly
return mul(dirTS, tangentToWorld);
}
float3 TransformObjectToWorldNormal(float3 normalOS)
{
#ifdef UNITY_ASSUME_UNIFORM_SCALING
return TransformObjectToWorldDir(normalOS);
#else
// Normal need to be multiply by inverse transpose
return SafeNormalize(mul(normalOS, (float3x3)GetWorldToObjectMatrix()));
#endif
}
VertexPositionInputs GetVertexPositionInputs(float3 positionOS)
{
VertexPositionInputs input;
input.positionWS = TransformObjectToWorld(positionOS);
input.positionVS = TransformWorldToView(input.positionWS);
input.positionCS = TransformWorldToHClip(input.positionWS);
float4 ndc = input.positionCS * 0.5f;
input.positionNDC.xy = float2(ndc.x, ndc.y * _ProjectionParams.x) + ndc.w;
input.positionNDC.zw = input.positionCS.zw;
return input;
}
float GetOddNegativeScale()
{
return unity_WorldTransformParams.w;
}
VertexNormalInputs GetVertexNormalInputs(float3 normalOS, float4 tangentOS)
{
VertexNormalInputs tbn;
// mikkts space compliant. only normalize when extracting normal at frag.
float sign = tangentOS.w * GetOddNegativeScale();
tbn.normalWS = TransformObjectToWorldNormal(normalOS);
tbn.tangentWS = TransformObjectToWorldDir(tangentOS.xyz);
tbn.bitangentWS = cross(tbn.normalWS, tbn.tangentWS) * sign;
return tbn;
}
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 ComputeViewSpacePosition(float2 positionNDC, float deviceDepth, float4x4 invProjMatrix)
{
float4 positionCS = ComputeClipSpacePosition(positionNDC, deviceDepth);
float4 positionVS = mul(invProjMatrix, positionCS);
// The view space uses a right-handed coordinate system.
positionVS.z = -positionVS.z;
return positionVS.xyz / positionVS.w;
}
UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
float4 _CameraDepthTexture_TexelSize;
inline float GetDepth01(float2 uv) {
float rawDepth = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(uv, 0, 0)).r;
return Linear01Depth(rawDepth);
}
inline float GetLinearDepth(float2 uv) {
float rawDepth = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(uv, 0, 0)).r;
return LinearEyeDepth(rawDepth);
}
#endif // SSR_COMMON