從零開始手擼WebGL3D引擎8:里程碑3-一個多光源場景

里程碑3

好久沒寫筆記了,本週又搞了幾天,基本實現了基於多pass的多光源前向渲染,加上之前實現的基本的scene和transform,暫且算作里程碑3:simple scene。雖然代碼裏面還有很多TODO,但勉強可以看些效果了。先上個視頻:

mini3d.js多光源逐像素 Blinn-Phong光照

現在把demo網頁部署到了碼雲上mini3d.js_examples,國內訪問比github快多了。

這個demo是在一個簡單的場景裏面,有兩個膠囊體,有一個平行光和兩個點光源,點光源會在場景中做螺旋運動。地面和膠囊體會接受這三個光源的光照(使用Blinn-Phong逐像素光照)。初始位置在左邊的膠囊體會自動旋轉同時在世界up軸(y軸)上自動上下移動,屏幕左右滑動可以改變該膠囊體在x,z平面上的位置。而右邊的這個膠囊體會平滑的旋轉以讓自己面向可以移動的膠囊體。

雖然內容不是很多,但已經具備一些3D引擎的要素了。而且最近投入到mini3d.js上的時間少了很多(因爲時間都用在刷leetcode了。。),所以從顯示單個模型的demo2到這個有場景和光照的demo已經過了很久。這中間可以總結和記錄的東西還是挺多的。本篇是總體介紹,可能會寫幾篇介紹一下某些東西的細節。

新增功能

爲了實現這個基本的demo,mini3d.js添加了很多功能(當然很多還不完善,一些採用了臨時替代方案)。

  • 基本的節點場景系統
    搞了個類似Unity的組件系統(不是ECS)。爲了方便,沒有獨立出Transform組件,而是把transform相關的功能放入到SceneNode裏面了。場景的主要功能是管理節點局部矩陣和世界矩陣的更新,以及管理Camera,Light和可渲染節點,爲渲染服務。同時由於Transform功能的需要,math模塊也更新了,新增了Matrix3專門用於處理旋轉,另外增加了四元數相關的內容,包括四元數和Matrix3之間的相互轉化,基於四元數和Matrix3的LookAt以及四元數的Slerp插值。可能有的同學說了,連基本的frustum culling都沒有啊。。是的,暫時沒有場景管理和剔除,沒有LOD,沒有材質排序,沒有渲染隊列,沒有透明渲染,沒有Batch,沒有PostProcessing。。。沒有的東西太多了,但是路一步一步走吧。
  • 多光源前向渲染框架
    這個參考了Unity的一些設計(但是暫時簡化了),光源相關的pass分爲ForwardBase和ForwardAdd (還有一個ShadowCaster沒實現)。一個材質中可以包含任意多的pass,按順序逐個渲染。如果是ForwardBase 的Pass,會輸入最重要的平行光,並只渲染一次該Pass。如果是ForwardAdd的Pass,會輸入其他多個光源,包含平行光和點光源,並且對於每個光源,渲染一次該Pass,並且把本次渲染的結果疊加到上一次。其他Pass只渲染一次,包括ShadowCaster和非光照Pass。注意,熟悉Unity的同學可能會說你這也不對啊,ForwardBase裏面還能處理點光源呢!是的,所以說是簡化了 ,因爲這些其實是關係到效率的東西,暫時不急加,等mini3d.js實現了很多看上去很棒的東西后再開始優化。
  • 材質的實現
    爲了和前向渲染框架配合,實現了一個材質類,考慮到開發速度,沒有搞材質文件,直接用代碼實現自定義材質,但是提供了一個框架,用來定義材質包含的Pass,需要的Unifrom,以及每個Pass使用到的頂點屬性。系統提供了很多系統公用Uniform,只要在材質初始化時描述一下用到的uniform類型,就會在渲染前自動填充,並且材質也可以使用自定義Uniform,需要自己在合適的時候設置。基於這個框架,理論上可以實現任意渲染效果(PostProcessing除外,因爲還沒實現GrabPass)。目前簡單實現了基於Blinn-Phong模型的逐頂點和逐像素光照材質,未來實現ShadowMap後會實現一個標準材質,後期還會實現PBR材質。當然卡通渲染,菲涅爾反射,CubeMap反射,玻璃折射,海水渲染這些都會一一嘗試一下。
  • 其他
    新增了程序生成模型,目前只能生成立方體和平面。其中平面可以定義寬度長度和分段數,可以創建爲wireframe模型(由於WebGL不支持全局的wireframe模式,所以採用GL_LINES繪製)

Next

  • Normal Mapping : 由於Obj格式不帶切線數據,還需要自己計算出切線。(如果用Unity,Unity直接就給你切線了,所以自己從零開始擼能學很多東西吧,之前說的頂點法線計算就是)
  • RenderTexture的封裝
  • PostProcessing 這個主要是要做個框架出來,可以嘗試幾種效果
  • Shadow Mapping 這個在很多教程裏面很簡單就出來效果,但是實際實現的時候很多坑,而且我們需要軟陰影。
  • Shader變體:也許某個時刻我覺得必須要實現了,否則會阻礙實現新的效果。但估計會對代碼結構調整比較大
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章