3D地表生成及渲染 VOXEL by 雲風

2021-04-12 17:06:29 字數 4458 閱讀 8497

想 跟 著 雲 風 的 講 解 來 慢 慢 體 會 嗎? 那 麼 就 先 看 看 右 邊 的 效 果 圖, 來 個 感 性 的 認 識 吧. yeah! 這 就 是 我 們 要 達 到 的 效 果 ;-) 是 不 是 和 某 些 遊 戲 裡 採 用 的 engine 的 效 果 不 大 一 樣? 是 的, 我 們 不 準 備 使 用 多 邊 形. 這 個 算 法 產 生 的 3d 地 錶比 用 多 邊 形 產 生 出 來 的 更 平 滑, 在 英 文 裡 我 們 稱 其 為 voxel. 它 大 量 的 被 用 於 現 在 的 模 擬 飛 行 的 遊 戲 中, 記 得 commache i 就 是 因 為 採 用 這 個 技 術, 而 使 我 耳 目 一 新, 頓 時 愛 上 了 這 個 遊 戲 :-)

閒 話 不 提 了, 我 在 學 習 3d 地 表 的 生 成 算 法 時, 有 幸 拜 讀 了 一 段 程 序, 深 受 啟 發. 原 本 早 就 應 該 將 其 介 紹 給 大 家, 一 直 沒 有 時 間 寫 這 篇 文 章. 這 兩 天 沒 有 更 新 主 頁, 來 這 兒 訪 問 的 朋 友 還 是 那 麼 多, 真 有 點 不 好 意 思. 就 為 大 家 花 點 時 間, 再 寫 篇 有 價 值 的 東 東 吧:-)

和 這 個 3d 地 表 有 關 的, 有 兩 個 部 分:一 是 生 成 的 算 法; 二 是 顯 示 的 算 法.地 表 和 其 它 的 物 體 不 同, 它 沒 有 復 雜 的 3d 結 構, 所 以 可 以 不 用 多 邊 形 去 描 述 它. 這 裡 我 們 採 用 了 一 個 256 x 256 的 數 組 來 儲 存 這 個 範 圍 內 的 每 一 個 點 的 高 度. 而 地 表 的 光 澤, 也 是 預 先 算 好 的 ;) 同 樣 儲 存 在 一 個 256 x 256 的 數 組 了. 渲 染 的 方 法 是 利 用 坡 度 (即 和 周 圍 點 的 高 度 差 來 決 定 的), 當 然 你 也 可 以 考 慮 點 的 絕 對 高 度, 比 如 在 絕 對 高 度 高 的 區 域 白 一 些, 以 造 成 一 種 山 頂 積 雪 的 感 覺, 這 就 是 你 自 己 的 發 揮 了. 在 生 成 地 表 時,第 一 步 是 決 定 外 形 的 概 況,這 裡 採 用 的 是 隨 機 的 方 式. 由 粗 到 細, 逐 步 細 化, 每 次 地 表 上 下 波 動 的 幅 度, 由 運 算 的 面 積 來 決 定. 而 在 實 際 運 用 時, 可 以 在 隨 機 的 過 程 中, 加 入 一 些 限 制, 來 控 制 地 表 的 生 成. 第 二 步, 就 是 將 前 面 生 成 的 圖 象 做 平 滑 處 理, 讓 每 個 點 去 和 周 圍 的 點 運 算, 取 平 均 值, 使 不 至 於 出 現 過 大 的 變 化, 這 個 過 程 多 重 復 幾 次 (這 裡 是 3 次), 就 可 以 得 到 上 佳 的 效 果 了 :-) 由 於 所 有 的 生 成 部 分 都 是 預 先 算 好, 所 以 可 以 不 考 慮 速 度 問 題.

顯 示 時, 同 樣 不 需 要 過 多 的 數 學 知 識. 我 們 由 近 及 遠 的 畫 出 地 表 就 可 以 了. 只 要 知 道, 距 離 視 點 越 遠, 看 到 的 高 度 就 越 低, 利 用 實 際 高 度 和 距 離, 不 難 計 算 出 應 當 在 屏 幕 上 繪 制 的 高 度. 如 果 你 以 前 稍 微 研 究 過 3d engine, 就 不 難 理 解 我 的 意 思. 而 出 於 地 表 3d 結 構 的 簡 單, 遠 處 的 部 分 是 不 會 遮 擋 住 近 處 的 部 分 的, 這 個 減 小 了 許 多 設 計 難 度. 只 是 在 處 理 視 線 和 我 們 生 成 的 地 圖 的 x,y 軸 成 一 定 角 度 時, 需 要 使 用 一 點 三 角 知 識.

我 最 大 的 遺 憾 是, 目 前 還 沒 有 搞 清 視 線 不 是 水 平 時 的 算 法. (如 果 使 用 多 邊 形 產 生 地 表, 卻 很 簡 單, 這 個 是 另 一 篇 文 章 的 內 容 了)

也 許 解 說 的 太 簡 單, 但 是 我 認 為 你如 果 能 欣 賞 一 下 源 代 碼, 一 切 都 會 變 的 簡 單. 原 來 的 程 序 已 經 是 很 清 晰 了, 但 作 者 還 是 加 入 了 少 許 優 化. 為 了 寫 這 篇 教 學 性 質 的 文 章,雲 風 又 將 程 序 重 寫 了 一 遍 (使 用 的

djgpp

編 譯),更 是 添 加 了 非 常 詳 細 的 中 文 注 解. 大 家 慢 慢 品 味 吧 :-)

#include #include #include #include #include #include #include #include #include // 將值限制在 0..255 之間

#define clamp(x) ((x)<0 ? 0 : ((x)>255 ? 255 : (x)))

// 取 x 的低位元組位, 即對 255 取模 (hmap 和 cmap 都是 256 x 256 的陣列)

#define l(x) ((x)&0xff)

typedef unsigned char byte;

byte hmap[256][256]; // 地表高度陣列

byte cmap[256][256]; // 色彩值陣列

byte video[320*200]; // 螢幕緩衝區

// 地表高度和色彩表的計算

void computemap(void)}}

// 平滑處理

for ( k=0; k<3; k++ )

for ( i=0; i<256; i++ )

for ( j=0; j<256; j++ )

// 顏色計算 (地表高度的衍生物)

for ( i=0; i<256; i++ )

for ( j=0; j<256; j++ )

}int lasty[320],// 畫在指定列上的最後乙個點

lastc[320];// 最後一點的顏色

// 畫地表的乙個"部分"; 它能畫出距離視點一定遠處的圖象

// 使用 lasty 陣列中儲存的上次畫過的位置, 保正了這個部分不會

// 覆蓋掉以前畫的部分. x0,y0 和 x1,y1 和 xy 座標描述

// 地表的高度, hy 是視點的高度, s 是由距離決定的比例因子.

// x0,y0,x1,y1 是 16.16 的定點數,

// 比例因子是 16.8 的定點值.

void line(int x0,int y0,int x1,int y1,int hy,int s)

if ( y<0 ) y=0;

while ( y

>18; cc+=sc;

b-=320; a--;

}lasty[i]=y;

}lastc[i]=c;

// 進一步計算下乙個 xy 座標

x0+=sx; y0+=sy;}}

float fov=3.141592654/4;

// 45 度寬的視角

// 畫出從點 x0,y0 (16.16) 以 a 角 看到的圖象

void view(int x0,int y0,float aa)

// 計算視點高度變數

// 計算 xy 座標; a 和 b 將被定位於

// 乙個 (0..255)(0..255) 的區間裡面.

u0=(x0>>16)&0xff; a=(x0>>8)&255;

v0=(y0>>16)&0xff; b=(y0>>8)&255;

u1=(u0+1)&0xff;

v1=(v0+1)&0xff;

// 由周圍 4 個點來決定裡面的高度

h0=hmap[v0][u0]; h2=hmap[v1][u0];

h1=hmap[v0][u1]; h3=hmap[v1][u1];

h0=(h0<<8)+a*(h1-h0);

h2=(h2<<8)+a*(h3-h2);

h=((h0<<8)+b*(h2-h0))>>16;

// 無覆蓋的由近及遠畫地表

for ( d=0; d<100; d+=1+(d>>6) )

// 將最終圖象 blit 到螢幕

_movedatal(_my_ds(), (unsigned)video, _dos_ds, 0xa0000, 16000); //320*200/4

}void main(void)

// 計算地圖高度

computemap();

// 主迴圈

// a = 角度

// x0,y0 = 當前座標

// s = 固定速度

// ss = 當前向前/向後的速度

// sa = 旋轉角速度

a=0; k=x0=y0=0;

s=4096;

ss=0; sa=0;

while(k!=27)}}

// 退回到文字模式

r.w.ax=0x03; int386(0x10,&r,&r);

}

3D渲染管線流程

首先用一張圖來回顧一下渲染管線的各個階段,目前為止我們接觸的著色器有頂點著色器和畫素著色器,而接觸到的渲染管線階段有 輸入裝配階段 頂點著色階段 光柵化階段 畫素著色階段 輸出合併階段.可以看到,幾何著色器是我們在將頂點送入光柵化階段之前,可以操作頂點的最後乙個階段。它同樣也允許我們編寫自己的著色器...

如何理解3D渲染引擎

框架的支援 3d引擎只是動力 在外層需要有完整的框架負責輸入輸出,網路通訊等,平台差異性 物件導向設計 外掛程式擴充套件機制,主要是功能擴充套件,引擎只負責3d效果的展出,實際的產品應用要考慮輸入輸出 網路通訊 其他媒介的支援 其中輸入輸出主要是滑鼠鍵盤,kinect等體感式外設 網路通訊主要是遊戲...

簡述3D引擎的渲染優化

文章出處 一 如何進行有效的效能評測 對於任何乙個3d應用程式來說,追求場景畫面真實感是乙個無止盡的目標,其結果就是讓我們的場景越來越複雜,模型更加精細,這必然給圖形硬體帶來極大的負荷以致於無法達到實時繪製幀率。因此,渲染優化是必不可少的。在渲染優化之前,我們需要對應用程式效能進行系統的評測,找出瓶...