177 lines
4.6 KiB
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 |