Re-Creating a Portal Effect,

I don’t think it’s possible for us to do it at all. I think the only hope for viewport lighting is if or when Roblox decides to add it, unfortunately. Theres still hope yet.

They probably won’t, since viewport frames were designed to show models and not the entire world. The only hope is if they will add “CameraViewFrame”.

2 Likes

OMG. This is my first time looking at this discussion, but this specific video on this post is so cool!

I like how the sky changes color. It’s like you entered a alternate reality.

1 Like

It’s Tardis!!

Fr, this would be cool for a Backrooms Game.

Hi,
It’s 2024 and I was hoping to make an easy-to-configure system that would allow the creation of multiple pairs of linked portals.
Is there already something similar done or a good starting point you know of?

For people wondering I was considering starting from [this].(Teleportation portal demo - Roblox)
Thanks :slight_smile:

4 Likes

What do you mean by linked ? Like they teleport sequentially? Or what is different ?

I assume they mean like instead of having one pair of portals in the game, they can make as many portals in the game as they want and link different portals together as they wish. If you play minecraft think of it as minecraft nether portals.

How does it determine what portal u get teleported to ?

Like you could just add to the script a table of available positions to teleport to or it choose where to go in a loop or whatever

Presumably you register both portals as a pair and the script transports you to the linked one when you pass through? Definitely not a random one because you can see through it to the other side.

2 Likes

This reply is semi related
When i opened the teleportation portal demo everything turned black! D: i think its cuz of memory full cuz i had a lot of tabs open. It didnt happen next time i opened it! :‍D
anyways i might use this teleportation portal in a game

1 Like

I am trying to make something like this on my own and I’m wondering how you only show the area that overlaps the portal from the viewport camera like shown here

1 Like

Would it be possible to make the portals work properly if I had a cube with portals on all sides?

I saw this one person showcase this exact thing I’m trying to do but I have no idea how they’ve done it and the creator hasn’t published it since when it was posted 2 years ago.

Using this demo I tried modifying the code so I could easily add multiple portals but it seems that the image doesn’t completely align. This is what it looks like:

Any ideas how to make this work?

2 Likes

Hi - I have been visiting this post for a while now, and it appears to still have a little bit of attention.
I’d like to address an issue that nobody seems to have brought up, or shrugged off recently,
that being that the portal doesn’t show lighting through it at all.
This is something really important depending on most of the portal’s uses, like horror game smooth transitions, shadows would be extremely important. If anybody thinks that they can come up with a solution to this, please either reply to this or message me via my DevForum profile.
Thanks.

2 Likes

Due to the nature of the way this is made, most lighting will not look identical to the real workspace, which is just a byproduct of using viewportframes.

Other methods would be actually cloning and moving objects behind the portal in real time, but that sounds QUITE laggy.

The best you can do is edit the lighting properties inside the viewportframe to align with the real lighting as much as possible. Until Roblox provides better lighting for them, or another method of displaying it, it still does have its limitations.

If you want to use it for something like a horror game, an easier approach is to just not use the viewportframe and have it be an invisible teleport, maybe using identical terrain around each portal so it looks seamless. The actual teleportation ignoring the viewportframe is still very smooth.

I did this as much as possible, but there was still a noticeable difference, like shadows not existing at all in the portal view

Thanks, I can edit it keeping this in mind.

What if you use some really complicated equation to figure out where the lighting is coming from and mirror that to an invisible part which creates the same shadow

2 Likes

I’ve been working on a way to create multiple portals with that system. I think you can understand how to make multiple ones by comparing this one I made with the one already provided in the demo. Basically, it just links portals like “Portal A to B,” “Portal C to D,” and you can keep going and make more. I’ve even developed a system that only shows the nearest pair of portals, but for now, it still needs some fixes, so I won’t post that.

Remember to make Portal C and D inside the “Portals” model for it to work.

local Players = game:GetService("Players")
local Lighting = game:GetService("Lighting")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Portal = require(ReplicatedStorage.Portal)

-- Define all four portals
local portalA = Portal.FromPart(workspace.World, workspace.Portals.PortalA, Enum.NormalId.Front)
local portalB = Portal.FromPart(workspace.World, workspace.Portals.PortalB, Enum.NormalId.Front)
local portalC = Portal.FromPart(workspace.World, workspace.Portals.PortalC, Enum.NormalId.Front)
local portalD = Portal.FromPart(workspace.World, workspace.Portals.PortalD, Enum.NormalId.Front)

-- Add skyboxes for all portals
portalA:AddSkybox(portalB:GetPart().Sky)
portalB:AddSkybox(portalA:GetPart().Sky)
portalC:AddSkybox(portalD:GetPart().Sky)
portalD:AddSkybox(portalC:GetPart().Sky)

-- Link portals in pairs (A-B and C-D)
portalA:Link(portalB)
portalB:Link(portalA)
portalC:Link(portalD)
portalD:Link(portalC)

-- World rendering and camera pass-through
local characterPortalSide = portalA
local prevPortalSide = characterPortalSide

local currentSkybox = characterPortalSide:GetPart().Sky:Clone()
currentSkybox.Parent = Lighting

local prevCamCF = workspace.CurrentCamera.CFrame
local prevCamFocus = workspace.CurrentCamera.Focus

RunService:BindToRenderStep("BeforeInput", Enum.RenderPriority.Input.Value - 1, function()
	workspace.CurrentCamera.CFrame = prevCamCF
	workspace.CurrentCamera.Focus = prevCamFocus
end)

RunService.RenderStepped:Connect(function(dt)
	local successTeleA = portalA:AttemptTeleport()
	local successTeleB = portalB:AttemptTeleport()
	local successTeleC = portalC:AttemptTeleport()
	local successTeleD = portalD:AttemptTeleport()
	
	if characterPortalSide == portalA and successTeleA then
		characterPortalSide = portalB
	elseif characterPortalSide == portalB and successTeleB then
		characterPortalSide = portalA
	elseif characterPortalSide == portalC and successTeleC then
		characterPortalSide = portalD
	elseif characterPortalSide == portalD and successTeleD then
		characterPortalSide = portalC
	end
	
	prevCamCF = workspace.CurrentCamera.CFrame
	prevCamFocus = workspace.CurrentCamera.Focus
	
	local cameraPortalSide = characterPortalSide
	
	for _, portal in pairs({portalA, portalB, portalC, portalD}) do
		local surfaceCF, surfaceSize = portal:GetSurface()
		local lp = surfaceCF:PointToObjectSpace(prevCamCF.Position)
		
		if lp.Z < 0.15 then
			continue
		end
		
		local success, cframe, focus = portal:GetCameraPassThrough()

		if success then	
			workspace.CurrentCamera.CFrame = cframe
			workspace.CurrentCamera.Focus = focus
			cameraPortalSide = portal:GetLinked()
			break
		end
	end
	
	-- Step characters and render for all portals
	portalA:StepCharacters()
	portalB:StepCharacters()
	portalC:StepCharacters()
	portalD:StepCharacters()
	
	portalA:Render()
	portalB:Render()
	portalC:Render()
	portalD:Render()
	
	if prevPortalSide ~= cameraPortalSide then
		currentSkybox:Destroy()
		currentSkybox = cameraPortalSide:GetPart().Sky:Clone()
		currentSkybox.Parent = Lighting
	end
	
	prevPortalSide = cameraPortalSide
end)

-- Physics step for all portals
local wasTouchingA = false
local wasTouchingB = false
local wasTouchingC = false
local wasTouchingD = false

RunService.Heartbeat:Connect(function()
	wasTouchingA = portalA:PhysicsStep(wasTouchingA)
	wasTouchingB = portalB:PhysicsStep(wasTouchingB)
	wasTouchingC = portalC:PhysicsStep(wasTouchingC)
	wasTouchingD = portalD:PhysicsStep(wasTouchingD)
	
	if not wasTouchingA and not wasTouchingB and not wasTouchingC and not wasTouchingD then
		portalA:SetTouching(false)
		portalB:SetTouching(false)
		portalC:SetTouching(false)
		portalD:SetTouching(false)
	else
		portalA:SetTouching(true)
		portalB:SetTouching(true)
		portalC:SetTouching(true)
		portalD:SetTouching(true)
	end
end)

-- Character rendering for all portals
local function onCharacterAdded(player, character)
	local cleanupA = portalA:WatchCharacter(player.Character)
	local cleanupB = portalB:WatchCharacter(player.Character)
	local cleanupC = portalC:WatchCharacter(player.Character)
	local cleanupD = portalD:WatchCharacter(player.Character)
	player.CharacterRemoving:Wait()
	cleanupA:Sweep()
	cleanupB:Sweep()
	cleanupC:Sweep()
	cleanupD:Sweep()
end

for _, player in pairs(Players:GetPlayers()) do
	if player.Character then
		task.spawn(onCharacterAdded, player, player.Character)
	end
	
	player.CharacterAdded:Connect(function(character)
		onCharacterAdded(player, character)
	end)
end

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		onCharacterAdded(player, character)
	end)
end)

I’d suggest to not make to many portals close to eachother :smile:

3 Likes

Hey pal, as I was looking for images for Non Euclidian reference portals for Roblox games to use as a presentation tool. I just want to know where you got that image, that looks hella classic

If you’re saying the image looks old, then remember that this topic is old - 2019 old. That post was from 2019.

1 Like