ฉันมีฉากนี้ที่สร้างด้วย THREE.js (ดูข้อมูลโค้ดที่แนบมาในโพสต์) หรือhttps://codepen.io/farisk/pen/jOPgKGQ
ขณะนี้มีการแผ่คลื่นวงกลมตามสูตรในdistance()ฟังก์ชัน ' '
เช่นนี้:
return Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2));
ฉันสงสัยว่าเป็นไปได้หรือไม่ที่จะแก้ไขสูตรเพื่อให้ฉันสามารถสร้างคลื่นรูป 'X' หรือ 'เครื่องหมายบวก (+)' แทนได้
var once = false;
class App {
init() {
this.stats = new Stats();
this.stats.showPanel(0);
document.body.querySelector('.stats').appendChild(this.stats.domElement);
this.backgroundColor = 0x000000;
this.ambientLightColor = 0xffffff;
this.spotLightColor = 0xff9999;
// this.boxColor = 0x1a63ed;
this.boxColor = 0xffffff;
this.angle = 0;
this.gridSize = 30;
this.ratio = 1.3
this.col = this.gridSize*this.ratio;
this.row = this.gridSize;
this.velocity = .05;
this.boxes = [];
this.amplitude = -7;
this.frequency = 0;
this.waveLength = 242;
this.scene = new THREE.Scene();
this.scene.background = new THREE.Color(this.backgroundColor);
this.camera = new THREE.PerspectiveCamera(2, window.innerWidth / window.innerHeight, 1, 10000);
this.camera.position.set(0, 800, 0);
this.addRenderer();
document.body.appendChild(this.renderer.domElement);
this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
this.addAmbientLight();
this.addDirectionalLight();
this.addFloor();
this.addBoxes(this.scene);
this.addGUIControls();
this.animate();
window.addEventListener('resize', this.onResize.bind(this));
}
addDirectionalLight() {
this.directionalLight = new THREE.DirectionalLight(0xffffff, 1);
this.directionalLight.castShadow = true;
this.directionalLight.position.set(0, 1, 0);
this.directionalLight.shadow.camera.far = 10000;
this.directionalLight.shadow.camera.near = -100;
this.directionalLight.shadow.camera.left = -40;
this.directionalLight.shadow.camera.right = 40;
this.directionalLight.shadow.camera.top = 20;
this.directionalLight.shadow.camera.bottom = -20;
this.directionalLight.shadow.camera.zoom = 1;
this.directionalLight.shadow.camera.needsUpdate = true;
const targetObject = new THREE.Object3D();
targetObject.position.set(-50, -82, 40);
this.directionalLight.target = targetObject;
this.scene.add(this.directionalLight);
this.scene.add(this.directionalLight.target);
}
addGUIControls() {
this.gui = new dat.GUI();
this.gui.add(this, 'amplitude', -10, 10);
this.gui.add(this, 'velocity', 0, .5);
this.gui.add(this, 'waveLength', 100, 500);
this.controller = this.gui.add(this, 'gridSize', 24, 150);
this.controller.onFinishChange((value) => {
this.gridSize = Math.floor(value);
this.clearScene();
this.col = this.gridSize*this.ratio;
this.row = this.gridSize;
this.addBoxes(this.scene);
});
}
addRenderer() {
this.renderer = new THREE.WebGLRenderer({ antialias: true });
this.renderer.shadowMap.enabled = true;
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
this.renderer.setSize(window.innerWidth, window.innerHeight);
}
addAmbientLight() {
const light = new THREE.AmbientLight(this.ambientLightColor, .5);
this.scene.add(light);
}
addSpotLight() {
this.spotLight = new THREE.SpotLight(this.spotLightColor);
this.spotLight.position.set(100, 250, 150);
this.spotLight.castShadow = true;
this.scene.add(this.spotLight);
}
clearScene() {
this.scene.remove(this.mesh);
this.boxes = [];
}
addBoxes(scene) {
const size = 0.05;
const height = 20;
const material = new THREE.MeshLambertMaterial({
color: this.boxColor,
});
const geometry = new THREE.BoxBufferGeometry(size, height, size);
geometry.translate( 0, 2.5, 0 );
this.mesh = this.getBox(geometry, material, this.row * this.col);
this.scene.add(this.mesh);
let ii = 0;
for (let i = 0; i < this.col; i++) {
this.boxes[i] = [];
for (let j = 0; j < this.row; j++) {
const pivot = new THREE.Object3D();
this.boxes[i][j] = pivot;
pivot.scale.set(1, 0.001, 1);
// pivot.position.set(i - this.gridSize*this.ratio * .5, height * .5, j - this.gridSize * .5);
pivot.position.set(i - this.gridSize*this.ratio * .5, height * 0, j - this.gridSize * .5);
pivot.updateMatrix();
this.mesh.setMatrixAt(ii++, pivot.matrix);
}
}
this.mesh.instanceMatrix.needsUpdate = true;
}
drawWave() {
let ii= 0;
for (let i = 0; i < this.col; i++) {
for (let j = 0; j < this.row; j++) {
const distance = this.distance(j, i, this.row * .5, this.col * .5);
const offset = this.map(distance, 0, this.waveLength, -100, 100);
const angle = this.angle + offset ;
if (!once) {
console.log(this.boxes)
once = true
}
this.boxes[i][j].scale.y = this.map(Math.sin(angle), -1, -this.amplitude, 0.001, 1);
this.boxes[i][j].rotation.z = this.map(Math.sin(angle), -1, -this.amplitude, 0.001, 1);
this.boxes[i][j].updateMatrix();
this.mesh.setMatrixAt(ii++, this.boxes[i][j].matrix);
}
}
this.mesh.instanceMatrix.needsUpdate = true;
this.angle -= this.velocity;
}
distance(x1, y1, x2, y2) {
// return Math.sin(x1 - x2)
return Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2));
}
map(value, start1, stop1, start2, stop2) {
return (value - start1) / (stop1 - start1) * (stop2 - start2) + start2
}
addFloor() {
const planeGeometry = new THREE.PlaneBufferGeometry(10, 500);
const planeMaterial = new THREE.ShadowMaterial({ opacity:1 });
this.floor = new THREE.Mesh(planeGeometry, planeMaterial);
planeGeometry.rotateX(- Math.PI / 2);
this.floor.position.y = 2;
this.floor.receiveShadow = true;
this.scene.add(this.floor);
}
getBox(geometry, material, count) {
const mesh = new THREE.InstancedMesh(geometry, material, count);
mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage);
mesh.castShadow = true;
mesh.receiveShadow = true;
return mesh;
}
addGrid() {
const size = this.col;
const divisions = size;
const gridHelper = new THREE.GridHelper(size, divisions);
gridHelper.position.set(0, 0, 0);
gridHelper.material.opacity = 0;
gridHelper.material.transparent = true;
this.scene.add(gridHelper);
}
animate() {
this.stats.begin();
this.drawWave();
this.controls.update();
this.renderer.render(this.scene, this.camera);
this.stats.end();
requestAnimationFrame(this.animate.bind(this));
}
onResize() {
const ww = window.innerWidth;
const wh = window.innerHeight;
this.camera.aspect = ww / wh;
this.camera.updateProjectionMatrix();
this.renderer.setSize(ww, wh);
}
}
new App().init();
html {
font-family: sans-serif;
}
* {
box-sizing: border-box;
}
body {
background: black;
color: #fff;
font-family: sans-serif;
overflow: hidden;
cursor: -webkit-grab;
cursor: -moz-grab;
padding: 0;
margin: 0;
}
canvas {
width: 100%;
height: 100%;
}
.stats {
opacity: 1;
z-index: 10;
position: absolute;
}
.dg.ac {
position: absolute;
z-index: 10 !important;
}
<main>
<div class="stats"></div>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.2/dat.gui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
" Plus"เป็นวิธีที่ง่ายที่สุดในการติดตั้ง คุณเพียงแค่ต้องการระยะทางสองระยะจากเส้นกึ่งกลาง (แนวนอนและแนวตั้ง)
const yd = j - this.row / 2; // distance from horizontal
const xd = i - this.col / 2; // distance from vertical
รับค่าต่ำสุดของค่าสัมบูรณ์ของแต่ละระยะทาง
const distance = Math.min(Math.abs(yd), Math.abs(xd));
จากนั้นคุณใช้ระยะทางนั้นเหมือนที่คุณทำในต้นฉบับ
หากคุณเปลี่ยนฟังก์ชันdrawเป็นดังต่อไปนี้ สิ่งนี้จะสร้างข้อดีที่ฉันคิดว่าคุณกำลังมองหา
drawWave() {
var ii= 0, x, y;
for (x = 0; x < this.col; x++) {
const bRow = this.boxes[x];
for (y = 0; y < this.row; y++) {
const yd = y - this.row / 2;
const xd = x - this.col / 2;
const distance = Math.min(Math.abs(yd), Math.abs(xd));
const angle = this.angle + this.map(distance, 0, this.waveLength, -100, 100);
const size = this.map(Math.sin(angle), -1, -this.amplitude, 0.001, 1);
bRow[y].scale.y = size;
bRow[y].rotation.z = size;
bRow[y].updateMatrix();
this.mesh.setMatrixAt(ii++, bRow[y].matrix);
}
}
this.mesh.instanceMatrix.needsUpdate = true;
this.angle -= this.velocity;
}
หากคุณต้องการกากบาท คุณต้องหมุน x และ y เพียง 45 องศา ฟังก์ชั่นถัดไปทำเช่นนั้น
drawWave() {
const xAx = Math.cos(Math.PI / 4); // Axis 45 deg CW
const xAy = Math.sin(Math.PI / 4);
var ii= 0, x, y;
for (x = 0; x < this.col; x++) {
const bRow = this.boxes[x];
for (y = 0; y < this.row; y++) {
const xx = x - this.col / 2;
const yy = y - this.row / 2;
const xd = xx * xAx - yy * xAy; // rotate
const yd = xx * xAy + yy * xAx;
const distance = Math.min(Math.abs(yd), Math.abs(xd));
const angle = this.angle + this.map(distance, 0, this.waveLength, -100, 100);
const size = this.map(Math.sin(angle), -1, -this.amplitude, 0.001, 1);
bRow[y].scale.y = size;
bRow[y].rotation.z = size;
bRow[y].updateMatrix();
this.mesh.setMatrixAt(ii++, bRow[y].matrix);
}
}
this.mesh.instanceMatrix.needsUpdate = true;
this.angle -= this.velocity;
}
มันจะมีประสิทธิภาพมากขึ้นถ้าคุณนำตรรกะทั้งหมดข้างต้นไปใช้ใน Vertex Shader
Jana Duggar เปิดใจเกี่ยวกับการค้นหาความรักของเธอ นี่คือทุกสิ่งที่เธอพูดเกี่ยวกับหัวข้อและกรอบเวลา 5 ปีสำหรับการแต่งงาน
เมื่อเร็ว ๆ นี้ แซม ฮิวแฮน นักแสดงจากเรื่อง 'Outlander' ได้เปิดเผยสิ่งที่เขาจะทำจากกองถ่ายเพื่อระลึกถึงเจมี เฟรเซอร์ บทบาทที่ทำให้เขากลายเป็นดารา
'She Loves You' เขียนขึ้นในหนึ่งชั่วโมง บันทึกเสียงในหนึ่งวัน และเป็นเพลงของ The Beatles ที่มีการแสดงที่ดีที่สุดเพลงหนึ่งในอาชีพของพวกเขา
Dolly Parton และคุณย่า Bessie มีความสัมพันธ์พิเศษ คุณยายพาร์ตันป่วยหนัก แต่นั่นไม่ได้ทำให้ดอลลี่หยุดแกล้งเธอ
คุณอาจคิดว่าไม้โอ๊คหรือฮิคคอรีเป็นไม้ที่แข็ง แต่เมื่อต้องพูดถึงไม้ที่แข็งที่สุดในโลกแล้ว พวกมันกลับไม่ใกล้เคียงเลย
มหาสมุทรเต็มไปด้วยความงาม แต่ก็ซ่อนสิ่งมีชีวิตใต้ท้องทะเลที่น่ากลัวที่สุดบางชนิดไว้เช่นกัน สัตว์เหล่านี้หลายชนิดซ่อนตัวอยู่ใต้ผิวน้ำอันมืดมิด ในโลกใต้ทะเลลึกอันแสนกดดันและมืดมิด
หากคุณกำลังต่อสู้กับศัตรูหรือกำลังเตรียมตัวสำหรับโหมด PvP การรู้ถึงการเสริมพลังดาบที่ดีที่สุดใน Minecraft จะช่วยให้คุณได้เปรียบอย่างมาก การเสริมพลังดาบจะช่วยให้คุณสร้างความเสียหายได้มากขึ้น เพิ่มจำนวนม็อบที่ดรอป และเพิ่มความทนทานของดาบ
เมื่อผู้คนพูดถึงประเทศสังคมนิยม พวกเขามักจะนึกถึงการควบคุมโดยรัฐบาลอย่างเต็มรูปแบบโดยไม่มีกรรมสิทธิ์ส่วนบุคคล แต่ในทางปฏิบัติ เศรษฐกิจแบบสังคมนิยมมีความหลากหลายอย่างมาก
“เด็ก” โผล่รับเชิญดาราดังพร้อมข่าวร้าย
RAV4 นี้อ้างว่าอยู่ในสภาพที่ดีเยี่ยมและมีไว้สำหรับการเล่นเก้าอี้ดนตรี
ภาพจากโดรนจับภาพนักดับเพลิงที่กำลังพยายามดับไฟ
Eyes of Wakanda เชื่อมโยงโดยตรงกับ MCU พร้อมอัปเดตเกี่ยวกับ X-Men '97, What If..., Daredevil และอีกมากมาย
Ava Gardner แต่งงานกับ Mickey Rooney และ Frank Sintra และเธอยังคบหาดูใจกับดาราฮอลลีวูดอีกหลายคน ต่อไปนี้คือประวัติการออกเดทของ Ava Gardner
จอห์น คลีส แต่งงานกับเจนนิเฟอร์ เวด ภรรยาของเขาในปี 2012 นี่คือทุกสิ่งที่คุณต้องรู้เกี่ยวกับเจนนิเฟอร์ เวด ภรรยาของจอห์น คลีส
Michael C. Hall แต่งงานกับ Morgan Macgregor ภรรยาของเขาตั้งแต่ปี 2016 นี่คือทุกสิ่งที่คุณต้องการทราบเกี่ยวกับภรรยาของ Michael C. Hall
Mena Suvari แต่งงานกับ Michael Hope สามีของเธอมาตั้งแต่ปี 2018 นี่คือทุกสิ่งที่ควรรู้เกี่ยวกับสามีของ Mena Suvari
มันทำให้ฉันประหลาดใจ ทันใดนั้นมันก็เกิดขึ้นบ่อยๆ มันอยู่กลางทางอีกครั้ง <ไม่ ไม่ใช่คนในมหาสมุทรแปซิฟิก คุณเป็นสีน้ำตาลแดง คนที่งานคาร์นิวัล> ทุกพาดหัวข่าวดัง…..
ในปี 2022 ด้วยการเปิดตัว GPT-3 ทักษะการเขียนดูเหมือนจะมีความสำคัญน้อยลง ด้วย AI คนที่เขียนไม่ดีก็สามารถสร้างพนักงานที่มีคุณภาพได้เช่นกัน
ในโลกที่เปลี่ยนแปลงอย่างรวดเร็วและการแข่งขันในปัจจุบัน อาชีพของคนๆ หนึ่งมีบทบาทสำคัญในการเติบโตส่วนบุคคล ความมั่นคงทางการเงิน และความพึงพอใจในชีวิตโดยรวม อย่างไรก็ตาม ผู้คนจำนวนมากพบว่าตัวเองติดอยู่ในวงจรของความเมื่อยล้าและความไม่พอใจอย่างไม่หยุดยั้ง ค่อยๆ สูญเสียชีวิตการทำงานไป
เมื่อสัปดาห์ที่แล้วฉันสังเกตเห็นข่าวประชาสัมพันธ์ที่เผยแพร่ผ่าน PressGazette (เว็บไซต์ข่าวของสื่ออังกฤษ) บทความประกาศว่า Acast ซึ่งเป็นบริษัทโฮสติ้งและโฆษณาพอดคาสต์ของ Scandi จะเป็นผู้นำกลุ่มผู้เผยแพร่ "อาจมีอิทธิพลมากที่สุด" ในพอดคาสต์