Threejs 字体单独发光
(本文章純原創,轉載請標注)
先上效果圖
這里用的是three的后效EffectComposer,材質用的是UnrealBloomPass。
正常使用后效的代碼如下:
????????????var?renderPass?=?new?RenderPass(?scene,?camera?);
????????????var?bloomPass?=?new?UnrealBloomPass(?new?THREE.Vector2(?window.innerWidth,?window.innerHeight),?1.5,?0.4,?0.85 );
? ? ? ? ? ? var composer?=?new?EffectComposer(?renderer);
????????????composer.addPass(?renderPass?);
????????????composer.addPass(?bloomPass?);
然后每幀調用composer.render();
這時候會整個場景都發光,效果圖如下:
如果想要做到部分發光怎么辦呢?
我搜了網上其他人的代碼,比如我想讓鞋帶單獨發光
代碼如下:
????????????model_.traverse(function(obj)
????????????????????{
????????????????????????if(obj.isMesh)
????????????????????????????obj.layers.set(1);
????????????????????});
? ? ? ? ? ? ? ? ? ? xiedai.layers.set(0);
其實就是把鞋帶的層級設為0, 其他都設為1
render()中在composer.render();前后添加:
????????????renderer.clear();
????????????camera.layers.set(0);
????????????composer.render();
? ? ? ? ? ? render.clearDepth();
? ? ? ? ? ? camera.layers.set(1);
? ? ? ? ? ? renderer.render(scene,?camera);
效果圖如下
我們發現鞋帶沒了。。。。
真的沒了嗎?
我換了個角度看
鞋帶其實是在的,而且正常發光,只不過three后效的layer被原場景擋住了
而且還有個很坑的問題,就是three的后效只有layer為0的時候才會生效,其他層都不會顯示。
那該怎么辦呢?
于是我想了個辦法,讓后效按照我的順序渲染,所以就把UnrealBloomPass.js的render改了一下
具體做法如下:
先注掉外部render()中的這三行代碼
????????????//?renderer.clearDepth();
????????????//?camera.layers.set(1);
????????????//renderer.render(scene,?camera);
首先解決只有layer為0才有后效的問題,只要改一行代碼即可
找到fsQuad的定義,也就是this.fsQuad?=?new?FullScreenQuad(?null?);這行代碼
在下面加上this.fsQuad._mesh.layers.enableAll();
其實就是后效沒有在所有層級上生效導致的
我們再解決后效渲染問題
首先改一下UnrealBloomPass的構造函數,添加兩個參數 scene和camera
再添加到this屬性中,這個后面要用到
class?UnrealBloomPass?extends?Pass?{
????constructor(?resolution,?strength,?radius,?threshold,?scene,?camera?)?{
????????super();
????????this.renderScene?=?scene;
????????this.renderCamera?=?camera;
????????this.strength?=?(?strength?!==?undefined?)???strength?:?1;
定義UnrealBloomPass的時候要做相應的修改,把scene和camera傳入
var?bloomPass?=?new?UnrealBloomPass(?new?THREE.Vector2(?window.innerWidth,?window.innerHeight),?1.5,?0.4,?0.85,?scene,?camera?);
然后到UnrealBloomPass.js中的render()中
有兩個if?(?this.renderToScreen?)這樣的判斷
我們就修改這兩個地方
第一個判斷中注釋掉這行
//this.fsQuad.render(?renderer?);
在下面添加代碼
renderer.render(?this.renderScene,?this.renderCamera?);
第二個判斷
if和else中都注釋掉
//this.fsQuad.render(?renderer?);
然后在判斷外部添加
????????this.renderCamera.layers.set(1);
????????renderer.render(?this.renderScene,?this.renderCamera?);
????????this.fsQuad.render(?renderer?);
這樣就改好了 效果圖如下
這樣就實現了局部發光,但是隨即我有發現了個問題
就是透明材質會和背景混合
比如我的字體的背景就是透明的 跟黑色的背景混合了,如下圖:
字體雖然發光了,但是黑色背景擋住了模型,我能想到的辦法就是專門用一個層級去跟透明材質混合,所以我又進行了如下處理:
把字體背景擋住的材質放到一個新的層級
houpian.layers.set(2);
回到UnrealBloomPass的render(),在第一個上述renderToScreen的判斷中添加代碼:
this.renderCamera.layers.set(2);
就可以得到開頭的效果圖了
不過以上所有的做法都沒有封裝性,希望three官方能考慮到多個層級需要單獨后效的問題
完事
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?cslg.panda
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? 2021.6.22
總結
以上是生活随笔為你收集整理的Threejs 字体单独发光的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BigBrother的大数据之旅Day
- 下一篇: 快速傅里叶变换的应用——快速卷积