如何实现three.js响应式设计(消除拉伸变形和锯齿)

techbrood 发表于 2019-11-09 15:26:43

标签: three.js, webgl, responsive design

- +

我们先创建一个基本的three.js场景,里面有一个cube对象。

分三步,首先声明一个canvas的html元素并设置其样式:

<canvas id="c"></canvas>
#c {
    width: 100%;
    height: 100%;
    display: block;
}

第二步,使用three.js创建场景、光照、相机和立方体模型(cube):

import * as THREE from '//techbrood.com/threejs/build/three.module.js';

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({canvas});

  const fov = 75;
  const aspect = 2;  // the canvas default
  const near = 0.1;
  const far = 5;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.z = 2;

  const scene = new THREE.Scene();

  {
    const color = 0xFFFFFF;
    const intensity = 1;
    const light = new THREE.DirectionalLight(color, intensity);
    light.position.set(-1, 2, 4);
    scene.add(light);
  }

  const boxWidth = 1;
  const boxHeight = 1;
  const boxDepth = 1;
  const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);

  function makeInstance(geometry, color, x) {
    const material = new THREE.MeshPhongMaterial({color});

    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);

    cube.position.x = x;

    return cube;
  }

  var cube = makeInstance(geometry, 0x44aa88,  0),

  //TODO: render the scene

}

第三步,循环渲染该场景:

  function render(time) {
    time *= 0.001;

    const speed = 1;
    const rot = time * speed;
    cube.rotation.x = rot;
    cube.rotation.y = rot;

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }

  requestAnimationFrame(render);

这样一个基本的3D场景就创建好了,其运行效果是一个旋转的立方体。

但是当我们调整网页大小时,会发现有2个问题:

  1. 立方体会发生拉伸变形,变成了长方体

  2. 立方体的边缘会出现明显的锯齿

要解决第1个问题,需要按照canvas的大小来调整camera的aspect和投影矩阵:

const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();

要解决第2个问题,我们得明白canvas元素有2个尺寸,一个是页面上呈现出来的尺寸(可以通过css来设置的样式),一个是canvas本身的像素值(分辨率),这和一般的图像元素类似。解决的方法也和防止图像拉伸一样,我们需要使显示尺寸和分辨率这两者匹配起来。

function resizeRendererToDisplaySize(renderer) {
  const canvas = renderer.domElement;
  const width = canvas.clientWidth;
  const height = canvas.clientHeight;
  const needResize = canvas.width !== width || canvas.height !== height;
  if (needResize) {
    renderer.setSize(width, height, false);
  }
  return needResize;
}

这样我们就实现了3D场景的响应式设计。

可以在线查看实现效果:https://wow.techbrood.com/fiddle/54855

possitive(2) views4308 comments2

发送私信

最新评论

JustTes2020 2021-04-14 03:39:18

test


㌍㌫㌶㍊㍍㍑㌫㌶㍍㌫㌍ 2020-07-25 17:50:23

收藏了 不错


请先 登录 再评论.
相关文章
  • 常用光照类型基本概念工作原理及其计算公式

    在三维场景中,原理上物体的渲染效果取决于光照与物体表面的相互作用,对于渲染程序而言,可以通过把一些数学公式应用于像素着色来实现,从而模拟出真实生活中的...

  • 谷歌ARCore技术特性简介

    谷歌美国时间2017.8.29号刚发布了ARCore预览版,这是一个类似于苹果ARKit的增强现实SDK,在此之前,谷歌虽然已投资AR平台Tango,但由于需要特定的硬件和传感器,...

  • CSS3原生变量(Native Variables)新特性简介

    对Web开发者来说,一个盼望已久的特性是CSS终于支持原生变量了!
    变量是程序语言中用来解决代码重复和进行表达式计算的关键概念(想想数学方程式中的x)。...

  • React JSX语法简介

    JSX是一种类似XML的标签语法,用来简化代码,我们可以不使用JSX,但了解并使用也没什么坏处:)在React中,JSX是一个使用 React.createElement() API的快捷方式...

  • ES6小知识:动态对象键(Dynamic Object Keys)语法简介

    在ES5,对象的键(key)总是被解释为字符串。ES6允许我们使用计算的值作为对象的键,使用方括号:[myKey]const

  • JavaScript事件模型图解

    在JavaScript中用户交互的核心部分就是事件处理。本文为对事件模型和处理机制的总体性描述。Event是什么?
    event是用户操作网页时发生的交互动作,比如clic...

  • Web界面编程状态变化和JS开发框架(React/Angular/Ember)

    UI编程中的一个关键课题就是界面组件化(可复用)以及组件状态管理。稍早一些的windows程序员可能接触过MFC,其界面编程中有一个DDX(DoDataExchange)的机制,...

  • Babylon.js入门教程和开发实例

    Babylon.js是一款WebGL开发框架。和Three.js类似。主要的技术区别是Three.js还试图回退兼容CSS 3D。Three.js是完全社区推动的,比Babylon.js要成熟些,而Babylon...

  • 纹理基础知识和过滤模式详解

    1、 为什么在纹理采样时需要texture filter(纹理过滤)。
    我们的纹理是要贴到三维图形表面的,而三维图形上的pixel中心和纹理上的texel中心并不一至(pixe...

  • Three.js入门教程1 - 基础知识和创建一个红色球体

    [ TECHBROOD注:Three.js是一个主流的开源WebGL库,WebGL允许使用JavaScript直接操作GPU,在网页上实现3D效果。
    Google的工程师Paul在网站aerotwist.com上...

  • Three.js 开发基础知识 - 绘制3D对象

    Three.js是一个用来简化WebGL开发的JavaScript库,比如绘制一个三维立方体,使用WebGL需要100多行,那Three.js只要10几行就能够完成。本文通过创建一个立方体来...

  • 使用纯CSS3实现一个3D旋转的书本

    有一些前沿的电商网站已经开始使用3D模型来展示商品并支持在线定制,而其中图书的展示是最为简单的一种,无需复杂的建模过程,使用图片和CSS3的一些变换即可实现...

  • 更多...