实例化形状内的透明度 [英] Transparency within instanced shapes

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

问题描述

我一直在玩 THREE.InstancedBufferGeometry.我终于有了一个可以工作的例子,现在一直在玩着色器.我尝试的第一件事是设置透明度.我的示例代码如下.

I've been playing with THREE.InstancedBufferGeometry. I finally got an example to work, and have now been playing with the shader. The first thing I tried was setting transparency. My example code is below.

初始状态,以及从许多其他摄像机角度(例如,将鼠标向左拖动),透明度似乎没有任何影响.但随后在其他摄像机角度(例如重新加载并将鼠标向右拖动),形状明显重叠,这正是我所期望的.

The initial state, and from a host of other camera angles (e.g. drag your mouse to the left), the transparency doesn't seem to have any effect. But then at other camera angles (e.g. reload and drag your mouse to the right), the shapes clearly overlap, which is what I was expecting.

对于实例化的形状,深度排序的处理方式是否不同,还是我做错了什么,或者遗漏了什么?我是否需要以某种方式更新形状,以便相机知道它们在场景中的适当深度?

Is depth-sorting handled differently for instanced shapes, or am I doing something wrong, or missing something? Do I somehow need to update the shapes so the camera knows their proper depth in the scene?

var cubeGeo = new THREE.InstancedBufferGeometry().copy(new THREE.BoxBufferGeometry(10, 10, 10));
//cubeGeo.maxInstancedCount = 8;

cubeGeo.addAttribute("cubePos", new THREE.InstancedBufferAttribute(new Float32Array([
  25, 25, 25,
  25, 25, -25, -25, 25, 25, -25, 25, -25,
  25, -25, 25,
  25, -25, -25, -25, -25, 25, -25, -25, -25
]), 3, 1));

var vertexShader = [
  "precision highp float;",
  "",
  "uniform mat4 modelViewMatrix;",
  "uniform mat4 projectionMatrix;",
  "",
  "attribute vec3 position;",
  "attribute vec3 cubePos;",
  "",
  "void main() {",
  "",
  "	gl_Position = projectionMatrix * modelViewMatrix * vec4( cubePos + position, 1.0 );",
  "",
  "}"
].join("\n");
var fragmentShader = [
  "precision highp float;",
  "",
  "void main() {",
  "",
  "	gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);",
  "",
  "}"
].join("\n");

var mat = new THREE.RawShaderMaterial({
  uniforms: {},
  vertexShader: vertexShader,
  fragmentShader: fragmentShader,
  transparent: true
});

var mesh = new THREE.Mesh(cubeGeo, mat);

scene.add(mesh);

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

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

<script src="http://threejs.org/build/three.js"></script>
<script src="http://threejs.org/examples/js/controls/TrackballControls.js"></script>
<script src="http://threejs.org/examples/js/libs/stats.min.js"></script>
<div id="host"></div>

<script>
  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 = 2.0; // need to speed it up a little

  var scene = new THREE.Scene();

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

  scene.add(light);

  function render() {
    if (typeof updateVertices !== "undefined") {
      updateVertices();
    }
    renderer.render(scene, camera);
    stats.update();
  }

  function animate() {
    requestAnimationFrame(animate);
    trackballControl.update();
    render();
  }

  animate();
</script>

推荐答案

您正在将 InstancedBufferGeometry 与半透明的网格一起使用.

You are using InstancedBufferGeometry with meshes that are translucent.

实例按照它们在缓冲区中出现的顺序进行渲染.每个实例的面都按照几何体指定的顺序进行渲染.

The instances are rendered in the order they appear in the buffer. The faces of each instance are rendered in the ordered specified by the geometry.

因此,如果您使用具有半透明的实例化,根据视角的不同,您可能会出现伪影.

Consequently, if you use instancing with translucency, you will likely have artifacts depending on the viewing angle.

根据您的用例,您可以尝试设置 material.depthWrite = false,但这可能会导致其他工件.

Depending on your use case, you can try setting material.depthWrite = false, but that can lead to other artifacts.

如果您的网格纹理具有完全透明的区域(而不是部分透明区域),您应该能够使用 material.alphaTest 来丢弃不需要的片段而不会产生伪影.

If your mesh textures have areas of complete transparency (rather than partial) you should be able to use material.alphaTest to discard unwanted fragments without artifacts.

three.js r.84

three.js r.84

这篇关于实例化形状内的透明度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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