2016-04-29 106 views
2

假设我正在渲染神奇女侠驾驶她的隐形喷气机。喷气式飞机由多个网格组成,并且大部分都是透明的。透明网格重叠的地方变得更加不透明。我希望没有重叠部分,这样透明部分仍然有阴影,但是材质会丢弃位于其他片段后面的透明片段,就好像神奇女侠坐在透明外壳内一样。渲染一个透明的外壳

也许一个很好的方法来说明,我想渲染透明网格,如不透明网格,但仍然允许它们透明。

作为一个例子,这里是普通女子驾驶她的天色,可见汽车:http://jsfiddle.net/TheJim01/e6ccfo24/

我已经做了深度测试和写作的不同排列,并尝试了所有的各种深度测试功能。我也尝试了不同的混合设置(我看到了THREE.NoBlending的一些建议,但那不是我想要的,因为我失去了透明度)。如果我必须为此编写自定义着色器,我会走这条路线,但我不知道从哪里开始。

HTML:

<script> 
// INITIALIZE 
var WIDTH = window.innerWidth, 
    HEIGHT = window.innerHeight, 
    FOV = 35, 
    NEAR = 1, 
    FAR = 1000; 

var renderer = new THREE.WebGLRenderer({ antialias: true }); 
renderer.setSize(WIDTH, HEIGHT); 
document.getElementById('host').appendChild(renderer.domElement); 

var stats= new Stats(); 
stats.domElement.style.position = 'absolute'; 
stats.domElement.style.top = '0'; 
document.body.appendChild(stats.domElement); 


var camera = new THREE.PerspectiveCamera(FOV, WIDTH/HEIGHT, NEAR, FAR); 
camera.position.z = 250; 

var trackballControl = new THREE.TrackballControls(camera, renderer.domElement); 
trackballControl.rotateSpeed = 5.0; // need to speed it up a little 

var scene = new THREE.Scene(); 

var light = new THREE.PointLight(0xffffff, 1, Infinity); 
light.position.copy(camera.position); 

scene.add(light); 

function draw(){ 
    light.position.copy(camera.position); 
    renderer.render(scene, camera); 
    stats.update(); 
} 
trackballControl.addEventListener('change', draw); 

function navStartHandler(e) { 
    renderer.domElement.addEventListener('mousemove', navMoveHandler); 
    renderer.domElement.addEventListener('mouseup', navEndHandler); 
} 
function navMoveHandler(e) { 
    trackballControl.update(); 
} 
function navEndHandler(e) { 
    renderer.domElement.removeEventListener('mousemove', navMoveHandler); 
    renderer.domElement.removeEventListener('mouseup', navEndHandler); 
} 

renderer.domElement.addEventListener('mousedown', navStartHandler); 
renderer.domElement.addEventListener('mousewheel', navMoveHandler); 
</script> 

CSS:

html *{ 
    padding: 0; 
    margin: 0; 
    width: 100%; 
    overflow: hidden; 
} 

#host { 
    width: 100%; 
    height: 100%; 
} 

的JavaScript:

// NOTE: To run this demo, you MUST use the HTTP protocol, not HTTPS! 

var msh = new THREE.Mesh(new THREE.SphereGeometry(10, 20, 20), new THREE.MeshLambertMaterial({color: "red"})); 
msh.position.set(0, 10, 0); 
scene.add(msh); 

var mat = new THREE.MeshLambertMaterial({ 
    color: "silver", 
    transparent: true, 
    opacity: 0.5 
}); 

msh = new THREE.Mesh(new THREE.CylinderGeometry(15, 15, 75, 20), mat); 
msh.rotation.set(0, 0, Math.PI/2); 
msh.position.set(0,10,0); 
scene.add(msh); 

msh = new THREE.Mesh(new THREE.CylinderGeometry(15, 15, 50, 20), mat); 
msh.rotation.set(Math.PI/2, 0, 0); 
msh.position.set(-20,-10,0); 
scene.add(msh); 

msh = new THREE.Mesh(new THREE.CylinderGeometry(15, 15, 50, 20), mat); 
msh.rotation.set(Math.PI/2, 0, 0); 
msh.position.set(20,-10,0); 
scene.add(msh); 

draw(); 

回答

5

如果你想呈现重叠透明的面孔,但不希望重叠区域更暗,可以实现一招:用

material.colorWrite = false; 

首先呈现的面孔,然后使它们与

第二次
material.colorWrite = true; 

小提琴:http://jsfiddle.net/yrfuy4j8/

您的提琴:http://jsfiddle.net/5eku8k37/

三人。 js r.76

+0

只是为了澄清,这个技巧并不取决于您将对象/组添加到场景的顺序。只要具有material.colorWrite = false的对象与其真实对象一起出现在场景中,它就会工作。 (在两个小提琴中进行测试) – TheJim01