Three.js Material transparent 兩個透明物體的渲染問題


原本想用兩個圓柱體實現盛滿液體的玻璃容器效果,如實有了如下代碼:

 1 var liquid = new THREE.Mesh(
 2   new THREE.CylinderGeometry(40, 40, 150, 32, 32),
 3   new THREE.MeshPhongMaterial({
 4     color: '#318414',
 5     emissive: '#318414',
 6     specular: '#22842c',
 7     shininess: 10,
 8     shading: THREE.FlatShading,
 9     transparent: true,
10     opacity: 0.5,
11   }),
12 );
13 
14 var tube = new THREE.Mesh(
15   new THREE.CylinderGeometry(45, 45, 150, 32, 32, true),
16   new THREE.MeshPhongMaterial({
17     color: '#3d79ff',
18     transparent: true,
19     opacity: 0.4,
20     shininess: 4,
21   }),
22 );
23 
24 SEDU.add( liquid, tube );

 效果如下:

 

 what? 效果不太對吧,里面綠色液體哪里去了???是不是透明造成的??修改一下試試看:

var tube = new THREE.Mesh(
  new THREE.CylinderGeometry(45, 45, 150, 32, 32, true),
  new THREE.MeshPhongMaterial({
    color: '#3d79ff',
    //transparent: true,
    opacity: 0.4,
    shininess: 4,
  }),
);

 

 

果然是transparent屬性造成的,但是這樣雖然顯示出來綠色液體的,但液體缺無法體現透明度了。

為什么一個transparent物體內的 另一個transparent物體無法顯示呢?

這是因為Three.js中 WebGLRenderer,會根據對象與攝像機的距離對象進行排序,並按照從最遠到最近的順序渲染透明對象。為了使兩個透明對象正確地呈現,后面的對象-也就是綠色液體-必須首先渲染。否則,由於深度緩沖區,它將根本不會渲染。因為我把他們兩個物體的坐標設為同一個坐標了,沒有了遠近的區別,所以綠色液體沒有被渲染。那么我們把 綠色液體的坐標稍微改動1個px是不是就能顯示出來了呢?

 

liquid.position.set( 0, 0, -1 );

 

 OK,綠色液體確實渲染出來了,看來這個問題輕松的就被搞定了。嗯,別高興的太早。如果物體是靜態的,那么可以這么處理,但如果是運動的就要各個方向都要看仔細了。

 

 

果然旋轉一下問題依然存在,那么怎么能徹底解決這個問題呢?下面提供幾種方案。

第一種 renderOrder

將tube的renderOrder設為1,即可正確渲染兩個物體。

第二種 depthWrite:false

將兩個物體材質的depthWrite屬性都設為 false,也可正確渲染兩個物體。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM