跳到主要內容

精選文章

從 OpenGL 到 WebGPU:一個人用 Kotlin 寫出「一次撰寫、三處執行」的 3D 引擎 —— kool 的故事

圖形科普 ・ 開源專案故事

從 OpenGL 到 WebGPU:一個人用 Kotlin 寫出「一次撰寫、三處執行」的 3D 引擎 —— kool 的故事

一份程式碼,同時跑在桌面 JVM(Vulkan / OpenGL)、Android 與瀏覽器(WebGPU / WebGL)。這背後是三十年的圖形 API 演化,也是一位開發者九年多的業餘堅持。

---



demo : https://neojou.github.io/newton-cradle/

---

如果你曾經想過:「我能不能只寫一份程式,就讓 3D 場景同時在 Windows、Mac、Android 手機和瀏覽器裡跑起來?」那麼你已經碰到了電腦圖形世界裡最古老、也最頭痛的問題之一 —— 每個平台說的「GPU 語言」都不一樣。

今天要介紹的 kool,是一個用 Kotlin 寫成的開源 3D 引擎,它正是瞄準這個問題而生。不過在認識它之前,讓我們先坐上時光機,回顧一下圖形 API 是怎麼一路走到今天的。

一、三十年的 GPU 語言演化史

1992:OpenGL 與「固定管線」時代

1992 年,Silicon Graphics(SGI)以自家的 IRIS GL 為基礎推出了 OpenGL,讓不同廠商的硬體可以用同一套 API 繪製 3D 圖形。早期的 OpenGL 採用所謂的固定功能管線(fixed-function pipeline):光照怎麼算、貼圖怎麼混合,都是硬體預先寫死的幾種選項,程式設計師只能「調旋鈕」,不能「改電路」。

2000 年代:可程式化著色器登場

隨著 GPU 越來越強大,業界開始允許開發者自己寫一小段程式在 GPU 上執行,這就是著色器(shader)。OpenGL 2.0(2004)把 GLSL(OpenGL Shading Language)納入核心規格;微軟的 DirectX 這邊則有 HLSL。從此,水面反光、皮膚透光、卡通描邊……各種視覺效果都變成「寫程式」的問題。

手機與網頁:OpenGL ES 與 WebGL

為了手機和嵌入式裝置,Khronos Group 推出了精簡版的 OpenGL ES;而把 OpenGL ES 帶進瀏覽器的,就是 2011 年問世的 WebGL(後來的 WebGL 2 對應 OpenGL ES 3.0)。從此網頁不用外掛也能跑 3D。

平台各自為政:DirectX 與 Metal

另一方面,微軟在 Windows 與 Xbox 上推動 DirectX / Direct3D,蘋果則在 2014 年推出自家的 Metal,並在之後將 OpenGL 標為棄用(deprecated)。結果就是:想跨平台的開發者,得面對一張越來越破碎的地圖。

2016:Vulkan —— 把控制權交還給開發者

OpenGL 的「驅動程式幫你打理一切」設計,在多核心 CPU 時代逐漸成為效能瓶頸。AMD 先推出了低階 API Mantle,後來把它貢獻給 Khronos,成為新一代標準 Vulkan 的重要基礎。Vulkan 1.0 於 2016 年 2 月發布,主打顯式(explicit)、低階控制:記憶體配置、同步、命令緩衝區都由開發者自己管理。代價是 —— 畫一個三角形可能要寫上千行程式碼。Vulkan 的著色器不直接吃 GLSL 文字,而 是吃一種中間格式 SPIR-V(二進位位元碼)。

2023:WebGPU —— 網頁的新世代 GPU API

在瀏覽器這端,W3C 的 GPU for the Web 工作小組設計了 WebGPU:概念上接近 Vulkan / Metal / Direct3D 12 的現代設計,並支援 compute shader(運算著色器)。它的著色語言叫做 WGSL(WebGPU Shading Language)。WebGPU 於 2023 年隨 Chrome 113 正式出貨(Windows、macOS、ChromeOS)。

📌 WebGPU 支援現況(依 gpuweb 官方實作狀態頁,2026 年 10 月查核)

  • Chromium 系(Chrome / Edge):Windows、macOS、ChromeOS 自 113 版起支援;Android 12+(部分 GPU)自 121 版起;Linux 依 GPU/驅動陸續開放。
  • Firefox:Windows 自 141 版、Apple Silicon Mac 自 145 版起預設啟用;Linux 與 Android 仍在進行中。
  • Safari:macOS / iOS / iPadOS / visionOS 26 起預設支援。

資料來源:gpuweb Implementation Status。各瀏覽器版本更新快速,以官方頁面為準。

小整理:圖形 API 時間軸

年份 事件 著色語言
1992SGI 推出 OpenGL(固定功能管線)—
2004OpenGL 2.0 將可程式化著色器納入核心GLSL
2011WebGL 1.0(基於 OpenGL ES 2.0)GLSL ES
2014Apple 推出 MetalMSL
2016Khronos 發布 Vulkan 1.0(承襲 AMD Mantle)SPIR-V
2023WebGPU 隨 Chrome 113 正式出貨WGSL
2025Firefox 141(Windows)、Safari 26 相繼預設支援 WebGPUWGSL

二、痛點:同一個畫面,要寫三四套著色器?

把上面的歷史攤開,跨平台開發者的困境就很清楚了:桌面上想用 Vulkan(要 SPIR-V)或 OpenGL(要 GLSL)、Android 上是 OpenGL ES、瀏覽器裡有 WebGL(GLSL ES)和 WebGPU(WGSL)。同一個「金屬質感的方塊」,可能要準備好幾份語法不同的著色器,還得各自除錯。

kool 的回答是:用 Kotlin 寫一次,其餘交給引擎翻譯。

💡 kool 支援的平台與後端(依 README)

  • 桌面 JVM:Vulkan、OpenGL(透過 LWJGL)皆「完整可用」;WebGPU(透過 wgpu4k)「大致可用」。Windows / Linux / macOS(macOS 不支援 OpenGL 後端)。
  • 瀏覽器(JS + WASM):WebGPU、WebGL 2。WebGPU 不可用時自動退回 WebGL。
  • Android:OpenGL ES 3。

KSL:用 Kotlin 寫著色器

kool 最核心的設計是 KSL(kool shader language),一個以 Kotlin 型別安全建構器(type-safe builder>)實作的著色器 DSL。你寫的是 Kotlin 程式碼,引擎再產生對應的 GLSL 或 WGSL。我們在原始碼中確認了三個產生器:GlslGenerator(OpenGL / WebGL)、WgslGenerator(WebGPU),以及給 Vulkan 用的 GlslGeneratorVk —— Vulkan 路徑會再透過 LWJGL 的 shaderc 編譯成 SPIR-V。

README 中的 Hello World 著色器長這樣:

shader = KslShader("Hello world shader") {
    val interStageColor = interStageFloat4()
    vertexStage {
        main {
            val mvp = mvpMatrix()
            val localPosition = float3Var(vertexAttribFloat3(Attribute.POSITIONS))
            outPosition set mvp.matrix * float4Value(localPosition, 1f.const)
            interStageColor.input set vertexAttribFloat4(Attribute.COLORS)
        }
    }
    fragmentStage {
        main {
            colorOutput(interStageColor.output)
        }
    }
}

作者在 README 中寫道,這種做法的好處是共用程式碼裡沒有任何寫死的平台專屬著色器,而且未來要加新的產生器(例如 Metal)也相對容易;kool 內建的所有著色器都是用 KSL 寫成的。想看實際效果,可以打開 HelloKsl 線上 Demo。

---

我也有做一份:https://neojou.github.io/kool_hello_world/



---

不只是渲染器:一整套工具箱

  • PBR 與影像式光照(IBL):金屬度工作流程、多種色調映射(ACES、Khronos PBR Neutral 等)、Bloom、 SSAO、螢幕空間反射、延遲著色(deferred shading)。
  • 物理引擎:3D 物理基於 NVIDIA PhysX 5.6,JVM 端用作者自製的 physx-jni,瀏覽器端用同樣是作者自製的 physx-js-webidl(WASM)。2D 物理則基於 Box2D 3.1.1(box2d-jni)。
  • 內建 UI 框架(ui2):API 深受 Jetpack Compose 啟發(remember、modifier、LaunchedEffect),但從零實作、直接在引擎的繪 圖環境裡執行。
  • glTF 2.0 模型載入:README 稱「(幾乎)完整」支援,包括動畫、morph target 與骨架蒙皮。
  • Compute shader、MSDF 字型、反向深度(reversed depth)、遊戲邏輯與渲染分離的雙執行緒架構。
  • 場景編輯器:完全用引擎本身(包括 UI)實作,有 網頁版可直接試玩;README 自承仍處於早期階段,缺少一些相當基本的功能。

🎮 親手玩玩看(瀏覽器直接執行,建議使用支援 WebGPU 的瀏覽器)

小技巧:網址加上 &backend=webgl 或 &backend=webgpu 可強制切換後端。

三、起源:2017 年冬夜的一個 commit

翻開 git 紀錄,kool 的第一個 commit「Initial commit」由作者 fabmax(GitHub 帳號;commit 紀錄中也以 Max Thiele 署名)提交於 2017 年 2 月 10 日(當地時間凌晨 00:06,UTC+1;換算台北時間為同日上午 07:06)。最早的幾個 commit 就已經在處理 WebGL 的視窗同步與滑鼠操控攝影機 —— 從第一天起,「瀏覽器」就在它的藍圖裡。

之後的發展,從 commit 與 release 紀錄可以整理出一條清楚的軌跡:

時間 kool 里程碑(依 git log / GitHub Releases)
2017-02第一個 commit,初期以 WebGL 為目標
2018-03開始 Android 平台移植
2018-04標記 v0.1.0
2019-10「very first vulkan test」—— 第一次嘗試 Vulkan
2020-01 ~ 06PBR + IBL、延遲著色、glTF 模型載入陸續加入
2021-01瀏覽器端物理由 ammo.js 換成 PhysX WASM;作者同月建立 physx-js-webidl 與 physx-jni 專案
2022-03開始開發 KSL(kool shading language)
2022-09新 UI 框架 ui2 合併(PR #19)
2023-04場景編輯器的第一個概念驗證
2023-12-13v0.13.0:Compute shader(第一部分)、桌面 OpenGL 與 WebGL 共用渲染後端
2024-03-24v0.14.0:全新 WebGPU 渲染器;舊 Vulkan 支援暫時 停用
2024-06-29v0.15.0:以編輯器為主(新專案資料模型、物理、角 色支援)
2024-07GitHub 組織 kool-engine 建立(7/18),專案由 fabmax/kool 移至 kool-engine/kool(舊網址目前會轉址)
2025-01-06v0.16.0:大量編輯器改進,PhysX 5.5
2025-03-27v0.17.0:重寫的 Vulkan 後端(同時帶來 macOS 支>援)、KSL 支援 struct、反向深度成為預設
2025-09-28v0.18.0:遊戲邏輯/渲染多執行緒、實驗性桌面 WebGPU(wgpu4k)、Swing 視窗後端
2025-12-21v0.19.0(目前最新正式版):Android 物理、Box2D 2D 物理預覽、UI 的 LaunchedEffect 與動畫改進

註:v0.13.0 之後的日期為 GitHub Release 發布時間(已換算為台北時間);更早的版本在 GitHub 上沒有 Release 頁面,以 git tag/commit 日期為準。Maven Central 上可查到的 kool-core 版本從 0.7.0 開始。

🔁 一個有趣的細節:Vulkan 的「來了又走,走了又來」

kool 早在 2019 年就做過 Vulkan 實驗,但 v0.14.0 的發布說明寫著 Vulkan 支援「暫時停用」;直到 v0.17.0 才以全新的 Vulkan 後端回歸。commit 紀錄顯示,新 Vulkan 後端的架構參考了為 WebGPU 後端設計的架構(2025 年 1 月:「adopting wgpu backend architecture for vulkan backend」)—— 這正好說明了 WebGPU 與 Vulkan 這兩代 API 在設計理念上的親緣關係。

四、社群:一人主導,但不孤單

以 2026 年 10 月 19 日查詢 GitHub API 的結果,kool 擁有約 592 顆星、51 個 fork, 貢獻者頁面列出約 15 位帳號(含 dependabot 機器人)。採用 Apache 2.0 授權,套件發布在 Maven Central(de.fabmax.kool)。主分支共約 2,500 個 commit,其中絕大多數來自作者本人 —— 作者自己在 Roadmap 討論中坦言,這是一個業餘專案(pet project),進度取決於他有多少空閒時間。

但社群的身影確實存在:

  • 桌面 WebGPU 後端使用 wgpu4k,v0.18.0 發布 說明特別感謝其作者 @ygdrasil-io 的協助。
  • 主分支上的新模組 kool-compose-ui(2026 年 1 月加入)由社群貢獻者提交,讓開發者能用 Jetpack Compose runtime 在 kool 裡寫 UI。
  • v0.19.0 的 UI 改進也感謝了社群貢獻者 @bat1set。
  • 交流管道:官方 Discord 伺服器與 GitHub Discussions。

用 kool 打造的作品:

⚠️ 誠實說:文件是弱項

README 自己寫著「documentation is still a bit of a weak spot」(文件仍是一個弱點)。GitHub 上也有使用者開 issue(#130)表示因缺乏 KDoc 而難以上手,作者回覆「有在計畫,但工作量很大」。目前我們沒有找到成體系的第三方教學;入門主要靠 README 範例、kool-templates 範本專案,以及 kool-demo 子專案的原始碼。

五、優點與限制

👍 優點

  • 真正的 Kotlin Multiplatform:一份共用程式碼涵蓋桌面、Android、瀏覽器
  • KSL 免去多套著色器的維護
  • 同時支援 Vulkan、WebGPU 等現代 API,且有 OpenGL / WebGL 後備
  • PBR、延遲著色、PhysX、glTF、UI 一應俱全
  • 線上 Demo 豐富,原始碼即範例
  • Apache 2.0 授權,持續有新 commit

👎 限制

  • 文件少、教學稀缺,學習曲線靠讀原始碼
  • 高度依賴單一作者的業餘時間,無時程保證
  • 仍在 0.x,API 會變動(主分支已有棄用與大型重構)
  • 編輯器仍屬早期,issue 中有數個編輯器錯誤回報
  • 無 iOS 目標;Android 目標預設關閉,Demo 未建置於 Android
  • 部分 Demo 僅支援 WebGPU;桌面 WebGPU 後端需 Java 22

和其他方案比一比

方案 主要語言 定位 與 kool 的差異
koolKotlin程式碼優先的 3D 引擎—(基準)
libGDXJava(可用 Kotlin)成熟的跨平台遊戲框架社群與資源多得多、支援 iOS;以 OpenGL 系為主
KorGEKotlinKotlin 多平台遊戲引擎同為 Kotlin,但偏重 2D;kool 偏重 3D 與現代渲染
GodotGDScript / C#(引擎 C++)編輯器優先 的完整引擎編輯器與生態遠為成熟;不是 JVM / Kotlin 生態
BevyRustECS 架構、程式碼優先理念相近(基於 wgpu、跨原生與網頁),但屬 Rust 生態
Three.js / Babylon.jsJavaScript / TypeScript網頁 3D 函式庫/引擎網頁端生態最大;kool 的優勢在於同一份 Kotlin 程式碼也能跑在 JVM 與 Android

表格為概略定位比較,非效能評測。

六、未來往哪走 ?

✅ 事實:作者在 Roadmap issue(#190,2025 年 12 月)的回覆

作者表示因為是業餘專案,很難給出路線圖,也無法提供時程;但「非常粗略地說」接下來的方向包括:

  • 進階 2D 物理(目前只提供 Box2D 功能的有限子集)
  • 渲染器的品質與效能改進(特別提到 Vulkan 後端仍有很大的效能提升空間)
  • 瀏覽器上的 Kotlin/WASM
  • 在 JVM 上採用較新的 FFM(Foreign Function & Memory)功能,主要影響 2D / 3D 物理的原生綁定
  • 重新投入編輯器開發

🔍 觀察:主分支(0.20.0-SNAPSHOT)上已經發生的事

  • WASM 目標:2025 年 12 月底起有 WASM 版 Demo、WASM 上的 WebGPU 後端與 2D 物理。不過 README 指出,因大量 JS 互通呼叫,WASM 目前多半比 JS 版慢,仍建議使用純 JS 目標。
  • 新的延遲著色管線:2026 年 5 月出現「deferred2」系列 commit(時間性濾波、螢幕空間反射、整合 AO / Bloom / 陰影),之後移入核心並用於車輛 Demo;2026 年 6 月舊的 DeferredPipeline 已標記為棄用。
  • 新的 compute AO 管線(2026 年 4 月),WebGPU 後端需要 texture-formats-tier1 功能。
  • SDL 視窗子系統:2026 年 5 月實作並在 commit 中「Promote SdlWindowSubsystem to default」,同時加入 SDL 手把支援與 Wayland 偵測。
  • KSL 大型重構:2026 年 5 月以 Kotlin context parameters 重構 KSL。
  • kool-compose-ui 模組:基於 Compose runtime,目前實作了部分元件。

🔮 推測(筆者個人解讀,非官方說法)

  • 從主分支的累積變更(新 deferred 管線、SDL 預設、KSL 重構、舊 API 棄用)來看,下一個 0.20 版可能會是一次變動幅度較大的版本,升級 時需留意相容性。
  • 隨著 Firefox 與 Safari 陸續預設開啟 WebGPU,「僅 WebGPU」的 Demo 能觸及的使用者應會增加,kool 在網頁端的 WebGPU 優先策略可能會越來越吃香。
  • 官方 Compose 式 UI(ui2)與社群的 kool-compose-ui 並存,未來兩者如何定位,目前看不出明確結論。
  • iOS / Metal 至今沒有實作;早在 2020 年的 issue #1 中,作者就提到著色器高度依賴生成的 GLSL 是一大障礙。KSL 的「多產生器」架構理論上為此留了一扇門,但目前沒有跡象顯示近期會動工。

結語:站在三十年肩膀上的一個人

從 SGI 的 OpenGL 到 W3C 的 WebGPU,圖形 API 的歷史是一部「越來越強、也越來越分裂」的歷史。kool 沒有試圖發明新的 GPU 標準,而是用 Kotlin 的語言能力,把這些分裂的標準重新縫合成一套共用的程式碼 —— 著色器用 KSL 一次寫好,物理用自製綁定讓 JVM 與瀏覽器擁有相同功能。

它還年輕(0.x)、文件不多、主要靠一個人撐著;但如果你是 Kotlin 開發者,想用熟悉的語言摸一摸 Vulkan 與 WebGPU 這些現代圖形 API,kool 是一個非常值得打開原始碼、跟著 Demo 一行行讀下去的專案。

🔗 延伸連結

本文資料查核日期:2026 年 10 月 19 日(台北時間)。星數、版本等數字會隨時間變動;標示 「觀察」「推測」的段落為筆者依公開 commit 紀錄所做的解讀,並非官方路線圖。

留言

熱門文章