Im making a in-game screenshot system (very laggy)

im making a screen shot system using viewport frames but the problem comes when i clone the whole game into one viewport frames,how can i NOT do that and only clone items that are seen by the camera?
here is my current local script

local ignore = {"Camera","Terrain","Script","LocalScript","Attachment","BodyVelocity","BodyForce","BodyThrust","SpringConstraint","Motor6d","PrismaticConstraint"}
script.Parent.MouseButton1Click:Connect(function()
	local s = script.Sky:Clone()
	s.Parent = script.Parent.Parent.Frame
	local vpf = s.ViewportFrame
	local cam = Instance.new("Camera")
	cam.CFrame = workspace.CurrentCamera.CFrame
	cam.Parent = vpf
	vpf.CurrentCamera = cam
	local scene = Instance.new("Model")
	scene.Name = "Scene"
	scene.Parent = vpf
	for i,v in pairs(workspace:GetDescendants()) do
		if (v:IsA("Part") or v:IsA("BasePart") or v:IsA("MeshPart") or v:IsA("UnionOperation")) and v.Name ~= game.Players.LocalPlayer.Name then
			if not table.find(ignore,v.ClassName) then
				v:Clone().Parent = scene
			end
		end
		if v.Name == game.Players.LocalPlayer.Name then
			local model = Instance.new("Model")
			model.Name = v.Name
			model.Parent = vpf
			for i,v in pairs(v:GetChildren()) do 
				v:Clone().Parent = model
			end
			model:FindFirstChild("Humanoid").DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None
		end
	end
end)

thx for any help you can give!

1 Like

Use something like that to check?

thanks ill check in a minute! hope it works!

Just a heads up that it might be a bit much for a quick check. You can probably get away with something a little simpler, like assuming that all parts are spheres with radius size.Magnitude/2 and that the view frustum is a round cone or something.

so yeah i tried out that function it was working and it made the lag sooooo much better but the problem i found that if i have two trees and i took a pic by standing in the middle i found that sometimes only one of them shows up here is my updated code

local ignore = {"Camera","Terrain","Script","LocalScript","Attachment","BodyVelocity","BodyForce","BodyThrust","SpringConstraint","Motor6d","PrismaticConstraint"}
local function OnScreen(camera, part)
	-- 1. get all eight points in 3D space for the part

	local pos, front, right, up = part.Position, part.CFrame.LookVector, part.CFrame.RightVector, part.CFrame.UpVector
	local hx, hy, hz = part.Size.X / 2, part.Size.Y / 2, part.Size.Z / 2

	local points = {
		pos - front * hz - right * hx - up * hy,
		pos - front * hz - right * hx + up * hy,
		pos - front * hz + right * hx - up * hy,
		pos - front * hz + right * hx + up * hy,
		pos + front * hz - right * hx - up * hy,
		pos + front * hz - right * hx + up * hy,
		pos + front * hz + right * hx - up * hy,
		pos + front * hz + right * hx + up * hy,
	}

	-- 2. compute AABB of the part's bounds on screen

	local minX, maxX, minY, maxY = math.huge, -math.huge, math.huge, -math.huge

	for i = 1, 8 do
		local screenPoint = camera:WorldToViewportPoint(points[i])
		local x, y = screenPoint.X, screenPoint.Y

		if screenPoint.Z > 0 then
			if x < minX then minX = x end
			if x > maxX then maxX = x end
			if y < minY then minY = y end
			if y > maxY then maxY = y end
		end
	end

	-- 3. AABB collision with screen rect

	local w, h = camera.ViewportSize.X, camera.ViewportSize.Y

	return minX < w and maxX > 0 and minY < h and maxY > 0
end
script.Parent.MouseButton1Click:Connect(function()
	local s = script.Sky:Clone()
	s.Parent = script.Parent.Parent.Frame
	local vpf = s.ViewportFrame
	local cam = Instance.new("Camera")
	cam.CFrame = workspace.CurrentCamera.CFrame
	cam.Parent = vpf
	vpf.CurrentCamera = cam
	local scene = Instance.new("Model")
	scene.Name = "Scene"
	scene.Parent = vpf
	for i,v in pairs(workspace:GetDescendants()) do
		if (v:IsA("Part") or v:IsA("BasePart") or v:IsA("MeshPart") or v:IsA("UnionOperation")) and v.Name ~= game.Players.LocalPlayer.Name then
			if not table.find(ignore,v.ClassName) then
				local touch = OnScreen(cam,v)
				if touch then
					v:Clone().Parent = scene
				end
			end
		end
		if v.Name == game.Players.LocalPlayer.Name then
			local model = Instance.new("Model")
			model.Name = v.Name
			model.Parent = vpf
			for i,v in pairs(v:GetChildren()) do 
				v:Clone().Parent = model
			end
			model:FindFirstChild("Humanoid").DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None
		end
	end
end)

I’m not sure, could you elaborate on the problem a bit?

so i have two trees in my camera area and if i take a screenshot using my in-game camera sometimes only one tree shows up thats the problem if you want a vid ill send

robloxapp-20210716-2134449.wmv (294.4 KB)

as you can see my camera sees the whole trees but the pics only shows half of those trees

That kinda looks right to me, it’s just that your viewport frame is a shorter aspect ratio than your game screen.

if you think the aspect ratio is the problem how do i fix it?
but i dont think its the aspect ratio problem ill send a vid that shows the problem more clearly

robloxapp-20210716-2140003.wmv (2.3 MB)

you can see here the problem more clearly as the trees dont show always if you want i could send the camera gui model