????????最近在做Three.js相關(guān)的一些工作列林,其中需要對構(gòu)建好的mesh動態(tài)改變其著色器瑞你,于是就做了下面的修改
this.mesh.material.vertexShader = material.vertexShader;
this.mesh.material.fragmentShader = material.fragmentShader;
????????因為mesh是不斷創(chuàng)建、添加到scene中希痴,這就造成了一個問題者甲,著色器已經(jīng)修改完畢,在場景中應(yīng)該按照修改完的著色器的值來展示砌创,但現(xiàn)實卻不是过牙,而是一部分按照后來修改的著色器展示甥厦,一部分沒有按照修改完的著色器展示,也就是說--修改后的著色器使mesh的展示寇钉,一部分正常刀疙,一部分異常,這是為什么呢扫倡?
????????借助調(diào)試Spector.js工具的先看到修改之前的著色器谦秧,這里只看一個典型值NUMBER_OF_TEXTURES,修改shader之前是4撵溃;修改之后依然是4疚鲤。
????????是不是覺得很怪異,圖片是我偷懶復(fù)制粘貼的缘挑,但情況就是這樣集歇,why???
吾日三省吾身,著實經(jīng)過一番痛苦的自查语淘,自認為在代碼賦值這一塊應(yīng)該是沒問題的诲宇,那這是什么問題?惶翻?姑蓝?
后來就仔細跟了一下Three.js的源碼,發(fā)現(xiàn)在其內(nèi)部使用了一個叫WeakMap的鍵值對集合吕粗,搜索一下纺荧,巴拉巴拉一大堆,核心就最后一段
????????再看一下Three.js是如何使用這個東西的
在Three.js中這個類會將要渲染的material存放在這里面颅筋,等下次渲染時候會從這個緩存中查找宙暇,如果存在,就直接使用緩存中的shader议泵,恍然大悟占贫,原來如此;
????????上面三幅圖就是造成我修改shader失敗的核心肢簿,回過頭再看一下WebGLProperties這個類,它有一個remove函數(shù)蜻拨,正好使用就是WeakMap的方法池充,那就每次修改著色器之前把當前的material從鍵值對中移除就好了吧?
? ? ? ? 那么就把代碼做點修改吧缎讼,增加下面一句
? ? ? ? 代碼跑起來收夸,結(jié)果已經(jīng)可以預(yù)見。
????????僅此血崭,記錄一下Three.js的踩坑之旅卧惜。