I’m trying to calculate the minimum surface offset for my custom camera system to avoid clipping on parts/meshes, my current system works to an extent but doesn’t seem to properly avoid all clipping.
This is my code that handles the detection and calculations:
local cameraRaycastParams: RaycastParams = RaycastParams.new()
cameraRaycastParams.FilterType = Enum.RaycastFilterType.Exclude
cameraRaycastParams.FilterDescendantsInstances = { self.character }
cameraRaycastParams:AddToFilter(CollectionService:GetTagged("CameraIgnore"))
local hitPosition: Vector3?, hitNormal: Vector3?
while true do
local originPosition: Vector3 = centerPosition
local direction: Vector3 = newCameraCFrame.Position - originPosition
local raycastResult: RaycastResult? = workspace:Raycast(originPosition, direction, cameraRaycastParams)
if raycastResult then
if raycastResult.Instance:IsA("Terrain") then
hitPosition, hitNormal = raycastResult.Position, raycastResult.Normal
break
else
if raycastResult.Instance.Transparency >= 0.7 then
if not table.find(cameraRaycastParams.FilterDescendantsInstances, raycastResult.Instance) then
cameraRaycastParams:AddToFilter({ raycastResult.Instance })
continue
end
end
hitPosition, hitNormal = raycastResult.Position, raycastResult.Normal
break
end
end
hitPosition = newCameraCFrame.Position
break
end
if hitNormal then
local nearPlaneZ: number = -currentCamera.NearPlaneZ
local fieldOfView: number = currentCamera.FieldOfView
local cameraDistanceToFocus: number = (currentCamera.Focus.Position - hitPosition).Magnitude
local clippingPlaneWidth: number = 2 * nearPlaneZ * math.tan(math.rad(fieldOfView) / 2)
local minimumDistanceToAvoidClipping: number = nearPlaneZ + clippingPlaneWidth / 2
hitPosition = hitPosition + hitNormal * minimumDistanceToAvoidClipping
end
When the camera gets close to a surface but doesn’t quite touch it yet, it can see through the surface, I’ve tried using other resources from topics similar to mine with no success, you can see the issue below: streamable
External MediaThe goal is to avoid this issue as a whole, if anyone has a solution, I’d greatly appreciate the help.