MAKE · WRITE · SHARE

Base-平面反射与斜截视锥体

平面镜和静水面的共同特点,是反射边界可以用一个平面表示。把相机关于这个平面镜像,再从镜像视角渲染,就能得到稳定的平面反射。

反射相机只解决了观察位置。还需要裁掉平面背后的内容、处理翻转的面朝向,并把渲染结果投影回接收表面。遗漏其中任一步,都可能出现漏画、穿帮或反射方向错误。

反射相机关于平面对称,镜面成为新的裁剪边界

1. 用平面描述镜面

采用列向量约定,平面写为 dot(n,p)+d=0,其中 n 是单位法线。点 p 到平面的有符号距离是 s=dot(n,p)+d。

点关于平面的反射为:

1
p' = p - 2 * (dot(n,p) + d) * n

方向向量没有位置平移项,因此 v'=v-2*dot(n,v)*n。法线如果没有归一化,必须先归一化并同步调整 d,或者在投影项中除以 dot(n,n)。

关于平面的对称关系:P 位于镜面上,Q 与 Q′ 是平面两侧的对称点

原笔记配图:关于平面的对称关系:P 位于镜面上,Q 与 Q′ 是平面两侧的对称点。

把向量分解为平行与垂直分量

原笔记配图:把向量分解为平行与垂直分量;反射会翻转垂直于平面的分量。

2. 反射矩阵与相机

把反射变换记作 R,它的线性部分是 I-2nnᵀ,平移部分是 -2dn。在这个约定下,原相机世界到观察矩阵为 V,反射观察矩阵可写成 V_reflect=V*R。

这表示先把世界点镜像,再从原相机观察;与镜像相机位置及朝向有相同几何意义。矩阵乘法顺序与行列向量约定有关,不能把这个式子直接贴进采用另一套约定的引擎。

反射的行列式为负,会翻转坐标系手性,导致三角形绕序反转。因此反射绘制可能需要反转 Cull 设置或采用对应的渲染状态。全局状态改动必须在绘制后恢复。

单位法线约定下的反射坐标展开与齐次矩阵

原笔记配图:单位法线约定下的反射坐标展开与齐次矩阵。矩阵乘法方向须与正文的列向量约定配套。

3. 为什么还要斜截近平面

普通相机的近平面与观察方向垂直,而镜面通常不是。镜像相机会看到镜面另一侧本不应进入反射的几何,例如水下物体在水面反射中穿出来。

Oblique Near-Plane Clipping(斜截近平面裁剪)修改投影矩阵,使指定平面成为新的近裁剪边界。它不是再加一台相机,而是改变相机视锥的裁剪条件。

先把世界平面转到反射相机空间,再交给相机的斜截投影接口。对于点变换 p_new=M*p_old,平面系数按 inverse(M)ᵀ 变换;直接把法线当位置乘矩阵,会丢掉平面距离。

只用镜像相机时,平面另一侧不应出现的几何仍可能进入反射视图

原笔记配图:只用镜像相机时,平面另一侧不应出现的几何仍可能进入反射视图。

镜像相机、反射平面与物体的空间关系

原笔记配图:镜像相机、反射平面与物体的空间关系;反射视图还需要沿镜面裁剪。

4. 一次反射绘制的资源流程

1
2
主相机状态 → 计算反射 V → 转换裁剪平面 → 构建斜截 P
→ 绘制反射 RT → 主表面投影采样 → 菲涅尔与材质合成

接收表面用反射相机的 VP 投影世界坐标,执行齐次除法和纹理坐标映射,再采反射 RT。Y 翻转、Reversed-Z、XR 和渲染目标方向需要依照管线处理,不能一律手写 uv.y=1-uv.y。

近平面可以沿法线轻微偏移,减少自相交;偏移过大又会把贴近水面的内容切掉。镜面本体和反射相机递归通常需要从反射绘制列表排除。

5. 成本与适用边界

主要成本是额外视图带来的可见性计算、几何与像素绘制,以及反射 RT 的存取。降低 RT 分辨率只能缓解部分像素成本,不能消除重复提交和顶点开销。

可以缩小反射物体集合、降低更新频率,或者只在镜面可见时更新。缓存会引入延迟,相机快速移动或动态物体经过时尤其明显。

单个平面反射适合平面镜和近似平的水面,不适合任意曲面。粗糙反射也不能只靠一张锐利镜像假装完成,应结合过滤、能量分配与备用环境反射。

总结

平面反射由几何镜像、裁剪与投影采样共同构成。先把矩阵和平面约定写清楚,再处理管线方向与绕序,最后优化额外视图的成本,才能得到可维护的实现。

参考资料