【Blender】Geometry Node 像素風

帽捲
Maochinn
Published in
10 min readNov 1, 2023

先看結果,這篇要介紹怎麼用Geometry Node做出像素風的圖片

事實上,這種效果不需要特別使用Geometry Node也可以完成,但是最近在學Geometry Node,就拿來實驗看看。

首先先介紹一下初始設置,Blender 3.4,基本上就是上方Geometry Nodes的layout,方塊也是預設的cube。

因為主要是用Geometry Nodes,所以大部分的操作會集中在左下角的Geometry Node Editor。

預設的Geometry Node長這樣,非常好理解

但是Geometry是什麼呢?我們可以透過左上角的Spreadsheet可以看到一些端倪,畫面中的Cube中含有一個Geometry,而一個Geometry其實就表示所有3D空間上的(幾何)資訊,例如:一個Cube由8個Vertex、12條Edge、6個Face所構成,其中,每個面又有4個點,因此有24個Face Corner,以上這些都是Cube中的Geometry所包含的資訊。

這邊你可能有個小疑問,一個cube到底是8個點還是24個點,因為本篇不會使用到Face Corner,因此只需先理解成一個Cube有8個點就好。

可以注意到這邊8個Vertex,它其實就是對應我們在Edit Mode中Cube的8個點。

接下來將Geometry Node拉成這個樣子

我們直接用Grid取代掉Input,它會輸入長、寬以及水平、垂直方向要產生幾個vertex,之後會產生一個網格,如果我們個別輸入Size X = 21、Size Y = 9、Vertices X=21、Vertices Y=9 會產生類似下圖這樣的一個平面,只是在Geometry Node產生的點沒辦法在Edit Mode編輯,所以你看不見這些點。

可以注意到,因為用Grid取代掉Input,因此目前產生的Geometry(Grid)與原始的Geometry(Cube)無關,因此無論你在Edit Mode怎麼樣調整你的Cube都不會對Grid有影響。

為了方便調整,可以將Grid的輸入拉到Input上,如此就能透過Property Panel直接調整長寬。

接下來要產生21*9個Cube在每個Vertices的位置上,可以透過Instance on Points,將原始的Geometry(Cube)作為Instance,放在每個Points上,而每個Point當然就是Grid輸出的Mesh,也就是將Grid中每個21*9個Vertices作為21*9個Points,最後將其輸出就完成了。

白話來說,就是將Cube複製21*9個放在個別的位置上面,其中因為每個cube的geometry都相同,所以可以稱之為instance。另外注意Spreadsheet,我們目前的輸出都是Instance,而沒有任何的Vertex之類的,其實Vertex是就是原本的Cube,因此只需儲存一份在內部即可。

這邊可以注意到總共有21*9=189個Instance,雖然我們知道他們的Geometry是是相同的,但是每個geometry整體有各自的position, uv_map, rotation。

接下來,為了後續方便,我們需要將所有Instance合併成一個Geometry,可以透過Realize Instances,使用後在畫面上不會有變化,但是在Spreadsheet可以發現Instance變成0,Vertex的數量變成8*21*9 = 1512了。

注意到uv_map的部分,前8個vertex的uv是相同的,這是因為前8個vertex組成第一個Cube的Geometry,因此前8個uv_map則對應上上圖第一個uv_map,以此類推。

接下來我們要將每個uv_map值傳到shader editor中,在Shader Editor中加入Atrribute,並且填入uv_map,就可以得到右圖的結果,就像是低像素的uv,因為每個cube都只填入一個顏色,也就是Grid對應的uv,因此只有21*9個色彩而已。

接下來我們要利用這個uv去採樣texture,有兩種做法,一般的做法是在Shader Editor中加入Image texture,另一種則是在Geometry Node中採樣Texture完再將顏色輸入到Shader Editor,前者是傳統的作法,而後者的理論上效率較高。

首先在Geometry Node中增加Named Attribute、Image Texture以及Capture Attribute,在前者的Name填入uv_map,並將其輸入到Image Texture的Vector,也就是將uv_map的值作為採樣Texture的uv座標,最後將採樣到的貼圖輸出出去。

同時,因為我們現在輸出的Attribute是自己多加的,因此我在Property Panel中將Attribute命名成color,可以在Spreadsheet中發現Vertex多了一個Attribute叫做color。

另外,在Shader editor中也要增加Atrribute,並且填入color,如此就可以得到我們想要的結果,這邊因為我們圖是3508x2450,因此我將SizeX改成35,SizeY改成24,當然如果想要更高的解析度可以將SizeX改成350,SizeY改成240就可以得到最開頭的結果了。

另外一種作法如下,利用Store Named Attribute將color附在instance上,如此就不需要透過Realize Instances,這是因為Group Output新增的Custom Atrribute不會依附在Instance上而是依附在vertex上,因此要透過Store Named Attribute Node來手動依附(binding)。

Group Output的屬性預設都是附在Vertex上,這是因為系統不知道你要將Custom Attribute附在Vertex、Face或是Instance之類的東西上,因此預設就是Vertex。

可以發現Spreadsheet中每個Instance多了一個color的attribute。

然後在Shader Editor中記得將Attribute Node的Type改成Instancer,表示拿Instance中的color。

這種做法在instance多的時候會發現有點卡頓的情況,這是因為每一幀都重新產生一堆instance,優點是不需要花費記憶體存大量的geometry,而一開始的方法則是產生一次instance後就轉換成Geometry存在記憶體中,也就是空間換取時間,這當然就看自己的取捨了。

--

--