portals can get complex, especially entering them. the easiest is most likely drei/portal. a first rough scaffold of the website you linked could be done in a few minutes.
if you want this in vanilla it can only be done with a shader. it’s not enough to render a scene into a webglrendertarget using the same camera and project it onto a plane, that would skew it when you turn the camera. the plane has to act as a mask into the virtual scene instead.
const PortalMaterialImpl = shaderMaterial(
{ map: null, resolution: new THREE.Vector2() },
`varying vec2 vUv;
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
vUv = uv;
}`,
`uniform sampler2D map;
uniform vec2 resolution;
varying vec2 vUv;
void main() {
vec2 uv = gl_FragCoord.xy / resolution.xy;
gl_FragColor = texture2D(map, uv);
#include <tonemapping_fragment>
#include <colorspace_fragment>
}`
)
as for entering, drei/portal uses a propperty “blend”. if it’s > 0 it renders the main scene and the portal as a mix until it reaches 1 and then it only renders the portal fullscreen, without needing to project it.