C#光线投射渲染引擎为何将本该直的线渲染成曲线?
光线投射引擎中近距离墙壁直边扭曲的修复思路
我基于Wolfenstein 3D引擎用C#实现了一个简易光线投射引擎:以string[]作为地图,为输出窗口的每个垂直像素切片(共960条)投射射线,通过测量射线传播距离转换为对应垂直切片的矩形高度来渲染画面。目前存在的问题是近距离墙壁的直边会被渲染成类似y=ln(x)曲线的扭曲形状,其余部分渲染正常。
已完成的排查与处理:
- 用
float adjusted_dist = (float)Math.Cos(angle) * length;修正了鱼眼效果,但未解决当前扭曲问题 - 射线投射逻辑经俯视图调试确认运行正常
- 屏幕尺寸为960px×540px,当前使用公式
int pixels = (int)(540 - (540 * heights[i] / max_dist));将射线距离转换为切片高度,其中max_dist设为常量150(地图每个字符对应10×10单位方块,场景内物体距离不超过150单位)
问题根源与改进思路
你的核心问题出在距离到屏幕高度的转换公式:原公式用线性比例映射距离与高度,但透视投影中物体高度和距离是反比关系,线性映射会导致近距离出现非线性扭曲。
替换为透视投影的正确计算逻辑
光线投射的标准高度计算基于相机投影平面的物理原理,步骤如下:
- 定义关键常量(根据你的场景参数):
const float WALL_UNIT_HEIGHT = 10.0f; // 对应地图方块的高度(10单位) const float FIELD_OF_VIEW = Math.PI / 3.0f; // 60度视场角(Wolfenstein 3D标准值) const float PROJECTION_PLANE_DIST = (960.0f / 2.0f) / (float)Math.Tan(FIELD_OF_VIEW / 2.0f); // 投影平面距离 = 屏幕半宽 / tan(视场角/2),确保透视比例正确 - 计算单一切片的高度:
// adjusted_dist是你已经修正鱼眼后的垂直距离 float sliceHeight = (WALL_UNIT_HEIGHT * PROJECTION_PLANE_DIST) / adjusted_dist; - 计算切片在屏幕上的上下绘制边界(保证垂直居中,且不超出屏幕):
int drawStart = (int)(540.0f / 2.0f - sliceHeight / 2.0f); int drawEnd = (int)(540.0f / 2.0f + sliceHeight / 2.0f); drawStart = Math.Max(0, drawStart); drawEnd = Math.Min(540 - 1, drawEnd);
为什么原公式会出错?
原公式540 * heights[i] / max_dist是将距离做线性比例缩放,但真实透视中,墙壁高度应该与距离成反比——距离越近,高度占屏幕的比例应该越大,且这个变化是非线性的。线性映射会在近距离时过度压缩墙壁高度,导致直边出现扭曲。
额外注意事项
- 确保
adjusted_dist是相机到墙壁的垂直距离(而非射线的欧氏长度),你用Math.Cos(angle)的修正逻辑是正确的,注意angle需用弧度计算,且是射线与相机朝向的夹角。 - 如果你的场景墙高不是10单位,对应调整
WALL_UNIT_HEIGHT的值即可。
内容的提问来源于stack exchange,提问作者David Latimer
相关产品推荐
相关产品推荐

