我正在尝试创建一个立方体形状的地形,这将允许沿着顶部平面上的那些 y轴的顶点位移。需要连接与顶部平面相邻的所有顶点。
以高效的方式,来自桌面或移动设备的用户输入会向上或向下移动它们。
根据我的阅读,最好将昂贵的操作卸载到GPU上。我认为在ShaderMaterial
中使用位移attribute
实现顶点位移似乎是完美的拟合,直到我阅读以下内容:
从THREE r72开始,不再支持在ShaderMaterial中直接分配属性。必须使用BufferGeometry实例(而不是Geometry实例)。
所以似乎不能使用attribute
代替Geometry
吗?
我尝试使用BufferGeometry
中的ShaderMaterial
沿顶层移动顶点但会产生以下结果:
BufferGeometry
的顶部平面顶点未连接到其他平面,与使用Geometry
方法连接的mergeVertices
相反。据我所知,该方法不适用于BufferGeometry
个对象?
基本上是什么开始了我对Geometry
的恐惧,不确定和怀疑是a post我读过mrdoob。
我为Geometry
already have this working,但希望将ShaderMaterial
attributes
与GPU结合使用,似乎仅由{{1}支持}, if 它为移动设备带来了性能优势,如果 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);
&#13;