So, I am trying to make a Wolfenstein-styled 2D Raycasting Renderer, but I am having issues with visuals.
The obvious issue is distortion. Some examples are below:
Side of a wall
Corner of a block
Does anyone know how to fix this?
Help will be greatly appreciated as always!
Raycast project.rbxl (32.9 KB)
local Gui = script.Parent
local MainFrame = Gui:WaitForChild("MainFrame")
local Canvas = MainFrame:WaitForChild("Canvas") -- Our container for the frames
local RS = game:GetService("RunService")
local CameraPart = workspace:WaitForChild("CameraPart") -- The player
local LevelWorkspace = workspace:WaitForChild("LevelWorkspace") -- The 2D map
local RenderDistance = 100
local FieldOfView = 170
local ViewDistance = 30 -- Fog?
local Resolution = 100 -- the columns. Can run up to 60FPS from 0-200 frames/columns
local function GenerateFrames() -- Creates all the frames that will be used
for i = 1, Resolution do
local Frame = Instance.new("Frame")
Frame.LayoutOrder = i
Frame.Name = "Frame" .. i
Frame.BorderSizePixel = 0
Frame.Size = UDim2.fromScale(1/Resolution, 1)
Frame.Parent = Canvas
end
end
local function ClearCanvas() -- Clears any old frames
for i, Frame in ipairs(Canvas:GetChildren()) do
if Frame:IsA("GuiObject") then
Frame:Destroy()
end
end
end
local function UpdateFrames() -- Renders the picture
local Count = -Resolution/2
for i, Frame in ipairs(Canvas:GetChildren()) do
if Frame:IsA("GuiObject") then
local Params = RaycastParams.new()
Params.FilterType = Enum.RaycastFilterType.Whitelist
Params.FilterDescendantsInstances = LevelWorkspace:GetChildren()
local ViewRayOrigin = CameraPart.CFrame.Position
local ViewRayDirection = (CameraPart.CFrame * CFrame.new((Count * FieldOfView) / Resolution, 0, -RenderDistance)).Position
local ViewRay = workspace:Raycast(ViewRayOrigin, ViewRayDirection, Params)
if ViewRay and ViewRay.Instance and ViewRay.Instance:IsA("BasePart") then
--print(ViewRay.Instance)
--print(ViewRay.Position)
--print(Count)
local Distance = (ViewRayOrigin - ViewRay.Position).Magnitude
Frame.BackgroundColor3 = ViewRay.Instance.Color
Frame.BackgroundTransparency = 1 * (Distance / ViewDistance)
Frame.Size = UDim2.fromScale(1 / Resolution, 1 / Distance)
--local DebugLaser = Instance.new("Part") -- Useful for visualizing the rays
--DebugLaser.Anchored = true
--DebugLaser.Size = Vector3.new(0.2, 0.2, Distance)
--DebugLaser.CFrame = CFrame.new(ViewRayOrigin, ViewRay.Position) * CFrame.new(0, 0, -Distance/2)
--DebugLaser.Parent = workspace
Count = Count + 1
end
end
end
end
ClearCanvas()
GenerateFrames()
UpdateFrames()
CameraPart.Changed:Connect(UpdateFrames) -- Render the picture when the player moves (not good if your world has moving objects)
--RS.RenderStepped:Connect(function() -- Always render the picture
--UpdateFrames()
--end)