You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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单位)

问题根源与改进思路

你的核心问题出在距离到屏幕高度的转换公式:原公式用线性比例映射距离与高度,但透视投影中物体高度和距离是反比关系,线性映射会导致近距离出现非线性扭曲。

替换为透视投影的正确计算逻辑

光线投射的标准高度计算基于相机投影平面的物理原理,步骤如下:

  1. 定义关键常量(根据你的场景参数):
    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),确保透视比例正确
    
  2. 计算单一切片的高度:
    // adjusted_dist是你已经修正鱼眼后的垂直距离
    float sliceHeight = (WALL_UNIT_HEIGHT * PROJECTION_PLANE_DIST) / adjusted_dist;
    
  3. 计算切片在屏幕上的上下绘制边界(保证垂直居中,且不超出屏幕):
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 06:40:20