Создайте сетку BoxGeometry 16x16 относительно размера области просмотра с Three.js - PullRequest
1 голос
/ 02 июля 2019

Вопрос идет настолько просто, насколько это возможно, название в значительной степени описывает то, что я пытаюсь сделать.

Я новичок в Three.js и WebGL, я более или менее понимаю основы создания куба, но когда дело доходит до того, что я пытаюсь сделать, я в растерянности.

Я в основном использую эту ручку в качестве справки, пока я учусь: https://codepen.io/jackrugile/pen/vOEKzw, поскольку она делает то, что я хочу, без привязки к размеру экрана

var tick = 0,
  smallestDimension = Math.min(window.innerWidth, window.innerHeight),
  viewportWidth = smallestDimension,
  viewportHeight = smallestDimension,
  worldWidth = 100,
  worldHeight = 100,
  rows = 30,
  cols = 30,
  tileWidth = worldWidth / cols,
  tileHeight = worldHeight / rows,
  FOV = 90,
  scene = new THREE.Scene(),
  camera = new THREE.PerspectiveCamera(
    FOV,
    viewportWidth / viewportHeight,
    0.1,
    1000
  ),
  renderer = new THREE.WebGLRenderer({
    antialias: true
  }),
  plane = new THREE.Mesh(
    new THREE.PlaneBufferGeometry(worldWidth, worldHeight, 1),
    new THREE.MeshPhongMaterial({
      color: 0x222222
    })
  ),
  cubes = new THREE.Object3D(),
  spotLight = new THREE.SpotLight(0xffffff),
  ambientLight = new THREE.AmbientLight(0x666666);

renderer.setSize(viewportWidth, viewportHeight);
renderer.shadowMapEnabled = true;
renderer.shadowMapType = THREE.PCFSoftShadowMap;

scene.add(plane);
scene.add(cubes);
scene.add(spotLight);
scene.add(ambientLight);

for (var x = 0; x < cols; x++) {
  for (var y = 0; y < rows; y++) {
    var width = tileWidth,
      height = tileHeight,
      dx = (cols / 2 - x),
      dy = (rows / 2 - y),
      depth = 1 + (20 - Math.sqrt(dx * dx + dy * dy)) / 4,
      xBase = -worldWidth / 2 + x * tileWidth + tileWidth / 2,
      yBase = -worldHeight / 2 + y * tileHeight + tileHeight / 2,
      zBase = depth / 2,
      cube = new THREE.Mesh(
        new THREE.BoxGeometry(width, height, depth),
        new THREE.MeshPhongMaterial({
          color: 'rgb(' + ~~((y / rows) * 255) + ', ' + ~~((x / cols) * 255) + ', 255)',
          shininess: 50
        })
      );
    cube.position.set(
      xBase,
      yBase,
      zBase
    );
    cube.castShadow = true;
    cube.receiveShadow = true;
    cube.zBase = zBase;
    cube.zScaleTarget = 1;
    cubes.add(cube);
  }
}

plane.position.set(0, 0, 0);
plane.castShadow = false;
plane.receiveShadow = true;

camera.position.set(0, 0, 100);

spotLight.position.set(0, 0, 100);
spotLight.castShadow = true;
spotLight.shadowCameraNear = 0.1;
spotLight.shadowMapWidth = 2048;
spotLight.shadowMapHeight = 2048;
spotLight.shadowDarkness = 0.1;

function step() {
  spotLight.position.x = Math.sin(tick / 100) * (worldWidth / 2);
  spotLight.position.y = Math.cos(tick / 100) * (worldHeight / 2);

  cubes.traverse(function(cube) {
    if (cube instanceof THREE.Mesh) {
      if (Math.abs(cube.scale.z - cube.zScaleTarget) > 0.001) {
        cube.scale.z += (cube.zScaleTarget - cube.scale.z) * 0.05;
      } else {
        cube.zScaleTarget = 1 + Math.random() * 10;
      }
      cube.position.z = cube.geometry.parameters.depth / 2 * cube.scale.z;
    }
  });

  tick++;
}

function render() {
  renderer.render(scene, camera);
}

function loop() {
  requestAnimationFrame(loop);
  step();
  render();
}

loop();

document.body.appendChild(renderer.domElement);
body {
  background: #000;
  overflow: hidden;
}

canvas {
  bottom: 0;
  display: block;
  left: 0;
  margin: auto;
  position: absolute;
  right: 0;
  top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>
worldWidth = 100,
worldHeight = 100,
rows = 30,
cols = 30,
tileWidth = worldWidth / cols,
tileHeight = worldHeight / rows,

Я вижу, он использует это, чтобы установить размер плиток, которые он использует в цикле:

...
var width = tileWidth,
    height = tileHeight,
    dx = ( cols / 2 - x ),
    dy = ( rows / 2 - y ),
    depth = 1 + ( 20 - Math.sqrt( dx * dx + dy * dy ) ) / 4,
    xBase = -worldWidth / 2 + x * tileWidth + tileWidth / 2,
    yBase = -worldHeight / 2 + y * tileHeight + tileHeight / 2,
...

Как бы я нарисовал эту плитку по всему окну просмотра, чтобы она была похожа на:

enter image description here

Спасибо!

1 Ответ

0 голосов
/ 02 июля 2019

Вместо того, чтобы взять Math.min используйте это в строке номер 2 smallestDimension = Math.max( window.innerWidth, window.innerHeight ) Он будет автоматически покрывать ваш размер экрана. Если вы хотите, вы можете изменить rows = 10 и col = 10

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...