The mapping looked flat/skewed because rays were cast on the wrong side of the facade, world directions were mixed with room-local origins, and B/(B+d) UV crush / center mullions distorted the pre-projected atlas. Use per-window object space (window at z=+1 into -Z), Joost far-hit slab tests, bounded B/(B+d) sampling, outer sash only, and a matching perspective atlas bake. Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
Interior Mapping(室内映射)
实现知乎专栏 Interior Mapping室内映射技术拆解 中的预投影 2D Atlas 室内映射:在无真实室内几何的情况下,透过窗户看到有透视深度的房间。
技术要点
- 切线空间射线–AABB 求交:每个窗户 tile 视为单位房间盒,用视线与远平面交点采样。
- 伪透视缩放:
scale = B / (B + depthNorm),对预投影贴图做相似三角形校正。 - 房间图集:运行时生成 4×4 正交预投影房间 Atlas,支持顺序 / 随机选房。
- 前景遮挡:文章中的深度图 Ray March 在此用过程化家具 AABB 代替(同算法:步进 + 二分求精),便于示例自包含、不依赖额外 set-1 深度贴图。
- 窗框 + 掠射菲涅尔:浅角时偏反射,掩盖预投影极限。
运行
make run/linux-debug GAME=examples/interior-mapping
# 或
cd examples/interior-mapping && ../../build/linux-debug/src/engine/eve run
操作
| 键 | 作用 |
|---|---|
O |
开关自动环绕 |
A / D |
偏航 |
W / S |
俯仰 |
[ / ] |
房间深度 |
- / = |
透视强度 |
F |
开关过程化家具遮挡 |
R |
开关随机房间 |
1 / 2 / 3 |
浅 / 默认 / 深预设 |
文件
shaders/interior_mapping.frag— Mesh3D 自定义片元着色器main.nut— 场景、参数绑定assets/room_atlas.png— 预投影房间图集(4×4)scripts/gen_room_atlas.py— 重新生成图集config.nut— 窗口配置
Mapping notes
The fragment shader builds a per-window room space (window on z=+1, back wall on z=-1)
from tiled mesh UVs, casts a view ray with Joost’s far-hit box test, then samples the
pre-projected atlas with scale = B / (B + d).
Debug: set fgSteps to 99 via the live uniform path to visualize face hits
(floor=red, ceiling=cyan, walls=green/blue, back=yellow).
Controls: O orbit, A/D yaw, W/S pitch, [/] depth, -/= perspective, F furniture, R random rooms.