Files
com.misaki.ao-volume/Runtime/Shader/Includes/VolumeSDF.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