最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Godot Shader 地形材質(zhì)原理與著色器編程

2023-02-18 08:07 作者:緊果唄  | 我要投稿

?? ShaderMaterial Programming 著色器材質(zhì)編程

有個(gè)好消息,Godot 4.0 RC2 放出來了,正式版本奮斗在這?3 年之間終于快完成了!

Release candidate: Godot 4.0 RC 2

The Godot 4.0 release is mere days away!

https://godotengine.org/article/release-candidate-godot-4-0-rc-2/

雖然,這小節(jié)內(nèi)容是講材質(zhì)與著色器編程,但本質(zhì)上,是在講數(shù)學(xué)的應(yīng)用。編程只是使用數(shù)學(xué)工具的手段,作品效果就是最終產(chǎn)品。這中間要經(jīng)歷的內(nèi)容很多,根據(jù)不同數(shù)學(xué)基礎(chǔ)的人自然有不同的理解或不理解,或者難以理解。到目前為止,傅里葉級(jí)數(shù)及其應(yīng)用是給我最大觸動(dòng)的數(shù)學(xué)工具,3Blue1Brown 制作的一個(gè)圖形化傅里葉級(jí)數(shù)教學(xué)視頻以一種難以想象的直觀手段,將極度抽象的數(shù)學(xué)工具,用形象的動(dòng)畫形式展示在觀眾面前。這真的太棒了,盡管,數(shù)學(xué)的意義遠(yuǎn)不止如此,但通過動(dòng)畫形象地說明了數(shù)學(xué)在音樂、圖像、電子、通信等等領(lǐng)域的共通性。


Godot 材質(zhì)有三類,它們都可以使用節(jié)點(diǎn)編輯界面方式、或者使用著色器方式進(jìn)行編輯,與 4 個(gè)資源類型關(guān)聯(lián):

  • **spatial**? ? ?- for 3D rendering.

  • **canvas_item** - for 2D rendering.

  • **particles**? ?- for particle systems.

Spatial Material 材質(zhì)基于物理的渲染 PBR - Physically Based Rendering 技術(shù),自迪士尼在 SIGGRAPH 2012 上提出了著名的迪士尼原則的 BRDF(Disney Principled BRDF)之后,由于其高度的易用性以及方便的工作流,已經(jīng)被電影和游戲業(yè)界廣泛使用。

???? Displacemnet & Terrain 轉(zhuǎn)換貼圖與地形

置換貼圖是地形制作的基本工具,在 GPU 渲染管線上,頂點(diǎn)著色器是處理幾何體原始信息的工具,通過修改頂點(diǎn)坐標(biāo),使用原先的平面幾何體產(chǎn)生任何希望的效果。結(jié)合噪聲紋理,根據(jù)其像素的灰度值來修改頂點(diǎn)的高度坐標(biāo),就可以使用平面按照噪聲紋理隆起,或者凹陷,形成逼真的地形。


材質(zhì)中 Height 用于啟用視差高度貼圖,和 Normal Mapping 類似,是用于改變表面光線細(xì)節(jié)的貼圖。Godot 3.5 中使用 Depth 屬性表示視差貼圖。

另一種用于地形制作的置換貼圖,Displacement Mapping,Godot 沒有直接在材質(zhì)中提供設(shè)置,而只能通過著色器來實(shí)現(xiàn),即需要?jiǎng)?chuàng)建著色器材質(zhì),對(duì)幾何體的頂點(diǎn)進(jìn)行直接處理。

創(chuàng)建 PlaneMesh 幾何體

給場景添加 MeshInstance3D 節(jié)點(diǎn),并為其創(chuàng)建一個(gè) PlaneMesh 平面幾何體,然后為其創(chuàng)建著色器材質(zhì),點(diǎn)擊 ShaderMaterial 打開著色器設(shè)置,在 Shader 屬性中創(chuàng)建一個(gè) `Shader` 即著色器程序?;蛘?,可以使用 `VisualShader` 進(jìn)行可視化著色器編程。


Godot 提供了 GLSL 編程接口,與源始的 OpenGL 著色器編程不同的是,直接在單個(gè)著色器程序中編寫:

  • Vertex Shader 頂點(diǎn)著色器:`void vertex() { ... }`

  • ?Fragment Shader 片段著色器:`void fragment() { ... }`

  • ?Lighting 光照處理函數(shù);:`void light() { ... }`

使用可視化著色器編程的一個(gè)好處是更直觀,直接通過圖形界面就可以生成著色器代碼,通過節(jié)點(diǎn)連接實(shí)現(xiàn)和各種著色器數(shù)據(jù)的賦值。通過選擇要編寫的著色器,所有可用的輸出變量就直接顯示在 Output 節(jié)點(diǎn)中。


節(jié)點(diǎn)化編程和代碼編輯方式有思路層面的差異,比如代碼中使用 uniform 來定義全局變量來輸出紋理資源,在可視編程中,只需要放置一個(gè) Texture 節(jié)點(diǎn),就會(huì)自動(dòng)創(chuàng)建相應(yīng)的 uniform 變量。但是資源數(shù)據(jù)的使用方式是有很大差別的。可以使用 `Expression` 或者 `GlobalExpression` 節(jié)點(diǎn)編寫 GLSL 代碼,它們分別會(huì)在著色器全局作用域、函數(shù)作用域中生成相應(yīng)的代碼。


最新推出的 compute shaders 則需要使用底層的 `RenderingDevice` 訪問 Vulkan API 來實(shí)現(xiàn)。

Godot 可視化編程 - Vertex Shader?

注意:Godot 使用 xz 表示地平面,獲取頂點(diǎn)坐標(biāo)時(shí)可以轉(zhuǎn)換為?VERTEX.xzy。


Godot 光照函數(shù)


在創(chuàng)建材質(zhì)時(shí),有兩個(gè)選擇,可以給 MeshInstance3D 幾何節(jié)點(diǎn)或者 Mesh 資源附加材質(zhì),兩者都通用。

創(chuàng)建 ShaderMaterial

然后點(diǎn)擊著色器打開它,在其屬性面板中,可以通過工具菜單 Save 將著色器保存到文件中進(jìn)行編輯。

Display Wireframe 線框視圖

為了讓 PlaneMesh 可以表現(xiàn)凹凸曲面,需要對(duì)平面進(jìn)行細(xì)分,讓它擁有更多的頂點(diǎn),而不是只有 4 個(gè)頂點(diǎn)。Subdivision Width/Depth 設(shè)置合適的值,比如 256。為何查看細(xì)分的效果,可以打開線框視圖功能,Perspective -> Display Wireframe,這樣就會(huì)將細(xì)分的邊線顯示出來。


以下要實(shí)現(xiàn)這個(gè)簡單的地形著色器包含內(nèi)容:

  • ?一個(gè)噪聲紋理,通過 NoiseTexture 加載 OpenSimplexNoise 或者新版本的 FastNoiseLite;

  • ?一個(gè)頂點(diǎn)著色器處理函數(shù) `void vertex()`;

  • ?使用一個(gè) GLSL `texture()` 紋理采樣函數(shù);

  • ?定義一些全局的著色器變量,用于地形的海拔高度偏移、地形紋理縮放,高度差放大等等;

著色器中需要使用 GLSL `texture()` 紋理采樣函數(shù),其返回值包含指定坐標(biāo)上的像素值 RGBA。對(duì)于灰度紋理來說,RGB 三分量是等值的,而透明度分量 Alpha = 1。


需要注意:

  • 新創(chuàng)建的 PlaneMesh 頂點(diǎn)坐標(biāo)值為 [-1,1] 范圍,平面中心為零點(diǎn),大小為 2x2,而 UV 坐標(biāo)范圍總是是 [0,1]。

  • Godot 中的 XYZ 三軸,紅綠藍(lán)三色對(duì)應(yīng),Y 是垂直方向,XZ 才是地平面。

3D 環(huán)境中,平移、Size 等使用米制單位,1 表示 1 米,創(chuàng)建噪聲紋理使用的是像素??梢允褂萌呛瘮?shù)去觀測(cè) PlaneMesh 細(xì)分后的頂點(diǎn)坐標(biāo)變化。三角函數(shù)的周期是 2PI,對(duì)于一個(gè) 20x20 大小的平面,它在兩個(gè)維度上就有 3 個(gè)多的三角函數(shù)周期的變化。

使用三角函數(shù)觀測(cè)頂點(diǎn)坐標(biāo)數(shù)據(jù)

在著色器中定義的 uniform 全局變量,Godot 會(huì)進(jìn)行處理,并且在 ShaderMaterial 面板中提供設(shè)置操作,分組在 Shader Params。注意,如果著色器程序有語法錯(cuò)誤時(shí),參數(shù)就不會(huì)顯示在發(fā)展面板中。

為著色器定義的 Height Map 屬性創(chuàng)建噪聲紋理:


然后,再調(diào)整一下著色器提供的參數(shù),Shader Params:Scale/Translation/Offset/Multiply。

地形效果參考:

Displacement Mappng Principle

???? 法向量修正


經(jīng)過以上操作得到的地形還只是停留在曲面的階段,對(duì)于一個(gè)能在項(xiàng)目中使用的地形,還需要更多的功能。綠植裝飾、光照效果等等基礎(chǔ)材質(zhì)屬性,還要提供碰撞檢測(cè)等等功能。


光照處理涉及到法線,中學(xué)的物理定義,光線是直線傳播的,反射光則與表面法線向量形成和入射角相等的夾角。當(dāng)前的地形雖然經(jīng)過基本的頂點(diǎn)置換處理,得到了與地面一樣起伏的曲面。但是,其法線還是和原來新創(chuàng)建的PlaneMesh 一樣,即所有細(xì)分出來的片面都擁有一樣的法線。當(dāng)光線照射到這個(gè)曲面時(shí),光照效果和照在平面上沒有兩樣的!

法線錯(cuò)誤與正確狀態(tài)下的光照對(duì)比

在場景上添加一個(gè)燈光節(jié)點(diǎn),散光燈或直射光都可以,DirectionalLight,OmniLight。然后打開法線視圖 Perspective -> Display Normal,就可以看到這個(gè)問題,面沒有明暗差異。如果添加散光燈,曲面的明暗變化只跟光源的距離有關(guān),而與曲面的朝向無關(guān)。


法線數(shù)據(jù)保存在 Mesh 資源中,前面的著色器只是修改了頂點(diǎn)坐標(biāo),而沒有處理法線信息,使得法線錯(cuò)誤。修復(fù)法線朝向有兩個(gè)方法:

  • ?修改著色器內(nèi)置的 `NORMAL` 或者 `NORMAL_MAP` 向量;

  • ?使用向量貼圖修正法線;

在噪聲程序紋理工具中,可以按同樣的方式生成法線貼圖,即和紋理貼圖一致的法線信息,Noise Texture面板中勾選 As Normal Map 選項(xiàng)即生成法線貼圖。


在渲染流水線上,頂點(diǎn)處理和法線處理使用不同的著色器,頂點(diǎn)著色器一般專用于頂點(diǎn)處理。法線處理可以在片段著色器中處理。如果使用 OpenGL API,則需要加載兩個(gè)著色器程序。在 Godot 中已經(jīng)處理好著色器的加載,只需要在同一相著色器程序中編寫 `void fragment()` 函數(shù)即可。


OpenGL Shading Language 手冊(cè)簡化 GPU 渲染流水線如下,開發(fā)者主參與兩個(gè)階段:

  • 1. **Vertex Processor**

  • 2. Tessellation Control Processor

  • 3. Tessellation Evaluation Processor

  • 4. Geometry Processor

  • 5. **Fragment Processor**

  • 6. Compute Processor

GLSL 著色器語言從語法上講,和 C 語言無異,基本數(shù)據(jù)類似也一樣。但是作為 GPU 著色器,它提供了大量向量、矩陣、紋理等數(shù)據(jù)類型,并且基于它們提供了豐富的 API。GLSL 實(shí)際上是幾種密切相關(guān)的語言,這些語言用于為 API 處理管道中包含的每個(gè)可編程處理器創(chuàng)建著色器。因此,編程模型完全與 C 語言編程不一樣。官方文檔倉庫中包含一個(gè)單頁面的語言手冊(cè) GLSLangSpec.4.60.html。


另一個(gè)問題是,**頂點(diǎn)著色器**與**片斷著色器**是兩個(gè) GPU 程序,雖然在 Godot 中使用同一個(gè)著色器代碼文件。這兩個(gè)著色器會(huì)在 GPU 渲染流水線上依工序執(zhí)行處理,為了將頂點(diǎn)著色器的數(shù)據(jù)傳遞給片斷著色器,GPU 編程中提供了 varying 變量,


GLSL 的一大特色就是有各種修飾符號(hào)來決定變量的使用規(guī)則,參考修飾符說明。uniformvarying 很大不同在于,前者在處理一個(gè)基本體的過程中是不會(huì)改變的,用來鏈接 CPU 運(yùn)行的程序與 GPU 運(yùn)行的著色器。后者則更像是一般的 C 語言變量,可以在著色器程序中改變它的值,并實(shí)現(xiàn)不同著色階段中的數(shù)據(jù)傳遞。


存儲(chǔ)修飾符 Storage Qualifiers [4.3]

  • ?`none` (Default) local read/write memory, or input parameter.

  • ?`const` Compile-time constant, or read-only function parameter.

  • ?`attribute` Linkage between a vertex shader and OpenGL ES for per-vertex data.

  • ?`uniform` Value does not change across the primitive being processed, uniforms form the linkage between a shader, OpenGL ES, and the application.

  • ?`varying` Linkage between a vertex shader and fragment shader for interpolated data.

參數(shù)修飾符 Parameter Qualifiers [4.4]

  • ?`none` (Default) same as `in`.

  • ?`in` For function parameters passed into a function.

  • ?`out` For function parameters passed back out of a function, but not initialized for use when passed in.

  • ?`inout` For function parameters passed both into and out of a function.

輸入?yún)?shù)在調(diào)用函數(shù)時(shí)復(fù)制傳入,輸出參數(shù)在函數(shù)返回時(shí)復(fù)制輸出值。其它修飾符參考官方手冊(cè)。


朗伯照明理想鏡面散射光模型,表面不吸收任何入射光,Lambertian lighting model 實(shí)現(xiàn)如下,Godot著色器中提供了光照函數(shù)定義,通過修改這個(gè)函數(shù)可以實(shí)現(xiàn)自己的光照效果:

在主光源光強(qiáng)度為 1.0 的條件下,ALBEDO 紋理會(huì)按以上算法與法線、入射光方向,衰減系數(shù)等因素下生成模型表面的漫射光效果,通過調(diào)整基本色輸入來調(diào)整最終效果。

修正法線后的正確光照

從輸出效果可以看到,由于紋理使用的是 8-bit 顏色深度,精度不足導(dǎo)致“等高線現(xiàn)象”,可以降低 Bump Strength 屬性減緩,更好的辦法是使用?EXR、TTF、TGA 等支持?16-bit?以上的圖像格式。

頂點(diǎn)著色器與法線處理代碼參考:


?????參考

  • 本文代碼請(qǐng)自取 https://github.com/Jeangowhy/Godot-Tour/tree/main/Particles

  • [The OpenGL? Shading Language, v4.60.7] https://github.com/KhronosGroup/OpenGL-Registry/tree/main/specs/gl/GLSLangSpec.4.60.html

  • [Inigo Quilez - 2D distance functions] https://iquilezles.org/articles/distfunctions2d/

  • [Your 1st 3D shader] https://docs.godotengine.org/en/latest/tutorials/shaders/your_first_shader/your_first_3d_shader.html

  • [Your 2nd 3D shader] https://docs.godotengine.org/en/latest/tutorials/shaders/your_first_shader/your_second_3d_shader.html

  • [Multiple resolutions] https://docs.godotengine.org/en/latest/tutorials/rendering/multiple_resolutions.html

  • [Setting up the game area] https://docs.godotengine.org/en/stable/getting_started/first_3d_game/01.game_setup.html

  • [Matlab Help - Mathematical Functions] https://ww2.mathworks.cn/help/symbolic/mathematical-functions.html

  • [The OpenGL Shading Language] https://www.khronos.org/opengl/wiki/OpenGL_Shading_Language

  • [The Book of Shaders by Patricio Gonzalez Vivo & Jen Lowe] https://thebookofshaders.com/?lan=ch

  • [Shaders Programming] https://docs.godotengine.org/en/3.5/tutorials/shaders/index.html

  • [Shading language] https://docs.godotengine.org/en/3.5/tutorials/shaders/shader_reference/shading_language.html

  • [Godot Shaders] https://docs.godotengine.org/en/3.5/tutorials/shaders/index.html

  • [Particle shaders] https://docs.godotengine.org/en/3.5/tutorials/shaders/shader_reference/particle_shader.html

  • [Converting GLSL to Godot shaders] https://docs.godotengine.org/en/3.5/tutorials/shaders/converting_glsl_to_godot_shaders.html

  • [Sprite Shaders] https://github.com/godotengine/godot-demo-projects/tree/master/2d/sprite_shaders

  • [Screen Space Shaders] https://github.com/godotengine/godot-demo-projects/tree/master/2d/screen_space_shaders

  • [Voronoi and Worley? cellular) noise - Godot Shaders] https://godotshaders.com/snippet/voronoi/

  • [smoothstep desmos] http://www.desmos.com/calculator/309w4rkmpe

  • [雙曲函數(shù)基礎(chǔ)知識(shí) by Coston] https://zhuanlan.zhihu.com/p/363616604

  • [Inigo Quilez - 3D distance functions] https://iquilezles.org/articles/distfunctions

  • [Ray Marching and Signed Distance Functions] https://jamie-wong.com/2016/07/15/ray-marching-signed-distance-functions/

  • [傅里葉級(jí)數(shù)、傅里葉變換與頻譜 by Eugene Khutoryansky] https://www.bilibili.com/video/BV1sS4y1G7WF

  • [Spatial Material] https://docs.godotengine.org/en/3.5/tutorials/3d/spatial_material.html

  • [Principled BSDF] https://docs.blender.org/manual/en/latest/render/shader_nodes/shader/principled.html

  • [Physically Based Rendering: From Theory to Implementation, Third Edition] http://www.pbr-book.org/3ed-2018/contents.html

  • [基于物理的渲染(PBR)白皮書 - 毛星云] https://zhuanlan.zhihu.com/p/53086060


Godot Shader 地形材質(zhì)原理與著色器編程的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
舞阳县| 丰原市| 子长县| 镇原县| 曲沃县| 咸阳市| 沈阳市| 攀枝花市| 罗城| 南郑县| 孝义市| 广宁县| 香格里拉县| 玉田县| 西安市| 东海县| 遂平县| 江油市| 平塘县| 那曲县| 稷山县| 永登县| 吉隆县| 新闻| 博罗县| 当雄县| 霸州市| 德阳市| 布拖县| 湘潭市| 高州市| 涟源市| 西峡县| 郧西县| 如皋市| 澄江县| 柘城县| 土默特右旗| 武威市| 南木林县| 县级市|