A few bugs i need help with for my raytracer

Hello, I have been scratching my head for the past 3 hours making a raytracer.
What I have so far technically “works” but there is a few issues with it.

The size of the screen, or rather the area it covers is very small and I do not know how to change the size, it also always points torwards the center of the world, which I know why is happening but I don’t know the fix for it.

here is a video demonstrating these issues:


note: despite me having my camera turned torwards spawn, it DOES raytrace in that direction even if i dont have it pointed there, the resolution also does not matter, as the area it traces stays the same size regardless of the resolution

and here is the script:

local Players = game:GetService("Players")
local AssetService = game:GetService("AssetService")

local fps = 3
local resX = 16
local resY = 16

local FrameTime = 1 / fps
local res = Vector2.new(resX, resY)
local ImageAspectRatio = resX/resY

print(ImageAspectRatio)

local player = Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local mouse = player:GetMouse()
local camera = workspace.CurrentCamera

local PlayerGui = player.PlayerGui
local Viewport = PlayerGui.Viewport
local ScreenBacking = Viewport.ScreenBacking
local Screen = ScreenBacking.Screen
local ErrorText = ScreenBacking.ErrorText

ErrorText.Visible = false
Viewport.Enabled = true

local DisplayImage = AssetService:CreateEditableImage({Size = res})
Screen.ImageContent = Content.fromObject(DisplayImage)

local PixelBuffer = buffer.create(DisplayImage.Size.X * DisplayImage.Size.Y * 4)

local RayParams = RaycastParams.new()
RayParams.FilterType = Enum.RaycastFilterType.Exclude
RayParams.FilterDescendantsInstances = {workspace.Rays, char.HumanoidRootPart}

while task.wait(FrameTime) do
	
	for i = 1, DisplayImage.Size.X * DisplayImage.Size.Y do
		local pixelIndex = (i - 1) * 4
		
		--logic
		local pixelX = -((i - 1) % DisplayImage.Size.Y)
		local pixelY = -(math.floor((i - 1) / DisplayImage.Size.Y))
		
		local pixelNDCX = (pixelX + 0.5) / DisplayImage.Size.X
		local pixelNDCY = (pixelY + 0.5) / DisplayImage.Size.Y
		
		local pixelScreenX = 2 * pixelNDCX - 1
		local pixelScreenY = 1 - 2 * pixelNDCY
		
		local pX = (2 * pixelScreenX - 1) * ImageAspectRatio
		local pY = (1 - 2 * pixelScreenY)
		
		local cameraFovX = math.tan(math.rad(camera.FieldOfView) / 2)
		local cameraFovY = math.tan(math.rad(camera.FieldOfView) / 2)
		
		pX = (pX * cameraFovX)
		pY = (pY * cameraFovY)
		
		local RayOrigin = camera.CFrame.Position
		local RayDirection = Vector3.new(pX, pY, 0) - RayOrigin
		
		local m = RayDirection.Magnitude
		RayDirection = RayDirection / Vector3.new(m,m,m)
		
		local ray = workspace:Raycast(RayOrigin, RayDirection * 500, RayParams)
		
		local R,G,B = 255,255,255
		
		if ray then
			R,G,B = ray.Instance.Color.R*255, ray.Instance.Color.G*255, ray.Instance.Color.B*255
			
			local part = Instance.new("Part")
			part.Position = ray.Position
			part.Size = Vector3.new(0.2, 0.2, 0.2)
			part.Anchored = true
			part.CanCollide = false
			part.Parent = workspace.Rays
		end
		
		--write
		buffer.writeu8(PixelBuffer, pixelIndex, R)
		buffer.writeu8(PixelBuffer, pixelIndex+1, G)
		buffer.writeu8(PixelBuffer, pixelIndex+2, B)
		buffer.writeu8(PixelBuffer, pixelIndex+3, 255)
	end
	
	DisplayImage:WritePixelsBuffer(Vector2.zero, DisplayImage.Size, PixelBuffer)
end

if any of you could help, it would mean a lot! thanks

not dividing the fov by 2 helped a bit, heres the results