我一直在研究这个想法,我发现有人已经完成了我一直在努力的类似想法。我正在寻找是否有人可以直接引导我直接找到我所缺少的东西,以便像这样在飞机上创建类似波浪运动的效果:http://samsy.ninja/
问题:我可以获得形状,但是我无法更改顶点以创建类似于http://samsy.ninja/的波浪效果。我正在尝试创建相同的效果,但我无法让wave更新正常工作。}
我相信,如果我只是在每个顶点和尾随后面的行中产生波浪效果,我可以让它工作,但我已经读过有更好的解决方案使用perlin噪音,但我还没有很多经验。
我如何绘制原始形状以获得类似于我显示的示例的波形:
public wave = Math.PI * 2 / 80;
public waveHeight = 20;
for (let i = 0; i < this.planeGeometry.vertices.length; i++) {
this.planeGeometry.vertices[i].z = (Math.sin(this.counter)) / 2 * this.waveHeight;
(this.planeGeometry as any).verticesNeedUpdate = true;
this.counter += this.wave;
// Reset back to 0 so each row has the same shape.
if (i % 201 == 0) {
this.counter = 0;
}
}
完整的源代码:
import { Component, AfterViewInit, ElementRef, Input, ViewChild, HostListener} from '@angular/core';
import { TweenLite } from 'gsap';
import * as THREE from 'three';
declare const require: (moduleId: string) => any;
var OrbitControls = require('three-orbit-controls')(THREE);
@Component({
selector: 'shared-background-scene',
templateUrl: './backgroundScene.component.html',
styleUrls: ['./backgroundScene.component.scss']
})
export class BackgroundSceneComponent {
public scene: THREE.Scene;
private renderer: THREE.WebGLRenderer;
private camera: THREE.PerspectiveCamera;
private cameraTarget: THREE.Vector3;
public controls: THREE.OrbitControls;
public clock = new THREE.Clock();
public fieldOfView: number = 60;
public nearClippingPane: number = 1;
public farClippingPane: number = 10000;
@ViewChild('canvas')
private canvasRef: ElementRef;
//Drawing images with particles
public plane: THREE.Mesh;
public shadowPlane: THREE.Mesh;
public planeGeometry = new THREE.PlaneGeometry(500, 200, 200, 200);
public planeMaterial = new THREE.MeshBasicMaterial({
color: 0xBBff53, wireframe: true,
});
public wave = Math.PI * 2 / 80;
public waveHeight = 20;
public counter = 0;
constructor() {
this.render = this.render.bind(this);
}
private get canvas(): HTMLCanvasElement {
return this.canvasRef.nativeElement;
}
private createScene() {
this.scene = new THREE.Scene();
}
private createCamera() {
let aspectRatio = this.getAspectRatio();
this.camera = new THREE.PerspectiveCamera(
this.fieldOfView,
aspectRatio,
this.nearClippingPane,
this.farClippingPane
);
// Set position and look at
this.camera.position.x = 0;
this.camera.position.y = 0;
this.camera.position.z = 500;
}
//create the plane that will hold the shadow, and the plane above it.
private createPlanes() {
// Create plane, and then rotate so it is sideways for the scene.
this.plane = new THREE.Mesh(this.planeGeometry, this.planeMaterial);
this.plane.rotation.x = Math.PI / 2;
this.scene.add(this.plane);
this.setPlaneGeometry();
}
// set geometry for plane wave. We use sin because it is going to be a continuous wave
private setPlaneGeometry() {
for (let i = 0; i < this.planeGeometry.vertices.length; i++) {
this.planeGeometry.vertices[i].z = (Math.sin(this.counter)) / 2 * this.waveHeight;
(this.planeGeometry as any).verticesNeedUpdate = true;
this.counter += this.wave;
// Reset back to 0 so each row has the same shape.
if (i % 201 == 0) {
this.counter = 0;
}
}
}
private getAspectRatio(): number {
let height = this.canvas.clientHeight;
if (height === 0) {
return 0;
}
return this.canvas.clientWidth / this.canvas.clientHeight;
}
private startRendering() {
try {
this.renderer = new THREE.WebGLRenderer({
canvas: this.canvas,
antialias: true
});
} catch (e) {
alert('You need to use the browser chrome, firefox, or enable webgl to see these 3D graphics.');
}
this.renderer.setPixelRatio(devicePixelRatio);
this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
this.renderer.shadowMap.enabled = true;
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
this.renderer.setClearColor(0xffffff, 1);
this.renderer.autoClear = true;
let component: BackgroundSceneComponent = this;
(function render() {
setTimeout(function () {
requestAnimationFrame(render);
}, 1000 / 20);
component.render();
}());
}
public render() {
this.setPlaneGeometry();
this.renderer.render(this.scene, this.camera);
}
private addControls() {
this.controls = new OrbitControls(this.camera);
this.controls.rotateSpeed = 1.0;
this.controls.zoomSpeed = 1.2;
this.controls.addEventListener('change', this.render);
}
/* Events */
private onResize(event: Event) {
this.canvas.style.width = "100%";
this.canvas.style.height = "100vh";
this.camera.updateProjectionMatrix();
this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
this.render();
}
/* LIFECYCLE */
ngAfterViewInit() {
this.createScene();
this.createCamera();
this.createPlanes();
this.startRendering();
this.addControls();
}
}