在Three.js中動(dòng)態(tài)改變meterial的著色器的不起作用的問題

????????最近在做Three.js相關(guān)的一些工作,其中需要對(duì)構(gòu)建好的mesh動(dòng)態(tài)改變其著色器,于是就做了下面的修改

this.mesh.material.vertexShader = material.vertexShader;

this.mesh.material.fragmentShader = material.fragmentShader;

????????因?yàn)閙esh是不斷創(chuàng)建、添加到scene中,這就造成了一個(gè)問題,著色器已經(jīng)修改完畢,在場(chǎng)景中應(yīng)該按照修改完的著色器的值來展示,但現(xiàn)實(shí)卻不是,而是一部分按照后來修改的著色器展示,一部分沒有按照修改完的著色器展示,也就是說--修改后的著色器使mesh的展示,一部分正常,一部分異常,這是為什么呢?

????????借助調(diào)試Spector.js工具的先看到修改之前的著色器,這里只看一個(gè)典型值NUMBER_OF_TEXTURES,修改shader之前是4;修改之后依然是4。


shader修改之前


shader修改之后

????????是不是覺得很怪異,圖片是我偷懶復(fù)制粘貼的,但情況就是這樣,why???

吾日三省吾身,著實(shí)經(jīng)過一番痛苦的自查,自認(rèn)為在代碼賦值這一塊應(yīng)該是沒問題的,那這是什么問題???

后來就仔細(xì)跟了一下Three.js的源碼,發(fā)現(xiàn)在其內(nèi)部使用了一個(gè)叫WeakMap的鍵值對(duì)集合,搜索一下,巴拉巴拉一大堆,核心就最后一段


Why WeakMap


????????再看一下Three.js是如何使用這個(gè)東西的

WebGLProperties


在Three.js中這個(gè)類會(huì)將要渲染的material存放在這里面,等下次渲染時(shí)候會(huì)從這個(gè)緩存中查找,如果存在,就直接使用緩存中的shader,恍然大悟,原來如此;


修改后的shader
緩存中的shader


最后返回的shder

????????上面三幅圖就是造成我修改shader失敗的核心,回過頭再看一下WebGLProperties這個(gè)類,它有一個(gè)remove函數(shù),正好使用就是WeakMap的方法,那就每次修改著色器之前把當(dāng)前的material從鍵值對(duì)中移除就好了吧?

WeakMap的remove方法

? ? ? ? 那么就把代碼做點(diǎn)修改吧,增加下面一句

修改后的賦值方式

? ? ? ? 代碼跑起來,結(jié)果已經(jīng)可以預(yù)見。

????????僅此,記錄一下Three.js的踩坑之旅。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容