簡體   English   中英

Three.js - 如何更新 PlaneBufferGeometry?

[英]Three.js - How to update a PlaneBufferGeometry?

我正在嘗試為我的 Three.js 應用程序創建一個海洋。 我從這個網站拿了例子: https://codepen.io/RemiRuc/pen/gJMwOe?fbclid=IwAR2caTQL-AOPE2Gv6x4rzSWBrOmAh2j-raqesOO0XbYQAuSG37imbMszSis

var params = {
  res : 32,
  speed : 8,
  amp : 2,
  wireframe : true,
  backgroundColor : 0x9c81e3,
  planeColor : 0x4a4a4a
}

var scene = new THREE.Scene();
scene.background = new THREE.Color(params.backgroundColor)
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 )
let canvas = document.getElementById("webgl")

var renderer = new THREE.WebGLRenderer({canvas:canvas, antialias: true})
renderer.setSize( window.innerWidth, window.innerHeight )

var simplex = new SimplexNoise()

var light = new THREE.AmbientLight( 0xcccccc ); // soft white light
scene.add( light );

var pointLight = new THREE.PointLight( 0xeeeeee, 1, 100 );
pointLight.position.set( 0, 20, -20 );
scene.add( pointLight );

let geometry, material, plane
createPlane()

camera.position.z = 5;
camera.position.y = 3;
camera.lookAt(new THREE.Vector3( 0, 3, 0 ))

var animate = function () {
  requestAnimationFrame( animate );

    for (var i = 0; i < geometry.vertices.length; i++) {
      var z = (i + Date.now() * params.speed/100000)
      geometry.vertices[i].z = simplex.noise4D(z,z,z,z) * params.amp
      plane.geometry.verticesNeedUpdate = true;
    }

  scene.background = new THREE.Color(params.backgroundColor)
  material.color = new THREE.Color(params.planeColor)
  material.wireframe = params.wireframe

  camera.rotation.y += 0.001
  renderer.render( scene, camera );
};

animate();

function createPlane(){
  geometry = new THREE.PlaneGeometry( 200, 200, params.res,params.res );
  material = new THREE.MeshLambertMaterial( {color: params.planeColor, side: THREE.DoubleSide, wireframe: params.wireframe} );
  plane = new THREE.Mesh( geometry, material );
  scene.add( plane );
  plane.rotation.x = Math.PI/2
}

/***RESIZE***/
window.addEventListener('resize', ()=>{
    document.querySelector('canvas').style.width = window.innerWidth + "px"
    document.querySelector('canvas').style.height = window.innerHeight + "px"

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

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

var gui = new dat.GUI()

var controller = gui.add(params, "res", 0, 100).name("Plane resolution")
gui.add(params, "speed", 0, 500).name("Wave speed")
gui.add(params, "amp", 0, 20).name("Wave amplitude")
gui.add(params, "wireframe", 0, 20).name("Wireframe")
gui.addColor(params, "backgroundColor").name("Background color")
gui.addColor(params, "planeColor").name("Plane color")

controller.onChange(()=>{
  scene.remove(plane)
  createPlane()
})

問題是,我使用的是PlaneBufferGeometry而不是PlaneGeometry ,看起來有些不同

創建水面后我在render中的代碼

for (var i = 0; i < waterGeometry.attributes.position.count; i++) {
    var z = (i + Date.now() * params.speed/100000);
    waterGeometry.attributes.position[i] = simplex.noise4D(z,z,z,z) * params.amp;
}
waterGeometry.attributes.position.needsUpdate = true;
waterPlaneMesh.attributes.position.needsUpdate = true;

我沒有收到任何錯誤,但無論我做什么,我得到的只是一個平面線框平面幾何圖形,它不會移動或任何東西。 我認為問題出在飛機的更新上?

這是一個示例,說明如何使用SimplexNoise庫置換緩沖區幾何體的頂點: 在此處輸入圖像描述

 body { margin: 0; background-color: #000; color: #fff; font-family: Monospace; font-size: 13px; line-height: 24px; overscroll-behavior: none; }
 <script type="module"> import * as THREE from "https://cdn.skypack.dev/three@0.136.0"; import { OrbitControls } from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls"; import { createNoise3D } from "https://cdn.skypack.dev/simplex-noise"; let simplex = createNoise3D(); let scene = new THREE.Scene(); let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 2000); camera.position.set(0, 0.5, 1).setLength(12); let renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(innerWidth, innerHeight); document.body.appendChild(renderer.domElement); window.addEventListener("resize", onWindowResize); //scene.add(new THREE.GridHelper()) let controls = new OrbitControls(camera, renderer.domElement); let light = new THREE.DirectionalLight(0xffffff, 0.5); light.position.setScalar(1); scene.add(light, new THREE.AmbientLight(0xffffff, 0.5)); let v3 = new THREE.Vector3(); let v2 = new THREE.Vector2(); let g = new THREE.PlaneGeometry(200, 200, 100, 100); g.rotateX(-Math.PI *0.5); let m = new THREE.MeshLambertMaterial({color: "aqua", wireframe: false}); let o = new THREE.Mesh(g, m); scene.add(o); let clock = new THREE.Clock(); renderer.setAnimationLoop(() => { renderer.render(scene, camera); let t = clock.getElapsedTime(); for(let i = 0; i < g.attributes.position.count; i++){ v2.fromBufferAttribute(g.attributes.uv, i).addScalar(t * 0.01).multiplyScalar(20); let h = simplex(v2.x, v2.y, t * 0.1); g.attributes.position.setY(i, h); } g.computeVertexNormals(); g.attributes.position.needsUpdate = true; }); function onWindowResize() { camera.aspect = innerWidth / innerHeight; camera.updateProjectionMatrix(); renderer.setSize(innerWidth, innerHeight); } </script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM