javascript - 渲染透明外壳

标签 javascript three.js

假设我正在渲染神奇女侠驾驶她的隐形喷气机。射流由多个网格组成,大部分是透明的。在透明网格重叠的地方,它变得更加不透明。我不想有重叠,这样透明部分仍然被遮蔽,但 Material 会丢弃其他片段后面的透明片段,就好像神奇女侠坐在透明壳内一样。

也许一个好的表达方式是我想像不透明网格一样渲染透明网格,但仍然允许它们透明。

例如,这是普通女性驾驶她最常见的汽车: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();

最佳答案

如果你想渲染重叠的透明面,但不希望重叠区域更暗,你可以实现一个技巧:先渲染面

material.colorWrite = false;

然后再次渲染它们

material.colorWrite = true;

您可以使用 Object3D.renderOrder 属性来确保使用 colorWrite = false 渲染面孔发生在使用 colorWrite = true 渲染之前。

three.js r.144

关于javascript - 渲染透明外壳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36947704/

相关文章:

javascript - html5拖放背景颜色故障

javascript - Magento:类型错误:N 不是函数

javascript - 使用 Node 请求模块的 UTF8 字符编码

javascript - 从选择类型中选择时如何刷新div而不是所有页面

javascript - Threejs创建天空盒场景

javascript - 动态几何体上的面法线

javascript - 使用 JavaScript 如何通过 ID 获取此 HTML 元素中的字符串?

javascript - A-Frame,AR.JS。如何在 NFT-Marker 中定位对象?

javascript - 无法使用 ThreeJS 和 React 导入 3D 模型

three.js - Three.js Object3D.clone() 会创建几何的深拷贝吗?