在pixi中使用你的自定義著色器

2022-07-09 11:06:11 字數 2698 閱讀 8835

通過幾天的學習,對opengl、shader有了乙個大致的了解。

回到學習的初衷吧,在基於pixi.js重構d3專案的時候,因為精靈層級的問題,我得按照一定的先後順序將不同類別的精靈新增到場景中去。

例如:針對人物關係的關係圖譜,所有的關係線必須要在所有的任務面板下面,但是移動人物面板的時候,與之關聯的關係線也要重新繪製;

所以刪除精靈之後再新增精靈使得層級增加的做法就有點不適用了(這會導致當前操作的關係線的層級提公升,很顯然,這不是我們所想要的)。

因此,我們每次操作,都要重新將所有的精靈(處理好新的位置之後),分批次新增到場景中,這就導致出現下面的**:

人物面板是一類精靈,關係線又是一類精靈,所以我們要用到兩個for迴圈,並且順序還得講究(先for迴圈關係線,再for迴圈人物面板);

這樣一來,如果頁面中有10000個人物面板(相對應的就有10000條關係線),那麼就要for迴圈10000+10000=20000次,針對拖拽操作,每觸發一次移動就要for迴圈20000次,

經過測試,由於精靈陣列是存於記憶體中的,for迴圈的時候很方便,但是對cpu的消耗很高!

當時,遇到這個問題的時候,朋友說可以將這部分的for迴圈也讓gpu去執行,然後就看到了shader,進而學習了opengl;

學完之後,發現著色器程式的渲染模式可以用四個字概括:逐點繪製。確實解決了在cpu上執行for迴圈的問題。但是乙個錯綜複雜的人物關係圖譜,要用著色器去繪製的話(咱先不討論shader載入紋理的問題),是不是就失去了使用pixi.js的意義,而且這也將使得開發工作變得更加複雜。

所以,我決定,鑑於關係圖譜專案的特殊性,使用依次for迴圈的方式來處理精靈層級的問題。

分析完問題之後,我們還是要看看,在pixi中如何使用我們自定義的著色器程式。

一、pixi_shaders

提取碼:j5t9 

效果圖:

3個iframe,3個片元著色器效果。

二、著色器**分析

第三個iframe對應的shader,效果是顏色不斷變化

let width =window.innerwidth;

let height =window.innerheight;

let shaderfrag =`

precision mediump

float

; uniform vec3 iresolution;

uniform

float

itime;

void

main()

`;let container = new

pixi.container();

let filter = new pixi.filter(null

, shaderfrag);

filter.uniforms.iresolution = [width, height, 1.0

];filter.uniforms.itime = 1.0

;container.filters =[filter];

//animate the filter

filter.uniforms.itime += 0.1

;});

前面我們談到,著色器的渲染模式是逐點繪製,所以我們只要定義任意一點繪製方式就可以了,因為他會自動將我們的著色器**應用到指定區域內的每個畫素點上。

繪製方式,這個概念有點抽象了,實際上就是顏色,每個畫素點的顏色!!!

我們來看上面的著色器**:

let shaderfrag =`

precision mediump

float

; uniform vec3 iresolution;

uniform

float

itime;

void

main()

`;

這個著色器接收由外面傳入的兩個引數:三維座標iresolution和隨著時間遞增的時間引數itime;

let filter = new pixi.filter(null

,shaderfrag);

filter.uniforms.iresolution

= [width, height, 1.0

];filter.uniforms.itime

= 1.0

;container.filters = [filter];

然後著色器程式先將座標進行轉換**換為pixi適用的座標),

然後根據轉換後的座標(向量)和時間引數計算出三維顏色(rgb),著色器程式輸出的顏色常量gl_fragcolor是四維向量(rgba),所以我們人為地給他加上alpha通道值。

這樣一來,單個畫素點輸出的顏色就確定了,然後逐點繪製,螢幕上所有的點的顏色就渲染出來了。

此外,加上乙個pixi的動畫,通過改變itime引數的值,實現改變單個畫素點輸出的顏色值,這樣,我們看上去就是顏色不斷變化的螢幕了。

filter.uniforms.itime+= 0.1

;});

在自定義HttpHandler中使用Session

最近需要做乙個對特定請求進行響應的介面,只是在內部處理,不存在ui,機於這種情況,當然是使用實現ihttphandler來進行處理,可以減掉載入html 控制項的時間。本來都是這樣想的,對於ihttphandler 中定義了兩個方法,processrequest httpcontext ctx 和 ...

structs 在action中使用自定義方法

一般來講,action的預設方法為execute 也就是在執行乙個action時,會自動呼叫這個方法.但是,有時候我們希望乙個action具有多個方法,而不是去建立多個action.那麼我們就需要動態的決定到底使用action中的哪個方法.比如,在名為path的 action中,它具有兩個方法add...

在自定義HttpHandler中使用Session

最近需要做乙個對特定請求進行響應的介面,只是在內部處理,不存在ui,機於這種情況,當然是使用實現ihttphandler來進行處理,可以減掉載入html 控制項的時間。本來都是這樣想的,對於ihttphandler 中定義了兩個方法,processrequest httpcontext ctx 和 ...