BoxBufferGeometry的焊缝边缘顶点

Jas*_*son 5 glsl webgl three.js

我试图创建一个立方体形状的地形,这将允许顶部平面上的那些顶点沿y轴移位.需要连接与顶部平面相邻的所有顶点.

以高效的方式,来自桌面或移动设备的用户输入将向上或向下移动它们.


根据我的阅读,最好将昂贵的操作卸载到GPU.我认为ShaderMaterial用a位移实现顶点位移attribute似乎是完美的拟合,直到我阅读以下内容:

从THREE r72开始,不再支持在ShaderMaterial中直接分配属性.必须使用BufferGeometry实例(而不是Geometry实例).

所以看来attribute用于我的Geometry是不可能的?

我沿着使用顶部平面位移的顶点尝试BufferGeometryShaderMaterial不过结果如下:

BufferGeometry和Geometry位移

顶平面的顶点BufferGeometry没有连接到其他平面,Geometry与通过其mergeVertices方法连接的平面相反.据我所知,该方法不适用于BufferGeometry对象?

基本上是什么开始我的恐惧,不确定和怀疑Geometry是我读到的一个帖子 mrdoob.

摘要

已经有了这方面的工作Geometry,但想利用与GPU的ShaderMaterialattributes,似乎只有支持BufferGeometry,如果它为移动提供了性能优势,如果 Geometry在将来可能会被废弃.


这是一个说明问题的小片段:

let winX = window.innerWidth;
let winY = window.innerHeight;

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(50, winX / winY, 0.1, 100);
      camera.position.set(2, 1, 2);
      camera.lookAt(scene.position);

const renderer = new THREE.WebGLRenderer();
      renderer.setSize(winX, winY);

document.body.appendChild(renderer.domElement);

const terrainGeo = new THREE.BoxBufferGeometry(1, 1, 1);
const terrainMat = new THREE.ShaderMaterial({
  vertexShader: `
    attribute float displacement;
    varying vec3 dPosition;

    void main() {

      dPosition = position;
      dPosition.y += displacement;

      gl_Position = projectionMatrix * modelViewMatrix * vec4(dPosition, 1.0);
    }
  `,
  fragmentShader: `
    void main() {
      gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
    }
  `
});
const terrainObj = new THREE.Mesh(terrainGeo, terrainMat);

let displacement = new Float32Array(terrainObj.geometry.attributes.position.count);
    displacement.forEach((elem, index) => {
      // Select vertex 8 - 11, the top of the cube
      if (index >= 8 && index <= 11) {
        displacement[index] = Math.random() * 0.1 + 0.25;
      }
});

terrainObj.geometry.addAttribute('displacement',
  new THREE.BufferAttribute(displacement, 1)
);

scene.add(camera);
scene.add(terrainObj);

const render = () => {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}

render();

const gui = new dat.GUI();

const updateBufferAttribute = () => {
  terrainObj.geometry.attributes.displacement.needsUpdate = true;  
};

gui.add(displacement, 8).min(0).max(2).step(0.05).onChange(updateBufferAttribute);
gui.add(displacement, 9).min(0).max(2).step(0.05).onChange(updateBufferAttribute);
gui.add(displacement, 10).min(0).max(2).step(0.05).onChange(updateBufferAttribute);
gui.add(displacement, 11).min(0).max(2).step(0.05).onChange(updateBufferAttribute);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5.1/dat.gui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r76/three.min.js"></script>
<style type="text/css">body { margin: 0 } canvas { display: block }</style>
Run Code Online (Sandbox Code Playgroud)