iT邦幫忙

2025 iThome 鐵人賽

DAY 25
1

這裡是鐵匠史密斯(Bro fist)~
既然我們已經渲染了牆壁,我們接下來也試試看渲染地板吧~

地板的渲染

老樣子,直接上圖:
https://ithelp.ithome.com.tw/upload/images/20250825/20157653a2nVUhL85S.png
德軍總部3D的圖中我們也得知:

  • 不只牆壁,地板的部分也是越靠近自己,地板亮度越亮,越遠離自己,地板亮度越暗
    我們原本的渲染程式碼如下:
// Decide the height of the wall by distance to the wall
int nCeiling = (float)(nScreenHeight / 2.0) - nScreenHeight / ((float)fDistanceToWall);
int nFloor = (float)(nScreenHeight / 2.0) + nScreenHeight / ((float)fDistanceToWall); // nFloor = nScreenHeight - nCeiling;

short nShade = ' ';
if (fDistanceToWall <= fDepth / 4.0f) // Get very close to wall -> will be full-shaded
    nShade = 0x2588;
else if (fDistanceToWall <= fDepth / 3.0f)
    nShade = 0x2593;
else if (fDistanceToWall <= fDepth / 2.0f)
    nShade = 0x2592;
else if (fDistanceToWall <= fDepth) // Get far to wall -> will be light-shaded
    nShade = 0x2591;
else
    nShade = ' '; // So far, far way -> will see nothing

for (int y = 0; y < nScreenHeight; y++)
{
    if (y < nCeiling) // If the pixel is above the nCeiling -> should be ceiling
    {
        screen[y * nScreenWidth + x] = ' '; // Set to space
    }
    else if (y > nCeiling && y <= nFloor) // If the pixel is between the nCeiling and nFloor -> should be wall
    {
        screen[y * nScreenWidth + x] = nShade; // Set to wall character
    }
    else // If the pixel is below the nFloor -> should be floor
    {
        screen[y * nScreenWidth + x] = ' '; // Set to floor character
    }
}

尤其,渲染地板的部分為:

    else // If the pixel is below the nFloor -> should be floor
    {
        screen[y * nScreenWidth + x] = ' '; // Set to floor character
    }

目前地板皆為 ' ' 字元,是該在這個地方動手腳了

    else // If the pixel is below the nFloor -> should be floor
    {
        // Shade floor based on poroption of the way from the center to the bottom of the screen
        float b{ 1.0f - (((float)y - nScreenHeight / 2.0f) / ((float)nScreenHeight / 2.0f)) };

        if (b < 0.25)
            nShade = '#';
        else if (b < 0.5)
            nShade = 'x';
        else if (b < 0.75)
            nShade = '.';
        else if (b < 0.9)
            nShade = '-';
        else
            nShade = ' ';

        screen[y * nScreenWidth + x] = nShade;
    }

在這裡有幾個特點:

  1. 只使用一般的字元 #x.- 附值 short nShade
  2. 地板渲染的部分與牆壁渲染的原理不同,並非依賴於fDistanceToWall 進行渲染,
    而是:
float b{ 1.0f - (((float)y - nScreenHeight / 2.0f) / ((float)nScreenHeight / 2.0f)) };

今日總結

  1. 地板渲染使用#x.- 字元渲染
  2. 渲染原理不依賴於 fDistanceToWall 來決定渲染的深淺

明日會提到一點小原理,並展示一下渲染的成果圖~
地板渲染原理的部分會以自己的理解嘗試解釋~
繼續走下去~

Reference

  1. 德軍總部3D

上一篇
Day 24 | Ray Casting 中場總結:從光線到角色的移動
下一篇
Day 26 | Ray Casting 渲染地板 - Part 2
系列文
用 C++ 實作簡易第一人稱視角遊戲:從入門到理解 Ray Casting30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言