使用 ThreeJS 中的新 PlaneBufferGeometry 访问顶点

Mig*_*use 3 javascript three.js

我知道 PlaneGeometry 已被弃用,我们应该在最新版本中使用 PlaneBufferGeometry。以下代码适用于 R125 之前的版本,我只是不知道如何调整代码以使其适用于 PlaneBufferGeometry:

var flagGeom = new THREE.PlaneBufferGeometry(4.5, 2.2, 40, 100, 200); // Replaced "PlaneGeometry " with "PlaneBufferGeometry" here.
flagGeom.translate(2.2, 1.1, 0);
  
  
flagGeom.vertices.forEach(v => { // Undefined error here.
    v.init = v.clone()
});
Run Code Online (Sandbox Code Playgroud)

pri*_*849 6

看来您的问题与此论坛主题相关。

userData您可以这样做(只是一个选项,不是最终的解决方案):使用存储在, 和 use方法中的附加数组.setXYZ()

body{
  overflow: hidden;
  margin: 0;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://josephg.github.io/noisejs/perlin.js"></script>
<script type="module">
console.clear();
import * as THREE from 'https://cdn.skypack.dev/three@0.129.0/build/three.module.js';
import { OrbitControls } from 'https://cdn.skypack.dev/three@0.129.0/examples/jsm/controls/OrbitControls.js';

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(-1, 0.5, 2).setLength(2.5);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x401000);
document.body.appendChild(renderer.domElement);

var controls = new OrbitControls(camera, renderer.domElement);

var light = new THREE.DirectionalLight(0xff5500, 2);
light.position.setScalar(10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xff0000, 1));

var loader = new THREE.TextureLoader();

// flag
var flagGeom = new THREE.PlaneGeometry(4, 2, 40, 20);
flagGeom.translate(2, 1, 0);
let pos = flagGeom.attributes.position;
flagGeom.userData = {
  init: []
}
for(let i = 0; i < pos.count; i++){
  flagGeom.userData.init.push(new THREE.Vector3().fromBufferAttribute(pos, i));
}
console.log(flagGeom.userData.init);

var flagMat = new THREE.MeshStandardMaterial({
  color: 0x777777,
  map: loader.load("https://cywarr.github.io/small-shop/PW_flag/PW_flag_map.png"),
  alphaMap: loader.load("https://cywarr.github.io/small-shop/PW_flag/PW_flag_alphaMap.png"),
  alphaTest: 0.5,
  side: THREE.DoubleSide,
  metalness: 0.5,
  roughness: 0.5
});
var flag = new THREE.Mesh(flagGeom, flagMat);
flag.position.set(-2, -1, 0);
flag.rotation.x = THREE.Math.degToRad(-18);
scene.add(flag);

// staff
var staff = new THREE.Mesh(new THREE.CylinderGeometry(0.04, 0.04, 4, 8), new THREE.MeshStandardMaterial({
  color: "black"
}));
flag.add(staff);

// background canvas texture
var canvas = document.createElement("canvas");
canvas.width = 128;
canvas.height = 64;

var ctx = canvas.getContext('2d');

var image = ctx.createImageData(canvas.width, canvas.height);
var data = image.data;

var canvasTexture = new THREE.CanvasTexture(canvas);
scene.background = canvasTexture;

window.addEventListener( 'resize', onWindowResize );

var clock = new THREE.Clock();
var delta = 0;
var time = 0;
var v = new THREE.Vector3();

render();

function render() {
  requestAnimationFrame(render);
  delta = clock.getDelta();
  time += delta;
  flagGeom.userData.init.forEach( (vi, idx) => {
    
    v.copy(vi);
    let yFade = Math.sin(v.y / flagGeom.parameters.height * Math.PI) * 0.25;
    v.x = v.x + yFade;
    let xFade = (v.x / flagGeom.parameters.width);
    v.z = noise.perlin2((v.x - (time * 2)) / flagGeom.parameters.width * 4, v.y / flagGeom.parameters.height * 2) * xFade;
    
    pos.setXYZ(idx, v.x, v.y, v.z);
  });
  flagGeom.computeVertexNormals();
  pos.needsUpdate = true;

  drawFrame(time);
  canvasTexture.needsUpdate = true;
  renderer.render(scene, camera);
}

function drawFrame(time) {

  var cWidth = canvas.width;
  var cHeight = canvas.height;

  for (var x = 0; x < cWidth; x++) {
    for (var y = 0; y < cHeight; y++) {
      var value = Math.abs(noise.simplex3(x / cWidth, y / cHeight, time * 0.25));

      var cell = (x + y * cWidth) * 4;
      data[cell] = 128 + Math.floor(128 * value);
      data[cell + 1] = Math.floor(256 * value);
      data[cell + 2] = 0;
      data[cell + 3] = 255; // alpha.
    }
  }

  ctx.fillColor = 'black';
  ctx.fillRect(0, 0, 100, 100);
  ctx.putImageData(image, 0, 0);

}

function onWindowResize() {

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize( window.innerWidth, window.innerHeight );

}

</script>
Run Code Online (Sandbox Code Playgroud)