48 lines
1.5 KiB
HLSL
48 lines
1.5 KiB
HLSL
#ifndef VOLUME_SDF
|
|
#define VOLUME_SDF
|
|
|
|
float3 GetPositionOS(float4x4 inverseWorldMatrix, float3 positionWS)
|
|
{
|
|
// To handle camera relative rendering we need to apply translation before converting to object space
|
|
return mul(ApplyCameraTranslationToInverseMatrix(inverseWorldMatrix), float4(positionWS, 1.0)).xyz;
|
|
}
|
|
|
|
float BoxSDF(float3 positionWS, VolumeData data)
|
|
{
|
|
float3 halfDim = data.size * 0.5;
|
|
|
|
float3 positionLS = GetPositionOS(data.inverseWorldMatrix, positionWS);
|
|
|
|
float3 d = halfDim - abs(positionLS);
|
|
float distToFace = min(d.x, min(d.y, d.z));
|
|
float maxDist = min(halfDim.x, min(halfDim.y, halfDim.z));
|
|
|
|
return saturate(distToFace / maxDist);
|
|
}
|
|
|
|
float CapsuleSDF(float3 positionWS, VolumeData data)
|
|
{
|
|
float3 positionLS = GetPositionOS(data.inverseWorldMatrix, positionWS);
|
|
|
|
float radius = data.size.x;
|
|
float length = data.size.y;
|
|
|
|
// Define capsule along Y-axis in local space
|
|
float3 capsuleStart = float3(0, -length * 0.5, 0);
|
|
float3 capsuleEnd = float3(0, length * 0.5, 0);
|
|
|
|
// Compute SDF in local space
|
|
float3 dir = capsuleEnd - capsuleStart;
|
|
float lengthSq = dot(dir, dir);
|
|
float3 toPoint = positionLS - capsuleStart;
|
|
float projection = saturate(dot(toPoint, dir) / lengthSq);
|
|
float3 closestPoint = capsuleStart + projection * dir;
|
|
return distance(positionLS, closestPoint) - radius;
|
|
}
|
|
|
|
float EvaluateAOVolumeMask(VolumeData data, float3 positionWS, float3 normalWS)
|
|
{
|
|
return BoxSDF(positionWS, data);
|
|
}
|
|
|
|
#endif |