BGFX是什么
BGFX是一個專注渲染接口的項目,而我打算做一個跨平台游戲引擎,渲染是引擎很基礎的功能,BGFX可以提供最基本的渲染API。
BGFX在基本的設計傾向上,還是類似opengl這種設置狀態機,呼叫Draw指令的設計。
但是多設置了一些概念,還是有一些學習成本的
BGFX不是一個引擎,但他為開發一個跨平台引擎節省了很多工作。
BGFX的一些特點
1. 首先BGFX所有的操作都是入隊列的,這樣可以很輕易的做到commandbuffer 多線程。直到調用BGFX.frame();會等待繪制
2. Bgfx並非完全嚴格按照gl設計,Commit指令相當於Draw,但是Clear指令只是設置一個狀態,不會在隊列里做出對應指令,這個clear狀態在每個view繪制 開始時實際做clear的動作。
3. 這里就涉及一個新概念View了,Bgfx封裝了幀的概念,幀好理解,Bgfx::frame()等待一幀,一幀就是你要畫點啥到屏幕上,一幀被分為若干個view,bgfx默認最大65536個view。一個view就是一堆繪制指令,一幀順序執行所有的view,每個view的開頭都是一個clear,每個view可以使用不同的目標,輸出到屏幕,或者輸出到rendertarget。
4. Bgfx 采用了一個很巧妙的設計實現了shader的跨平台,之前我沒有好好看bgfx的實現,直接跑去看spirvcross 這類方案了,草率了。仔細一看,bgfx自己就帶了shaderc,可以自己編譯多個平台的shader。而且BGFX的實現方法就是替換,很巧妙很簡單的。
談談BGFX的新概念VIEW
BGFX的新概念view 會帶來一些不同的用法,我們過去做渲染沒有這樣的概念,通常管線直接來管理這些工作,所以場景和UI的結合就管線直接管了,畫UI的時候ClearDepthOnly就可以了。但是BGFX clear的時機只有view開始時,所以對於BGFX,你必須把場景放入一個View,UI放入另一個View,然后都准備好,執行一次Bgfx::frame()等他畫出來。
設計始終是一把雙刃劍,概念更清晰,同時也更復雜。BGFX 這個VIEW的設計,帶來一點額外的學習成本,但是把繪圖工作需要多次操作,最終合成出一個最終的幀的這個操作。分的更加清晰了,我認為還是比較優秀的設計。
按照BGFX的view設計,如果你的場景里有一個電視看着另一個場景,BGFX就應該0號view畫場景2,輸出到rt,1號view畫創景1,2號view畫UI。RenderTarget和 UI都應該被合並到一起,一起來Bgfx.Frame();
談談BGFX的跨平台Shader
BGFX的shader 跨平台方案基本上是基於GLSL,但是很多指令都改了一下,這樣在編譯成不同版本的Shader時,只需要進行替換,這也帶來一些小問題,就是這玩意不是嚴格的glsl了。
首先BGFX編譯Shader需要一個varying.def.sc 文件(可以指定名字,不指定默認會找這個)
他負責的就是glsl語法中 vraying 和 attribute 定義,可以看出雖然改了語法,還是熟悉的味道。
然后是vertexshader
可以看到bgfx這里加了個自己的新玩法
$input 用來配置attribute
$output 用來配置 varying 和上邊的配置文件統一
bgfx_shader.sh 里就是一堆宏了,這個一看就懂。
Fragment shader
Fragment shader 的input 是 varying
這里的SAMPLER2D 要用宏來定義,因為他在hlsl 和 glsl 相差很大,bgfx選擇用宏來搞定差別
采樣函數換成了texture2D也是基於上述原因
編譯bgfx tool 可以得到shaderc 命令行工具,你需要的所有文件,bgfx源碼里都有。
看一下我的批處理,你能感受到他的跨平台效果了嗎?
談談BGFX可能的一些問題
Bgfx把三矩陣放進了一些深層邏輯
默認定義了這些uniform,並且會自己對提交的內容進行深度排序(這肯定依賴ModelViewProj)
這也多管了一些引擎該管的事情,也導致使用上需要更注意。
可能透明和不透明物體也得分view 來繪制了,我還沒實踐這些,但是從接口上看,BGFX只允許對View設置排序模式。
面對一打有不同排序要求的繪制任務,不同Clear要求的繪制任務,不同RT要求的繪制任務,BGFX開出的葯方都是同一個,放進不同的View里。
既然有人幫你做了這么多了,你還有什么接口,不做個引擎呢。
附圖一張,慢慢努力。