Ray Tracing with reflection and godray

Hi , heres a ray tracing script that is NOT made by me, I just fixed it and add non crashing loading
It still crash when studio close though, The script is made is originally made by oysi
1
2
3
4
It can somewhat handle 40,000 pixel and does well at 3600 pixel

2 Likes

Can you send a link to the script? And instructions on how to add it?

Im not free to send rn but heres the old model,Oysi's Raytracing camera - Roblox

2 Likes

How did you run 3,600 pixels? when i was using this script long ago it didn’t work, script would say same issue with mine rtx, “exhausted time”, even with while wait() do, wait(1)

1 Like

Idk, Im just taking their script and added Part check + Slower loading and swab out the FindPartOnRay, Ill post when im free,Also what i meant was it is able to run 60 by 60 in realtime

1 Like

Heres Oysi Raytracing fixed - Roblox, If it errors then send me the error

1 Like

Okay wait (asdadkjwkejqwqieuqwieu)

So, here, i add workspace.part.shape, because just part.shape.name doesn’t work
Screenshot 2022-04-29 at 10.24.44

Screenshot 2022-04-29 at 10.24.57

-- Script made by Oysi

wait(1)

-- Player declarations
local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera
local char
local w = game.Workspace
-- Get character
repeat char = player.Character wait(1/30) until char

-- Path declarations
local dev = script.Parent
	local render = dev.screen.render
	local settings = dev.settings

-- Rendering declarations
local pixels
local screen
local sctemp
local res

local fps = 0

	-- Setup display
	function setupDisplay()
		render:ClearAllChildren()
		pixels = {}
		screen = {}
		sctemp = {}
		for x = 1, res do
			pixels[x] = {}
			screen[x] = {}
			sctemp[x] = {}
			for y = 1, res do
				local pixel = Instance.new("Frame")
				pixel.BackgroundColor3 = Color3.new(50/255, 100/255, 150/255)
				pixel.BackgroundTransparency = 0
				pixel.BorderSizePixel = 0
				pixel.Size = UDim2.new(1/res, 0, 1/res, 0)
				pixel.Position = UDim2.new((x - 1)/res, 0, (y - 1)/res, 0)
				pixel.ZIndex = 2
				pixel.Parent = render
				pixels[x][y] = pixel
				screen[x][y] = {r = 0, g = 0, b = 0, h = false, d = nil}
				sctemp[x][y] = {r = 0, g = 0, b = 0, h = false, d = nil}
			end
		end
	end

	-- Ray cast
	function rayCast(pos, dir, ignore)
		return workspace:FindPartOnRay(Ray.new(pos, dir), ignore)
	end

	-- Get normal
function getNormal(part, pos)
	if w.Part.Shape.Name == "Block" then
		local dif = part.CFrame:pointToObjectSpace(pos) / part.Size
		local rot = part.CFrame - part.CFrame.p
		if     dif.x < -0.4999 then return rot * Vector3.new(-1, 0, 0)
		elseif dif.x >  0.4999 then return rot * Vector3.new( 1, 0, 0)
		elseif dif.y < -0.4999 then return rot * Vector3.new(0, -1, 0)
		elseif dif.y >  0.4999 then return rot * Vector3.new(0,  1, 0)
		elseif dif.z < 	0.4999 then return rot * Vector3.new(0, 0, -1)
		elseif dif.z > 0.4999 then return rot * Vector3.new(0, 0,  1)
		else                        return       Vector3.new(0, 1,  0)
		end
	elseif w.Part.Shape.Name == "Ball" then
		return (pos - part.Position).unit
	end
end

	-- Do wait
	local lastWait = tick()
	function doWait()
		if tick() - lastWait > 1/30 then
			wait(1/30)
			lastWait = tick()
		end
	end

-- Ray trace
function rayTrace(pos0, dir, ignore, numRays)
	local hit, pos = rayCast(pos0, dir*settings.display.rayLength.Value, ignore)
	local r, g, b = 0, 0, 0

	-- Hit
	if hit then
		local N = getNormal(hit, pos)		
		
		-- SUN SHADER
		local S = N:Dot(game.Lighting:GetSunDirection())
		
		-- Is facing sun
		if S > 0 then
			local lit = true
			
			-- Shadows
			if settings.shading.shadows.Value == 1 then
				if rayCast(pos, game.Lighting:GetSunDirection()*settings.display.rayLength.Value, hit) then
					lit = false
				end
			end
			
			-- Diffuse shading
			if settings.shading.diffuse.Value == 1 and lit then
				r = r + hit.Color.r*S
				g = g + hit.Color.g*S
				b = b + hit.Color.b*S
			end
			
			-- Specular shading
			if settings.shading.specular.Value == 1 and lit then
				local R = dir - 2*N*dir:Dot(N)
				local spec = R:Dot(game.Lighting:GetSunDirection())
				if spec > 0 then
					spec = spec^settings.shading.specular.power.Value
					spec = spec*settings.shading.specular.intensity.Value/100
					r = r + spec
					g = g + spec
					b = b + spec
				end
			end
		end
		
		-- Ambient shading
		if settings.shading.ambient.Value == 1 then
			r = math.max(r, hit.Color.r*0.3)
			g = math.max(g, hit.Color.g*0.3)
			b = math.max(b, hit.Color.b*0.3)
		end
		
		-- Reflection
		if hit.Reflectance > 0 and numRays < settings.display.maxRays.Value then
			local R = dir - 2*N*dir:Dot(N)
			
			local r2, g2, b2, h2, d2 = rayTrace(pos + R*0.01, R, ignore, numRays + 1)
			
			r = r*(1 - hit.Reflectance) + r2*hit.Reflectance
			g = g*(1 - hit.Reflectance) + g2*hit.Reflectance
			b = b*(1 - hit.Reflectance) + b2*hit.Reflectance
		end
	else
		-- Sky
		r = r + 100/255
		g = g + 175/255
		b = b + 250/255
	end

	return r, g, b, hit ~= nil, dir
end

-- Rendering
while true do
	-- Realtime resolution change
	if res ~= settings.display.res.Value then
		res = settings.display.res.Value
		setupDisplay()
	end

	-- Declarations
	local ignore = (camera.CoordinateFrame.p - camera.Focus.p).magnitude < 1 and char or nil
	local frame0 = camera.CoordinateFrame
	local pos0 = frame0.p
	local start = tick()

	-- FoV depth
	local depth = 1/math.tan(math.rad(settings.display.fov.Value)/2)

	-- Cast rays
	for x = 1, res do
		for y = 1, res do
			local xPos = 2*(x - 1)/(res - 1) - 1
			local yPos = 2*(y - 1)/(res - 1) - 1

			-- Cast ray
			local pos1 = frame0 * Vector3.new(xPos, -yPos, -depth)
			local r, g, b, h, d = rayTrace(pos0, (pos1 - pos0).unit, ignore, 1)

			-- Update screen data
			local s = screen[x][y]
			s.r = r s.g = g s.b = b s.h = h s.d = d
			
			-- Update temp data
			local t = sctemp[x][y]
			t.r = r t.g = g t.b = b t.h = h t.d = d

			doWait()
		end
	end
	
	-- Pixel shaders
		
		-- Sun shader
		for x = 1, res do
			for y = 1, res do
				local s = screen[x][y]
				if not s.h then
					local sun = s.d:Dot(game.Lighting:GetSunDirection())
					if sun > 0 then
						sun = sun^50
						s.r = s.r + sun*253/255
						s.g = s.g + sun*184/255
						s.b = s.b + sun*019/255
					end
				end
			end
		end
		
		-- Update temp
		for x = 1, res do
			for y = 1, res do
				local s = screen[x][y]
				local t = sctemp[x][y]
				t.r = s.r t.g = s.g t.b = s.b
			end
		end

		-- Get sun position
		local dif = frame0:pointToObjectSpace(frame0.p + game.Lighting:GetSunDirection()*999)
		local px = dif.x / -dif.z * depth
		local py = dif.y /  dif.z * depth
		local sx = math.floor((px + 1)/2 * res + 0.5)
		local sy = math.floor((py + 1)/2 * res + 0.5)
		
		-- God rays
		if settings.shaders.godRays.Value == 1 and dif.z < 0 then
			local samples = settings.shaders.godRays.samples.Value
			local density = settings.shaders.godRays.density.Value/100
			local weight = settings.shaders.godRays.weight.Value/100 * frame0.lookVector:Dot(game.Lighting:GetSunDirection())
			local decay = settings.shaders.godRays.decay.Value/100
			local hit = settings.shaders.godRays.hit.Value/100
			local sky = settings.shaders.godRays.sky.Value/100
			for x = 1, res do
				for y = 1, res do
					local s = screen[x][y]
					local xd = (x - sx)/samples * density
					local yd = (y - sy)/samples * density
					local illuminationDecay = 1
					for i = 1, samples do
						local nx = math.floor(x - xd*i + 0.5)
						local ny = math.floor(y - yd*i + 0.5)
						if nx >= 1 and nx <= res and ny >= 1 and ny <= res then
							local o = sctemp[nx][ny]
							local c = o.h and hit or sky
							local factor = illuminationDecay * weight
							s.r = s.r + o.r*c*factor*253/255
							s.g = s.g + o.g*c*factor*184/255
							s.b = s.b + o.b*c*factor*019/255
							illuminationDecay = illuminationDecay * decay
						else
							break
						end
					end
					doWait()
				end
			end
		end

	-- Display image
	for x = 1, res do
		for y = 1, res do
			local s = screen[x][y]
			pixels[x][y].BackgroundColor3 = Color3.new(
				math.min(math.max(s.r, 0), 1),
				math.min(math.max(s.g, 0), 1),
				math.min(math.max(s.b, 0), 1)
			)
		end
	end

	-- Calculate fps
	fps = fps + (1/(tick() - start) - fps)/math.max(fps, 2)
	dev.screen.fps.Text = "Fps: " .. math.floor(fps*10 + 0.5)/10
end

Ill help you at 4:00 bkk time chars chars

16:00? I will wait, thanks :grinning: (11111212312312)

From what I’ve seen you are using the old one which uses findpartonray, You should replace it with this one

If it still crash i suggest lowering the resolution to 60, I used it at 200 for texting purposes, Also itll load longer than Oysi as that prevented crashing

1 Like

God, thanks, it’s now works, i can now take some cool photos :smiley:

1 Like

Roblox Studio crashed when leaving game xD

You could try on a more powerful pc though. Havent tryed on my new pc.

  • AMD Ryzen 3 Pro
  • 16GB RAM
  • 256GB SSD
  • AMD integrated graphics
  • Gigabit Ethernet

How could it be not enough?

Probably integrated graphics (mine doesn’t crash, but my old mac does ) mine is
AMD Ryzen 9 5900X
16GB RAM
RTX 3060 12 GB
500 GB SSD and a 2 TB hard drive
Idk for internet