UnityGame/Library/PackageCache/com.unity.render-pipelines.core/Runtime/GPUDriven/GeometryUtilities.hlsl
2024-10-27 10:53:47 +03:00

84 lines
2.6 KiB
HLSL

#ifndef GEO_UTILITIES_H
#define GEO_UTILITIES_H
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl"
struct CylinderBound
{
float3 center;
float3 axis;
float halfHeight;
float capRadius;
};
struct SphereBound
{
float3 center;
float radius;
};
float CompleteSinCos(float sinOrCos)
{
return sqrt(max(1.0f - sinOrCos*sinOrCos, 0.0f));
}
float2 ProjectedHalfLengths(CylinderBound cylinder, float3 planeNormal)
{
float absCosTheta = abs(dot(planeNormal, cylinder.axis));
float sinTheta = CompleteSinCos(absCosTheta);
float h = cylinder.halfHeight;
float r = cylinder.capRadius;
float halfLengthAlongNormal = absCosTheta * h + sinTheta * r;
float halfLengthInPlane = max(sinTheta * h + absCosTheta * r, r); // ellipse, so use max of two axis lengths
return float2(halfLengthInPlane, halfLengthAlongNormal);
}
struct BoundingObjectData
{
float3 frontCenterPosRWS;
float2 centerPosNDC;
float2 radialPosNDC;
};
BoundingObjectData CalculateBoundingObjectData(SphereBound boundingSphere,
float4x4 viewProjMatrix,
float4 viewOriginWorldSpace,
float4 radialDirWorldSpace,
float4 facingDirWorldSpace)
{
const float3 centerPosRWS = boundingSphere.center - viewOriginWorldSpace.xyz;
const float3 radialVec = abs(boundingSphere.radius) * radialDirWorldSpace.xyz;
const float3 facingVec = abs(boundingSphere.radius) * facingDirWorldSpace.xyz;
BoundingObjectData data;
data.centerPosNDC = ComputeNormalizedDeviceCoordinates(centerPosRWS, viewProjMatrix);
data.radialPosNDC = ComputeNormalizedDeviceCoordinates(centerPosRWS + radialVec, viewProjMatrix);
data.frontCenterPosRWS = centerPosRWS + facingVec;
return data;
}
BoundingObjectData CalculateBoundingObjectData(CylinderBound cylinderBound,
float4x4 viewProjMatrix,
float4 viewOriginWorldSpace,
float4 radialDirWorldSpace,
float4 facingDirWorldSpace)
{
const float3 centerPosRWS = cylinderBound.center - viewOriginWorldSpace.xyz;
const float2 halfLengths = ProjectedHalfLengths(cylinderBound, facingDirWorldSpace.xyz);
const float3 radialVec = halfLengths.x * radialDirWorldSpace.xyz;
BoundingObjectData data;
data.centerPosNDC = ComputeNormalizedDeviceCoordinates(centerPosRWS, viewProjMatrix);
data.radialPosNDC = ComputeNormalizedDeviceCoordinates(centerPosRWS + radialVec, viewProjMatrix);
data.frontCenterPosRWS = centerPosRWS + halfLengths.y * facingDirWorldSpace.xyz;
return data;
}
#endif