从零实现传送门(Portal)系统:视图渲染与物理穿越Building a Portal System From Scratch: View Rendering and Physical Traversal
传送门看起来「魔法」,但拆开来是两个相对独立的问题:看起来能穿过去(渲染)和 真的能穿过去(物理)。
一、视图渲染
每个传送门是一块 quad,上面贴一张 RenderTexture。渲染这张贴图的虚拟相机由「主相机相对本门的变换」映射到「另一扇门」得到:
Matrix4x4 m = portalB.TransformMatrix
* flip180
* portalA.InverseTransformMatrix
* mainCamera.localToWorldMatrix;
virtualCam.transform.SetPositionAndRotation(m.GetPosition(), m.rotation);
关键:斜裁剪面 (oblique near-plane clipping) 要对齐目标门平面,否则会把门后的墙渲染进来穿帮。两扇门互相可见时会无限递归,需限制深度。
二、物理穿越
- 克隆体:物体开始进门时在另一扇门生成镜像;
- 过中点瞬移:质心越过门平面瞬间传送本体并交换速度方向;
- 速度重定向:出门速度按两门相对旋转重新投影。
设计收获
真正让项目拿奖的是用一个核心机制撑起整套关卡的克制 —— 每关只教一个新用法。
Portals split into two independent problems: looking like you can pass through (rendering) and actually passing through (physics).
1. View rendering
Each portal is a quad textured with a RenderTexture. The virtual camera is positioned by mapping "the main camera relative to this portal" onto "the other portal":
Matrix4x4 m = portalB.TransformMatrix
* flip180
* portalA.InverseTransformMatrix
* mainCamera.localToWorldMatrix;
virtualCam.transform.SetPositionAndRotation(m.GetPosition(), m.rotation);
Key: oblique near-plane clipping must align to the destination portal's plane, or you render the wall behind it. When two portals see each other you get infinite recursion — cap the depth.
2. Physical traversal
- Clone: spawn a mirror at the other portal as the object enters;
- Teleport at the midpoint: the instant the center of mass crosses the plane, teleport the body and swap velocity direction;
- Velocity redirection: re-project exit velocity by the portals' relative rotation.
The design lesson
What won the award was the restraint of building whole levels on one core mechanic — each level teaches exactly one new use.