Making bullet tracer "motion-blur" look smooth

I have checked some posts about achieving a motion blur effect with bullet tracers, from what I have seen, it involves the manipulation of Bezier curves/beam curves and bullet position relative to the camera a frame earlier.

The issue is that I am not properly manipulating the beams, as the result does not look properly smoothed like what I want to achieve, the issue is not with the handler itself (not setting bezier curve positions or knowing where the bullet is) but how the math is done.

Intended result (Looks more natural, smoothed out, not weird):

Actual result (Weird zig-zag curves or too linear):
image

The code

local setCurveP1 = function(beam, pos)
	local vel = (pos-beam.Attachment0.WorldPosition)
	if vel.Magnitude ~= 0 then
		beam.Attachment0.WorldAxis = vel.Unit
	else
		beam.Attachment0.WorldAxis = Vector3.yAxis
	end
	beam.CurveSize0 = vel.Magnitude
end

local setCurveP2 = function(beam, pos)
	local vel = (pos-beam.Attachment1.WorldPosition)
	if vel.Magnitude ~= 0 then
		beam.Attachment1.WorldAxis = -vel.Unit
	else
		beam.Attachment1.WorldAxis = -Vector3.yAxis
	end
	beam.CurveSize1 = vel.Magnitude
end

game:GetService("RunService").Heartbeat:Connect(function(Step)
	for _, Data in list do --for every bullet
		local Beam = data[1] --beam object

		local OldPosition = Data[2]
		local OldVelocity = Data[3]
		local NewPosition = Data[4]
		local NewVelocity = Data[5]

		Beam.Attachment0.WorldPosition = Camera.CFrame:PointToWorldSpace(
			PreviousCameraCFrame:PointToObjectSpace(OldPosition)
		) --previous position relative to current camera
		Beam.Attachment1.WorldPosition = NewPosition
		
		local TranslatedOldVelocity = Camera.CFrame:PointToWorldSpace(
			PreviousCameraCFrame:PointToObjectSpace(OldVelocity)
		) --previous velocity relative to current camera
		
		setCurveP1(Beam, Beam.Attachment0.WorldPosition + TranslatedOldVelocity*Step)
		setCurveP2(Beam, Beam.Attachment1.WorldPosition - NewVelocity*Step)
		--these two set the bezier curves of the beam so it is not a relevant function
		--math for these functions were obtained from the roblox docs related to beams
		
		Data[3] = NewVelocity
		Data[2] = NewPosition
	end
	
	PreviousCameraCFrame = Camera.CFrame
end)

I can’t seem to find a solution to what I could be doing wrong, I am mainly seeking for a better way to properly replicate a bullet tracer effect with motion blur.

1 Like