Excellent. As any softawre enginerr fan of portal I also did it using a cusom engine. I had same problems but there was no tutorial in the past. The rule was to use the computation between the entrance speed and camera orientation with the entrance normal and use this to modify the speed vector and the camera orientation using the exit normal. I don't know if you used this method but as I remember that worked for me 😂. But it was a long time ago lol. Thx for the video
you can fix the portals by not applying the tonemapper to the portal surface. you see, when you use viewports, the sight you see already has tonemapping on it, and applying it again causes this weird issue where the sight you see through the portal has this extra brightness added to it. omiting it makes all the difference
As a behinner that just started to experiment with the Engine I really liked that video ^^ And what really catched me at the end was David Tennant as the Doctor ❤
nicee i also have been trying to make portal in godot for some time, and my issue was clipping the camera's view so that it only renders things that are behind the portal, and not be "blocked" by the wall or things behind it, how did you fix that?
i enjoyed the devlog and would be up to watch more. i think this video is a perfect example of how literally anything that one might want to create themselves will think "oh this should be pretty easy ill just do this" and it works but then the realization hits that the thing is jank af and 90% of the time will go to polishing the thing so that it works properly. the gamedev struggle 😂
Haha, so true! Thanks for the nice comment, I'm glad you liked the video, and I'm definitely listing a few other ideas for projects, demos, devlogs, features, etc :)
Haven't gotten to look at your source code yet, but I notived that your portals are likely rendering the tonemapping twice, which leads to the colors being brighter in the portal then suddenly jumping back when you go through it. To fix this, you can override the world environment of the Portal camera to have its tone-mapping set to Linear. Overall, neat project though! I'm definitely gonna check out the source code.
Thanks for the nice and interesting comment! I completely agree, the luminosity change upon teleportation is one of the things I really want to fix when I get the time to work on a v2 - and thank you for your advice, I'll definitely look in that direction :) Cheers!
I just applied portal transformantions to a player's transform and velocity, everything was simple (it even worked with portals that has different sizes). I left code below. The main part of it is: func _physics_process(delta): if !otherside: process_mode = Node.PROCESS_MODE_DISABLED return for i in len(tp_check_list): var b = tp_check_list[i] if (b.global_position - global_position).dot(basis * Vector3(0,0,1)) < 0.0: var endpoint := otherside.global_transform endpoint.basis *= Basis(Vector3(-1,0,0),Vector3(0,1,0),Vector3(0,0,-1)) b.global_transform = endpoint * global_transform.inverse() * b.global_transform b.velocity = endpoint.basis * global_transform.basis.inverse() * b.velocity tp_check_list.remove_at(i)
There's definitely a lot of ways I could improve/change the portals visuals to match various styles... I'm pretty happy with how I managed to recreate Portal's effect so far, but I could totally make it better ;)
Heya! Basically, I ended up chopping the process in really granular steps and, in particular, I first apply a basic transform that still has the problem shown at 04:06, but then I reapply some reverse operations to "tilt the head back up" and put my entire character in the right direction. If you're curious about the details of this tutorial and other game remakes or tutorials, you can check out my Patreon memberships over here: www.patreon.com/minapecheux ;) Hope it helps a bit, cheers!
@@minapecheux I have not tried the character rotation yet, but to rotate the portal camera in sync with the player's camera relative to the rotation of both portals it is possible to use: transform = this_portal.transform * other_portal.transform.affine_inverse() * player_camera.global_transform I wonder if anyone else found this concise solution
You know what's hilarious? for the past couple of weeks, i've had the same idea of making portal 3. I *also* wanted to put it on TH-cam, and i *also* wanted to do it in Godot! I know french, which im not sure if you do or not, im just assuming because of the french last name (doesnt have to do with game dev but its another similarity). THE COINCIDENCE.
I think it would be useful to remove the current player controller, work on it as if there was no gravity (like a flight simulator) and then make a new player controller that could have a custom gravity vector. Then if the gravity vectors don't match when crossing, you can interpolate between them to point the character downwards smoothly.
That's a really interesting idea! I don't know how easy the interpolating-to-normal state switch would be, but that's definitely something worth exploring... for now, my FPS character is sort of "cancelled" for a while after coming out of a portal, until I collide with something, but I'm not sure that's the best approach, so I'm absolutely writing down your idea in the back of my head for (hopefully!) future reworks :) Thanks!
Maybe they have an identical room copy somewhere and rotate that room accordingly when the portal is created and then orientate it upright slowly. Then the original room becomes the 2nd room. Just spit balling crazy ideas. Anywayz, Portal 3 when?
Haha no worries - Portal's physics is... well pretty mind-reversing ^^ And think there are definitely some features that work with a copy (for example pushing objects through the portals, so that you can get the "mirrored" copy on the other side)! For the rooms though I think it wouldn't work... But I'm glad you're interested in the project, and thanks for the comment! :)
Speaking of which, is there an equivalent to replacement shader from unity in Godot? Ie render a whole scene with a single shader instead of per material, for effect like night goggles 🥽?
Mmh, as far as I know, there is a replacement shader system yet in Godot. Though if you want to make a global full-screen effect like that, you can use the custom post-processing feature (docs.godotengine.org/en/stable/tutorials/shaders/custom_postprocessing.html) :) I worked with it when I made Godot shaders for my Patreons, and it's pretty easy to work with: you just put a ColorRect above your scene with a custom material, and then you get the screen texture, and you're all set :) But yep, not exactly the same, so I don't know if that will solve your problem! Cheers :)
@@minapecheux oh thanks, sad, I rely on that so much... really I wanted to capture UV data in a viewport to get a custom cheap GI effect (uv mean any point of a custom lightmap buffer can reference another in the same lightmap)
Wow, looks like a cool plan/project! Note that I might not know everything about Godot shaders - perhaps you could leave a message in a Github thread? Somebody in the community may know more! :)
Heya! Yup - I used it for some recent Godot tutorials + the 1 minute tutorials :) (Although I don't necessarily agree with the philosophy and how all the data is fed to the algorithms... I have to admit it does save me a lot of time...)
Nice job! :D For further reference, this video also explains the inner workings of portal's portals in depths, if you're interested in other implementations th-cam.com/video/_SmPR5mvH7w/w-d-xo.html
Thanks, glad you liked it :) And thank you very much for the additional ref, too - I came across it but it wasn't as much a work basis as the others... still, totally worth mentioning! ;)
Awesome! It was cool to see you tackle this game dev challenge.
Thanks, I'm really glad you liked it! (and very happy I managed to get something half-decent ^^)
You are levelling up Mina, another amazing one!!!
Thank you so much! :D
great explanation ! Your devlogs are one of my favorites :)
Yay, thank you so much for the nice comment! I'm glad you find these videos interesting :)
This was great! Definitely this type of video
That’s pretty nice, good job and nice video!
Thanks! I'm glad you liked it :)
Well done! I have a game design that involves (simple) portals, so keen to see where you take this 👌
Thanks, glad you liked it! And good luck on your project ;)
This is a really really good explanation. I tried to do a similar thing some time ago and I now realize why it did not work😅.
Thanks for this content!
You're very welcome, thanks so much for the kind comment! :)
Excellent. As any softawre enginerr fan of portal I also did it using a cusom engine. I had same problems but there was no tutorial in the past. The rule was to use the computation between the entrance speed and camera orientation with the entrance normal and use this to modify the speed vector and the camera orientation using the exit normal. I don't know if you used this method but as I remember that worked for me 😂. But it was a long time ago lol. Thx for the video
Thanks for the kind comment, glad you liked the video!
Yup I did something similar all in all, with perhaps some shortcuts from Godot... ^^
you can fix the portals by not applying the tonemapper to the portal surface. you see, when you use viewports, the sight you see already has tonemapping on it, and applying it again causes this weird issue where the sight you see through the portal has this extra brightness added to it. omiting it makes all the difference
Heya, thanks a lot for the advice! That's definitely one of the key things I'd like to fix for a v2, as soon as I get a chance :)
Cheers!
As a behinner that just started to experiment with the Engine I really liked that video ^^
And what really catched me at the end was David Tennant as the Doctor ❤
I'm so glad you liked it, thanks for the nice comment! And yup - I thought if I could sneak in a Whovian reference... I had to :D
nicee i also have been trying to make portal in godot for some time, and my issue was clipping the camera's view so that it only renders things that are behind the portal, and not be "blocked" by the wall or things behind it, how did you fix that?
The perfect channel For Beginners 💔🙂
Thank you so much!! :)
i enjoyed the devlog and would be up to watch more. i think this video is a perfect example of how literally anything that one might want to create themselves will think "oh this should be pretty easy ill just do this" and it works but then the realization hits that the thing is jank af and 90% of the time will go to polishing the thing so that it works properly. the gamedev struggle 😂
Haha, so true! Thanks for the nice comment, I'm glad you liked the video, and I'm definitely listing a few other ideas for projects, demos, devlogs, features, etc :)
Спасибо! Твое видео очень помогло мне теперь я знаю как реализовать портал из портал!❤
Haven't gotten to look at your source code yet, but I notived that your portals are likely rendering the tonemapping twice, which leads to the colors being brighter in the portal then suddenly jumping back when you go through it.
To fix this, you can override the world environment of the Portal camera to have its tone-mapping set to Linear. Overall, neat project though! I'm definitely gonna check out the source code.
Thanks for the nice and interesting comment! I completely agree, the luminosity change upon teleportation is one of the things I really want to fix when I get the time to work on a v2 - and thank you for your advice, I'll definitely look in that direction :)
Cheers!
I just applied portal transformantions to a player's transform and velocity, everything was simple (it even worked with portals that has different sizes). I left code below. The main part of it is:
func _physics_process(delta):
if !otherside:
process_mode = Node.PROCESS_MODE_DISABLED
return
for i in len(tp_check_list):
var b = tp_check_list[i]
if (b.global_position - global_position).dot(basis * Vector3(0,0,1)) < 0.0:
var endpoint := otherside.global_transform
endpoint.basis *= Basis(Vector3(-1,0,0),Vector3(0,1,0),Vector3(0,0,-1))
b.global_transform = endpoint * global_transform.inverse() * b.global_transform
b.velocity = endpoint.basis * global_transform.basis.inverse() * b.velocity
tp_check_list.remove_at(i)
#@tool
extends Area3D
class_name Portal
@onready var cam := $SubViewport/Camera3D
@onready var woj : PGWorld
@onready var pcam : Camera3D
@export var otherside : Portal #may be lookin directly at other portal
var aps : bool = true
var tp_check_list := []
@export var hsize : Vector2 = Vector2(1,1) :
set(value):
hsize = value
$visual.mesh.size = hsize
$visual2.mesh.size = hsize
$teleport.shape.size = Vector3(hsize.x,hsize.y,1)
if otherside:
if aps:
otherside.aps = false
otherside.hsize = hsize
else:
aps = true
func _ready():
pcam = get_viewport().get_camera_3d()#woj.client.cam
#$SubViewport.size = floor(get_tree().get_root().get_viewport().size*0.5)
$visual.mesh.size = hsize
$visual2.mesh.size = hsize
$teleport.shape.size = Vector3(hsize.x,hsize.y,1)
pass # Replace with function body.
#disable processing on locations should optimize em
func _physics_process(delta):
if !otherside:
process_mode = Node.PROCESS_MODE_DISABLED
return
for i in len(tp_check_list):
var b = tp_check_list[i]
if (b.global_position - global_position).dot(basis * Vector3(0,0,1)) < 0.0:
var endpoint := otherside.global_transform
endpoint.basis *= Basis(Vector3(-1,0,0),Vector3(0,1,0),Vector3(0,0,-1))
b.global_transform = endpoint * global_transform.inverse() * b.global_transform
#b.scale = -b.scale
b.velocity = endpoint.basis * global_transform.basis.inverse() * b.velocity
tp_check_list.remove_at(i)
func _process(delta):
#camera effects and adjustments goes here
if !otherside:
#if !(Engine.editor_hint):
process_mode = Node.PROCESS_MODE_DISABLED
return
#$visual.visible = (pcam.global_position - global_position).dot(basis * Vector3(0,0,1)) > 0.0
if !($visual.visible):
$SubViewport.render_target_update_mode = SubViewport.UPDATE_DISABLED
return
else:
$SubViewport.render_target_update_mode = SubViewport.UPDATE_WHEN_VISIBLE
scale = Vector3(1,1,1)
var endpoint := otherside.global_transform
endpoint.basis *= Basis(Vector3(-1,0,0),Vector3(0,1,0),Vector3(0,0,-1))
cam.global_transform = endpoint * global_transform.inverse() * pcam.global_transform
cam.fov = pcam.fov
var relcp : Vector3 = pcam.global_position - global_position
#TODO: plane discard shader
#cam.near = clamp(relcp.distance_to(relcp.clamp($visual.get_aabb().position,$visual.get_aabb().end)),pcam.near,pcam.far)
pass
func _on_body_entered(body):
if body is PhysicsBody3D:
tp_check_list.append(body)
func _on_body_exited(body):
var b = tp_check_list.find(body)
if b != -1:
tp_check_list.remove_at(b)
You should tweak your shader settings or the portal camera settings to make the portals look more seemless
There's definitely a lot of ways I could improve/change the portals visuals to match various styles... I'm pretty happy with how I managed to recreate Portal's effect so far, but I could totally make it better ;)
@@minapecheux Soon the video "how to upgrade the portal of my top tiers portal video"? :D
@@woumGameDev Haha, I wish! :)
this is really cool
Thanks! :)
What transformation did you use to solve the problem of horizontal exit portals projecting incorrect view that you show at 4:06?
Heya! Basically, I ended up chopping the process in really granular steps and, in particular, I first apply a basic transform that still has the problem shown at 04:06, but then I reapply some reverse operations to "tilt the head back up" and put my entire character in the right direction.
If you're curious about the details of this tutorial and other game remakes or tutorials, you can check out my Patreon memberships over here: www.patreon.com/minapecheux ;)
Hope it helps a bit,
cheers!
@@minapecheux I have not tried the character rotation yet, but to rotate the portal camera in sync with the player's camera relative to the rotation of both portals it is possible to use:
transform = this_portal.transform * other_portal.transform.affine_inverse() * player_camera.global_transform
I wonder if anyone else found this concise solution
You know what's hilarious? for the past couple of weeks, i've had the same idea of making portal 3. I *also* wanted to put it on TH-cam, and i *also* wanted to do it in Godot! I know french, which im not sure if you do or not, im just assuming because of the french last name (doesnt have to do with game dev but its another similarity). THE COINCIDENCE.
Haha, indeed, what a coincidence! And yup, I'm French ;)
Good luck on your project(s) then :)
So Mina is working on Portal 3 confirmed :D
Haha, I wish! I think I'm nowhere near the real thing, but that would be so sick if Valve made a 3rd episode... (or perhaps "Portal Alyx" in VR? :D)
I think it would be useful to remove the current player controller, work on it as if there was no gravity (like a flight simulator) and then make a new player controller that could have a custom gravity vector. Then if the gravity vectors don't match when crossing, you can interpolate between them to point the character downwards smoothly.
That's a really interesting idea! I don't know how easy the interpolating-to-normal state switch would be, but that's definitely something worth exploring... for now, my FPS character is sort of "cancelled" for a while after coming out of a portal, until I collide with something, but I'm not sure that's the best approach, so I'm absolutely writing down your idea in the back of my head for (hopefully!) future reworks :)
Thanks!
Nice video
Thanks! :)
Maybe they have an identical room copy somewhere and rotate that room accordingly when the portal is created and then orientate it upright slowly. Then the original room becomes the 2nd room. Just spit balling crazy ideas. Anywayz, Portal 3 when?
Hm my idea is kinda bad. Just realized there are items not stuck on the walls. And items can also get thrown into the portal.
Haha no worries - Portal's physics is... well pretty mind-reversing ^^ And think there are definitely some features that work with a copy (for example pushing objects through the portals, so that you can get the "mirrored" copy on the other side)!
For the rooms though I think it wouldn't work...
But I'm glad you're interested in the project, and thanks for the comment! :)
Speaking of which, is there an equivalent to replacement shader from unity in Godot? Ie render a whole scene with a single shader instead of per material, for effect like night goggles 🥽?
Mmh, as far as I know, there is a replacement shader system yet in Godot. Though if you want to make a global full-screen effect like that, you can use the custom post-processing feature (docs.godotengine.org/en/stable/tutorials/shaders/custom_postprocessing.html) :)
I worked with it when I made Godot shaders for my Patreons, and it's pretty easy to work with: you just put a ColorRect above your scene with a custom material, and then you get the screen texture, and you're all set :)
But yep, not exactly the same,
so I don't know if that will solve your problem!
Cheers :)
@@minapecheux oh thanks, sad, I rely on that so much...
really I wanted to capture UV data in a viewport to get a custom cheap GI effect (uv mean any point of a custom lightmap buffer can reference another in the same lightmap)
Wow, looks like a cool plan/project! Note that I might not know everything about Godot shaders - perhaps you could leave a message in a Github thread? Somebody in the community may know more! :)
Did you use generative AI for some of your thumbnails?
Heya! Yup - I used it for some recent Godot tutorials + the 1 minute tutorials :)
(Although I don't necessarily agree with the philosophy and how all the data is fed to the algorithms... I have to admit it does save me a lot of time...)
@@minapecheux ah, I see. Thanks for your honesty.
Neat well done
Thanks! :)
love you
Super vidéo
Merci beaucoup ! :)
Great!!!!
Thanks :)
Wow! ❤
Nice job! :D
For further reference, this video also explains the inner workings of portal's portals in depths, if you're interested in other implementations
th-cam.com/video/_SmPR5mvH7w/w-d-xo.html
Thanks, glad you liked it :)
And thank you very much for the additional ref, too - I came across it but it wasn't as much a work basis as the others... still, totally worth mentioning! ;)
teleportation is horribly wrong.. just because you just teleporting player, but not passing trought it.
Très très forte
Merci beaucoup ! :D