渲染透明壳 [英] Rendering a transparent shell

查看:122
本文介绍了渲染透明壳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我正在渲染神奇女侠驾驶她的Invisible Jet。喷射器由多个网格组成,并且大部分是透明的。在透明网格重叠的地方,它变得更不透明。我不希望重叠,透明部分仍然是阴影,但材料丢弃了其他碎片后面的透明碎片,好像神奇女侠坐在透明的外壳里。

Let's say I'm rendering Wonder Woman piloting her Invisible Jet. The jet is made up of multiple meshes, and is mostly transparent. Where the transparent meshes overlap, it becomes more opaque. I'd like to not have that overlap, such that the transparent parts are still shaded, but the material discards transparent fragments that are behind other fragments, as if Wonder Woman is sitting inside a transparent shell.

也许放置它的好方法是我想渲染透明网格,如不透明网格,但仍然允许它们透明。

Perhaps a good way to putting it is that I want to render transparent meshes like opaque meshes, but still allow them to be transparent.

As一个例子,这里是普通女性驾驶她的大多数可见车: http://jsfiddle.net/TheJim01/e6ccfo24/

As an example, here is Average Woman driving her Mostly-Visible Car: http://jsfiddle.net/TheJim01/e6ccfo24/

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

I've done different permutations of depth testing and writing, and tried all the various depth test functions. I've also tried different blending settings (I saw several suggestions for THREE.NoBlending, but that's not what I want because I lose transparency). If I have to write a custom shader for this, I'll go that route, but I'm not sure where to start.

HTML:



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:

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();


推荐答案

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

If you want to render overlapping transparent faces, but do not want the overlapping regions to be darker, you can implement a trick: render the faces first with

material.colorWrite = false;

然后再次渲染它们

material.colorWrite = true;

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

你的小提琴: http://jsfiddle.net/5eku8k37/

three.js r.76

three.js r.76

这篇关于渲染透明壳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆