#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