Github霸榜:從零開始學3D著色器編程

2021-01-12 新智元

新智元原創

來源:Github

編輯:元子

【新智元導讀】這篇教程是今日GitHub趨勢榜第一,一天便達到了1500星。主要介紹了通過使用Panda3D遊戲引擎和OpenGL著色語言來為3D遊戲添加紋理,法線貼圖,泛光,環境遮擋等等。教程內容十分豐富,動圖也非常生動。

Shader,是運行在GPU上的程序,中文稱為著色器。它的主要用途是對三維物體進行著色處理,對光與影進行計算,以及控制紋理顏色的呈現等,最終,將遊戲引擎中的幾何數據轉化為屏幕上的模型、場景以及特效。

吃雞、農藥、戰地、塞爾達…都離不開著色器,著色器被譽為照亮虛擬世界的"魔法"。 著色器還可以用來做後期處理,類似PS。

著色程序是一整套編譯好並連結在一起的著色器的集合。著色器shader的編寫需要使用著色語言GL Shader Language(GLSL),GLSL的語法與C語言很類似。

著色器編程不光是對開發技能的考驗,更是對程式設計師想像力的挑戰,以至於有說法稱會寫Shader的程式設計師是站在食物鏈頂端的人。想成為遊戲開發高手,著色器編程是必備技能。

有興趣在3D遊戲中添加紋理,光照,陰影,法線貼圖,環境光遮蔽了嗎?好極了!今天新智元為大家帶來一個Github項目,從零開始教會大家進行3D遊戲著色。

以下一系列著色技術,都是具有高可移植的技巧,無論是Godot還是Unity都將適用。通過這些技術,你的遊戲視覺效果將提升到新的高度。

對於著色器之間的粘合劑,作者選擇了神器Panda3D遊戲引擎和OpenGL著色語言(GLSL)。

Panda3D是一個強大的渲染引擎。核心渲染模塊基於C++開發。Panda3D提供了Python的腳本化實用接口。

本項目code在以下環境下測試通過。

Linux manjaro 4.9.135-1-MANJAROOpenGL renderer string: GeForce GTX 970/PCIe/SSE2OpenGL version string: 4.6.0 NVIDIA 410.73g++ (GCC) 8.2.1 20180831Panda3D 1.10.1-1

本文只對該repo做一個大致介紹,具體代碼及講解請參閱項目地址:

https://github.com/lettier/3d-game-shaders-for-beginners.git

運行示例代碼需要先build

如果你想運行示例代碼,首先要先build。根據不同平臺安裝對應版本的Panda3D。其次,Clone項目repo,進入目錄,開始編譯。

Linux:

g++\ -c main.cxx \ -o 3d-game-shaders-for-beginners.o \ -std=gnu++11 \ -O2 \ -I/usr/include/python2.7/ \ -I/usr/include/panda3d/

編譯完成後執行:

g++\ 3d-game-shaders-for-beginners.o \ -o 3d-game-shaders-for-beginners \ -L/usr/lib/panda3d \ -lp3framework \ -lpanda \ -lpandafx \ -lpandaexpress \ -lp3dtoolconfig \ -lp3dtool \ -lp3pystub \ -lp3direct \ -lpthread

Mac:

clang++\ -c main.cxx \ -o 3d-game-shaders-for-beginners.o \ -std=gnu++11 \ -g \ -O2 \ -I/usr/include/python2.7/ \ -I/Developer/Panda3D/include/

編譯完成後執行:

clang++\ 3d-game-shaders-for-beginners.o \ -o 3d-game-shaders-for-beginners \ -L/Developer/Panda3D/lib \ -lp3framework \ -lpanda \ -lpandafx \ -lpandaexpress \ -lp3dtoolconfig \ -lp3dtool \ -lp3pystub \ -lp3direct \ -lpthread

坐標系統

開始插手著色器代碼之前,需要對3D物體的坐標系統有所了解。和在立體幾何的坐標系意義,繪製3D物體也是需要x、y、z三個坐標軸的值。

將定義好的坐標軸的值轉換為實際繪製的坐標,需要經過五個坐標系統的轉換。

模型空間

相對於原點 (0,0,0) 而自定義的起始坐標點。

世界空間

世界空間就是當所有物體一起繪製、仍然相對於原點的、更大的一個坐標系。可以防止模型出現扎堆兒情況。

觀察空間

將世界空間的坐標轉化為攝像機的視角所觀察到的空間坐標。

裁剪空間

根據我們的需要來裁剪一定範圍內的物體,而在這個範圍之外的坐標就會被忽略掉,實質上還是進行坐標的操作。

屏幕空間

將坐標投射到屏幕上。

渲染到紋理

渲染到紋理(Render To Texture, RTT)是現在很多特效裡面都會用到的一項很基本的技術,實現起來很簡單,也很重要。

渲染到紋理是為了實現一些特殊的效果,比如一個光滑的球體,它應該是可以反射周圍環境的,這個時候就需要先渲染到紋理。

在此設置中,示例代碼執行以下操作:

存儲幾何數據(如頂點位置或法線)供以後使用存儲材料數據(如漫反射顏色)供以後使用UV映射各種紋理(漫反射,普通,陰影等)計算環境光,漫反射光,鏡面光和發光光呈現霧

紋理和光照(Lighting)

紋理涉及使用UV坐標將一些顏色或一些其他類型的矢量映射到片段。 U和V的範圍從0到1。每個頂點都獲得一個UV坐標,並在頂點著色器中輸出。

完成lighting涉及到計算和組合環境光、漫反射光、鏡面光和發射光方面。示例代碼使用Phong lighting。Diffuse代碼:

// ...float diffuseIntensity = max(dot(normal, unitLightDirection), 0.0);if (diffuseIntensity > 0) {// ... }// ...

法線貼圖

法線貼圖(英語:Normal mapping)是一種模擬凹凸處光照效果的技術,是凸凹貼圖的一種實現。法線貼圖可以在不添加多邊形的前提下,為模型添加細節。常見的使用場景是為低多邊形模型改善外觀、添加細節,此時的法線貼圖一般根據高多邊形模型或高度貼圖生成。

頂點代碼:

// ...uniform mat3 p3d_NormalMatrix;// ...in vec3 p3d_Normal;// ...in vec3 p3d_Binormal;in vec3 p3d_Tangent;// ... vertexNormal = normalize(p3d_NormalMatrix * p3d_Normal); binormal = normalize(p3d_NormalMatrix * p3d_Binormal); tangent = normalize(p3d_NormalMatrix * p3d_Tangent);// ...

描邊

描邊著色器需要一個輸入紋理,用於檢測邊緣中的顏色。此輸入紋理的候選者包括材質的漫反射顏色、漫反射貼圖的顏色、頂點法線,甚至法線貼圖的顏色。

uniformstruct {vec4diffuse;}p3d_Material;outvec4 fragColor;voidmain() {vec3diffuseColor = p3d_Material.diffuse.rgb;fragColor = vec4(diffuseColor, 1);}

霧化、全屏泛光

霧(fog,或在Blender中稱為mist)將霧氣效果添加到場景中,提供神秘感和柔化。

// ...uniform structp3d_FogParameters { vec4 color ; float start ; float end ; } p3d_Fog;// ...

Panda3D提供了一個很好的數據結構,可以保存所有fog參數,你也可以手動將其傳遞給著色器。

Bloom有時候也叫Glow效果,中文一般叫做「全屏泛光」,可以使得發光物體看起來更逼真。

屏幕空間環境光遮蔽(SSAO)

環境光遮蔽(AO,ambient occlusion),大致上指的是幾何物體的拐角處,因為受光不全面(被相鄰的面擋光/遮蔽),導致變暗。屏幕環境光遮蔽技術使用了屏幕空間場景的深度而不是真實的幾何體數據來確定遮蔽量。這一做法相對於真正的環境光遮蔽不但速度快,而且還能獲得很好的效果,使得它成為近似實時環境光遮蔽的標準。

下面動圖展示了用AO和沒用AO的區別。用了AO,物體拐角的地方會變暗看起來就更逼真。

景深

景深(英語:Depth of field, DOF)景深是指相機對焦點前後相對清晰的成像範圍。在光學中,尤其是錄影或是攝影,是一個描述在空間中,可以清楚成像的距離範圍。

雖然透鏡只能夠將光聚到某一固定的距離,遠離此點則會逐漸模糊,但是在某一段特定的距離內,影像模糊的程度是肉眼無法察覺的,這段距離稱之為景深。

景深淺則模糊範圍大,虛化效果明顯。反之則虛化效果減弱。焦外代碼示例:

//...vec4result = vec4(0);for(int i = 0; i < size2; ++i) {x = size - xCount;y = yCount - size;result+=texture(blurTexture,texCoord+vec2(x * separation, y * separation));xCount-= 1;if(xCount < countMin) { xCount = countMax; yCount -= 1; }}result = result / size2;//...

色調分離和像素化

色調分離是指一幅圖像原本是由緊緊相鄰的漸變色階構成,被數種突然的顏色轉變所代替。這一種突然的轉變,亦稱作「跳階」。色調分離其實就是用來製造分色效果。

將3D遊戲像素化使他看起來很有趣,並可以節省時間,不必手動創建所有的像素藝術。和色調分離相結合,可以打造真正的復古外觀。

參考連結:

https://github.com/lettier/3d-game-shaders-for-beginners.git

相關焦點

  • 從零開始怎麼學計算機編程?
    於是很多人想投身其中,而且很大一部分都是零基礎非科班的狀態。在學習者中有大學生,也初高中生,他們都有一個共性,沒什麼基礎。從零基礎開始學習編程成為了一種常態,可是,也正是因為我們在編程方面是零基礎,很容易導致我們選錯專業和行業。從零開始學習電腦如何才能保證學好呢?以下為大家做一個簡單的總結,希望我們能在學習時有所參考。
  • 從零開始學Arduino編程
    本文基於Getting Started With Arduino(建議初學者購買),重點連載從零開始學習Arduino的基礎編程知識和詳細程序實現,只針對剛拿到Arduino但基本無編程經驗的同學,高手請繞行。
  • 適合Java新手的開源項目集合——在 GitHub 學編程
    興趣是最好的老師,HelloGitHub 就是幫你找到編程的樂趣。讓我們開始~一、青銅萬事開頭難1.1 快樂的小鳥作為整篇文章的開頭,我選擇了一個比較輕鬆好玩的項目,希望能夠勾起你對編程的興趣每一部分都用了一張思維導圖來整理出各個知識點,既能夠對將學知識的大致了解,也方便了學習後,對已學知識的鞏固複習,可以說良心到不行。你完全可以按照自己的節奏,學習的進度去查看每一個知識點。
  • GitHub中文趨勢榜第一!「2020新冠肺炎記憶」項目已獲4.9K星標
    這兩天,又一個關於新冠肺炎的 GitHub 登上了中文趨勢榜的首位,截至目前,已經收穫近 5K Star,600+ Fork。項目介紹nCovMemory 項目的中文名稱是「2020新冠肺炎記憶:報導、非虛構與個人敘述」,創立該項目的目的是為研究人士提供方便自然語言處理、疫情防治取用相關資料的資料庫。
  • 學編程不止是為做程式設計師,編程貓小火箭學員家長:學編程,是培養思維...
    學編程不止是為做程式設計師,編程貓小火箭學員家長:學編程,是培養思維的好方式 2020年03月25日 10:26作者:網絡編輯:王動   國家之爭的內核是經濟之爭
  • GitHub趨勢日榜第一
    GitHub趨勢日榜排名全球第一,已斬獲2K+星。為什麼這麼火?因為這是一本基於TensorFlow 2.0 正式版的中文深度學習開源書。還包含電子書和配套原始碼。從目錄章節構成來看,理論與編程並不是獨立分開,而是隨著難度的遞增,循序漸進、穿插編排的。大體上可以分為四個部分。第一部分是1-3章。主要介紹人工智慧的初步認知,並引出相關問題。
  • Github標星過萬,Python新手100天學習計劃,這次學不會算我輸!
    大數據文摘編輯部出品作為目前最火也是最實用的程式語言,Python不僅是新手入門程序界的首選,也逐漸成為了從大廠到小廠,招牌需求list的必要一條。當然,學Python這件事情,你可能也和文摘菌一樣,已經下了一百次決心,但是最後都「從入門到放棄」。
  • Github中文項目排行榜,你永遠想不到開發者都用它幹了什麼
    當然,還是有編程指南、機器學習之類的正經項目。不久前,有 GitHub 用戶吐槽說,GitHub 的每日趨勢榜不按照國家和地區來區分,使得榜單上總會有很多點讚量很大的中文項目,有時候甚至會佔據半壁江山。這位用戶呼籲,GitHub 應該按照開發者所屬國家和地區進行項目排行。
  • 從零開始學電路基礎- -從零開始學電路基礎,初學者們看這裡~~~
    導讀:從零開始學電路基礎,這篇文章志在讓親們快速掌握電路基礎知識,為以後學習更深入的知識打下基礎,從零開始學電路基礎是專門針對初學者的,大神們請自覺飄過~~~本文引用地址:http://www.eepw.com.cn/article/268472.htm  電路的概念
  • 從零開始學習ST/SCL程式語言
    首先看下什麼是SCL語言:SCL語言是一種結構化文本,類似於計算機高級語言的編程方式,他的語言規範解決計算機的PASCAL語言。S7-SCL(Structured Control Language 結構化控制語言) 具有以下特點:· 1、是一種類似於PASCAL的高級程式語言· 2、符合國際標準IEC 61131-3· 3、PLCopen基礎級認證· 4、適用於 S7-300 (推薦CPU314以上), S7-400,S7-1200,S7-1500, C7
  • Python視頻教程網課編程零基礎入門數據分析網絡爬蟲全套Python...
    Python視頻教程網課編程零基礎入門數據分析網絡爬蟲全套Python視頻教程 2020年07月08日 11:00作者:黃頁編輯:黃頁 本課程為
  • 核心功能全部開源,雖霸榜GitHub,但怎麼賺錢?|陶建輝
    集群開源後,在GitHub趨勢榜上連續5天霸榜 另外一方面,基礎軟體必須面向全球市場MongoDB就是採用的AGPL,一年前,開始使用自己的帶有更強限制的開源協議,其目的是不容許雲廠商免費使用。 還有一點需要明確的是,我們開源的協議是可以更改的,等我們有時間,我們將制定一個僅僅限制雲廠商使用的開源協議,只是已經release的版本按照當時的開源協議執行即可。採用AGPL是我們目前這個階段,最簡單最合適的保護方式。
  • 如何系統地從零開始學習PLC?
    PLC在現在的人懂的人看來,的確是比較簡單的東西,畢竟它屬於應用類型的二次編程開發。但是作為一個零基礎初學者,要學PLC,還是要付出一定的時間來摸索的。先要明白PLC本質是繼電器電路的軟體化,也就是在電腦上畫畫繼電器電路圖,這個是它的根本,所以在學習PLC之前,你一定要有點電工基礎,理解和實操過繼電器電路的使用,這個是非常重要的,畢竟PLC軟體的東西都是在模擬硬體電路,請關注:容濟點火器作為一個過來人,我當年也是從零開始學PLC的中國的大學教育,因為很多原因,往往比較重視理論教育,而在學校裡邊的動手機會是沒有那麼多的,特別是
  • 張藝興新專《夢不落雨林》正式發售,霸榜酷狗專輯銷量榜
    2018年10月19日,在北美以「超級新人」身份出道的張藝興攜第三張個人專輯《夢不落雨林/NAMANANA》,於北京時間15:00,在酷狗音樂平臺開始發售,中英文雙碟22首原創歌曲同步出發,主打歌帶你進入張藝興的「夢不落雨林」,一同體會跌宕起伏的冒險之旅。
  • 又現霸榜「神跡」,10個國服猴子稱號被1人全部拿下,堪比九日!
    雖然說王者榮耀是一款難度相對簡單的遊戲,想要打上王者段位並不難,但是要挑戰王者榮耀中的各項紀律就比較難了,比如騷白的333連勝,沒用一些手段基本不可能達成,當然還有之前的國服第一貂蟬憑藉個人實力創造的霸榜「8個國服稱號」的紀錄!
  • 信息學奧賽太原市集訓隊零基礎選拔活動通知
    【信息學奧賽暑期一個月衝獎】 關於信息學奧賽太原市集訓隊、 預備隊隊員零基礎選拔活動的通知楊老師有豐富的信息學奧賽選材和培訓經驗,在短短的三個月中就讓零基礎的學員拿到一等獎。在青少年編程普及的工作中,採用國際信息學奧賽金牌教學體系,讓零奧數、零編程基礎的孩子,在短時間內掌握C++語言,算法,數據結構知識和思維結構,衝擊信息學奧賽小學普及組、初高中提高組獎牌。
  • 不用從零學android入門編程,這款傻瓜式開發工具,快速製作App
    現在,不需要從零開始學android編程技術,任何人都可以輕鬆製作手機APP。國外的網際網路巨頭:比如谷歌的輕代碼 H5 應用開發工具——App Maker,微軟的PowerApps,就是通過拖拽式的進行應用開發。
  • Unity粒子遇上著色器,引爆視覺特效
    下面來分析粒子系統驅動的數據,Michał使用粒子的尺寸(Size)和顏色(Color)來控制一些著色器參數。如下圖所示:  最後提交大賽評審的版本,事實已經禁用了粒子渲染,因為這些粒子只是為了將數據傳遞給著色器,不會執行任何其它操作。 下面的操作視頻打開了粒子渲染,幫助大家理解特定參數的調整所引起的變化: 那這些粒子到底是如何驅動著色器的呢?
  • 韓遊榜:《黑色沙漠》上漲4位 《絕地求生》霸榜6周
    [摘要]《黑色沙漠》加入新角色,升至12月第三周的韓遊榜第15位,《絕地求生》連續霸榜六周。12月第三周,曾經的期待大作《黑色沙漠》急速上升值得關注。
  • 制霸輸出榜,當前神威魔王究竟強在哪裡?
    武神壇巔峰賽常規賽賽事正酣,截止第二周比賽結束,當前場均角色傷害榜前8名中,魔王寨玩家制霸榜單,佔據4個名額之多。 其餘法系門派——龍宮、小雷音雖也有出現過,但根本無力與魔王競爭。