Camera:GetLargestCutoffDistance Source?

Since Camera:GetLargestCutoffDistance is deprecated (Camera | Roblox Creator Documentation), I have to create my own method to get the “Largest Cutoff Distance”.
For some reason even though I managed to achieve identical results there seems to be some imprecision on the x-axis. If somebody has the source of the original camera method or has achieved 100% identical results please share it with me.

function SCamera:GetLargestCutOffDistance(CameraCFrame: CFrame,Focus: CFrame)
	local Origin = Focus.Position
	local Direction = CameraCFrame.Position - Focus.Position 
	local RaycastResult: RaycastResult = workspace:Raycast(Origin,Direction,self.RayParams)
	
	if RaycastResult then
		return (RaycastResult.Position - CameraCFrame.Position).Magnitude 
	else
		return 0 
	end
end 
1 Like

Hello,

I just found this post from searching up this topic myself while trying to implement my own occulsion

Quote from the GetLargestCutoffDistance() documentation,

This function is used by ‘PopperCam’ in the default camera scripts to ensure obstructions do not come between the Camera and the Camera’s subject.

The replacement for this deprecated method seems to be implemented in the Roblox default camera modules as a function.

The new function can be found in PlayerModule.CameraModule.ZoomControler.Popper
Make a copy of the PlayerModule during runtime and paste it back into StarterPlayerScripts ,
then from there you can access the Popper by requiring the module.

From my limited testing, the Popper() function seems to returns the same as GetLargestCutoffDistance().
i.e. “the distance that the Camera needs to be pushed towards its Camera.Focus to ensure there are no obstructions between the Camera.Focus and Camera.CFrame of the Camera.”

Hope this will help you

3 Likes

Thank you for taking the time to share this with me. I took a quick look at the Popper module it seems to serve the same purpose. I will test to confirm as soon I can and mark your reply as the solution.

1 Like

Apologies for the very late response but it seems the Popper function returns another kind of distance. If somebody has found the GetLargestCutoffDistance source feel free to enlighten me.

Edit: It seems like the Popper returns the maximum distance from the focus point. (while factoring occlusion)

1 Like

Hey there, this is going to be a late reply (one year!) but I’ve just made a version that seems to replicate the functionality of :GetLargestCutoffDistance() quite well!

The issue I found with your above implementation is that it fails to account for the collision radius of the camera. I’ve made a version of your function that accounts for the collision radius and returns a proper magnitude to avoid that X-axis inaccuracy/clipping:

local function getLargestCutoffDistance(currentFocus: CFrame, goalCFrame: CFrame, collisionRadius: number, ignoreList: { any }?): number
	local origin = currentFocus.Position

	local params = RaycastParams.new()
	params.FilterDescendantsInstances = ignoreList or {}
	params.FilterType = Enum.RaycastFilterType.Exclude

	-- Camera bounds
	local cameraOffsets = {
		Vector3.new(0, 0, 0), -- camera center
		Vector3.new(collisionRadius, 0, 0), -- right of the camera
		Vector3.new(-collisionRadius, 0, 0), -- left of the camera
	}

	local largestCutoffDistance = 0

	for _, offset in ipairs(cameraOffsets) do
		local correctedGoalCFrame = goalCFrame * CFrame.new(offset)
		local direction = ((correctedGoalCFrame.Position) - currentFocus.Position)
		local result: RaycastResult = workspace:Raycast(origin, direction, params)

		if not result then
			continue
		end
		local distance = (result.Position - correctedGoalCFrame.Position).Magnitude
		if distance > largestCutoffDistance then
			largestCutoffDistance = distance
		end
	end

	return largestCutoffDistance
end

The next question is:

“How do we calculate the collision radius of the camera?”

This function below will do it for you. I’m not going to act like I understand the math of how it fully works lol.

local function getCollisionRadius(): number
	local camera = workspace.CurrentCamera
	local viewportSize = camera.ViewportSize
	local aspectRatio = viewportSize.X / viewportSize.Y
	local fovRads = math.rad(camera.FieldOfView)
	local imageHeight = math.tan(fovRads) * math.abs(camera.NearPlaneZ)
	local imageWidth = imageHeight * aspectRatio

	local cornerPos = Vector3.new(imageWidth, imageHeight, camera.NearPlaneZ)
	return cornerPos.Magnitude
end

Hopefully this helps you if you still need it or it helps anyone else who stumbles across this DevForum post!

2 Likes

Thanks for the reply! I have since figured out a way to replicate the functionality and have implemented a very similar implementation (no pun intended) for my camera resource.

function SUCamera._GetCollisionRadius(self: SUCamera)
	if self._CurrentCamera == nil then
		return 0
	end

	local ViewportSize: Vector2 = self._CurrentCamera.ViewportSize
	local AspectRatio = ViewportSize.X / ViewportSize.Y
	local FovRads = math.rad(self.FOV)
	local ImageHeight = math.tan(FovRads) * math.abs(self._CurrentCamera.NearPlaneZ)
	local ImageWidth = ImageHeight * AspectRatio

	local CornerPos = Vector3.new(ImageWidth, ImageHeight, self._CurrentCamera.NearPlaneZ)

	return CornerPos.Magnitude
end
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.