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