iT邦幫忙

2025 iThome 鐵人賽

DAY 17
1
自我挑戰組

用 C++ 實作簡易第一人稱視角遊戲:從入門到理解 Ray Casting系列 第 17

Day 17 | Ray Casting : 距離決定牆壁的高矮 - Part 3

  • 分享至 

  • xImage
  •  

周末好~ 鐵匠史密斯在此。
8/17 (日),美好的周末~ 大家過得如何呢~?

總而言之,直接切入正題,關於 javidx9 大神提到的 nCeiling 以及 nFloor 公式,目前以我的認知來嘗試解釋,公式的推導
當然,今日的紀錄算是不完全的,如果大佬們願意傳授一些知識、技巧的話,小弟真的感激不盡。
那關於其他敘述玩家畫面中牆壁的高矮之資源,可以在 Ray Casting Tutorial 中參考。

針孔成像定理

看了Ray Casting Tutorial 後,想到以前光學有學過針孔成像定理,對我來說,光學成像定理會解釋得更清楚,可以參考翰林學院 的圖片:
https://ithelp.ithome.com.tw/upload/images/20250817/20157653f5og4NtFkl.png
https://ithelp.ithome.com.tw/upload/images/20250817/20157653qEDzjQWG5u.png
光經過針孔之後,會得到一個倒立、相反的實像
由圖中可以假設:
物體高為 h
物體至針孔距離為 d
針孔至像距離為 D
物體於平幕的像高為 H
依照相似三角形的原理,可以得知 h: H = d: D

另外,其實我們可以直接比擬人眼的光學原理,直接上圖(來自知乎:眼球成像):
https://ithelp.ithome.com.tw/upload/images/20250817/20157653SNCrJgvzhm.png
假設人眼為凸透鏡,不計算厚度,其對遠方物體的成像為左右顛倒、上下相反的倒立實像,只不過大腦會將光訊號(倒立實像)處理成正立實像。
人眼只要假設凸透鏡沒有厚度,且光欄(Pupil)為凸透鏡,光欄大小相對於其他物體極小(Pupil size ~ 0),那我們可以將凸透鏡視為針孔!

回到公式,我們得知了h: H = d: D
那我們可以知道,平幕的像高為 H = h * D / d
是不是就跟Ray Casting Tutorial提到的公式一樣了呢?
https://ithelp.ithome.com.tw/upload/images/20250817/20157653c32KS7jNYy.png

另外我們可以知道,底片(平幕)至針孔的距離固定,且假設物體高度固定為1(遊戲世界中的牆壁高度都一樣),所以,可以把公式改寫成:

H = h * 1 / d ~ 1/d 

也就是說像的高度 H 與物距 d 成反比,是否就有點像javidx9 大神提到的公式的後項 nScreenHeight /((float)fDistanceToWall) ?

// Decide the height of the wall by distance to the wall
int nCeiling = (float)(nScreenHeight / 2.0) - nScreenHeight /((float)fDistanceToWall);

目前是推導到這裡,就我的認知,依照針孔成像的定理,來決定fDistanceToWall 距離 以及 像高 的關係,再依照比例 nScreenHeight 來分配 nCeiling 以及 nFloor 的 高度

今日總結

  • 針孔成像定理 推論 nCeiling 以及 nFloor 公式的由來

這些都是初步的推導,日後會以 3-D 的方式來做幾合推導並補充在文章內,不過,這邊些跟大家分享一些觀念就好,明日會繼續探討渲染牆壁 的部分~
我們繼續走下去~

Reference:

  1. Ray Casting Tutorial
  2. 翰林學院
  3. 知乎:眼球成像
  4. NCYU - MXPC: 針孔相機

上一篇
Day 16 | Ray Casting : 距離決定牆壁的高矮 - Part 2
下一篇
Day 18 | Ray Casting : 視角的轉動 - Part 1
系列文
用 C++ 實作簡易第一人稱視角遊戲:從入門到理解 Ray Casting30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言