如何实现three.js响应式设计(消除拉伸变形和锯齿)
我们先创建一个基本的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个问题,需要按照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


- 相关文章
3D感知和建模关键硬件技术:双目、3D结构光和TOF
无论VR、AR和3D打印,其核心技术包含3D成像和建模。而3D建模属于劳动密集型的工作,耗时耗力,凡这类工作都会是被新技术革命的地方,自动3D建模技术就是为了解决...
OpenGL/WebGL顶点坐标变换过程简介
世界坐标是按照笛卡尔坐标系定义出来的绝对坐标系,下面的各种坐标系都建立在世界坐标的基础上。对象坐标系对象被应用于任何...
常用光照类型基本概念工作原理及其计算公式
在三维场景中,原理上物体的渲染效果取决于光照与物体表面的相互作用,对于渲染程序而言,可以通过把一些数学公式应用于像素着色来实现,从而模拟出真实生活中的...
CSS3原生变量(Native Variables)新特性简介
对Web开发者来说,一个盼望已久的特性是CSS终于支持原生变量了!
变量是程序语言中用来解决代码重复和进行表达式计算的关键概念(想想数学方程式中的x)。...CSS3特性查询(Feature Query: @supports)功能简介
这是2017年不能不了解和学习的一个CSS新特性,非常实用,考虑到现实世界浏览器的复杂性,该特性本应该先于其他新特性出来。我们已经知道使用媒体查询(Media Que...
深入理解CSS3滤镜(filter)功能和实例详解
CSS3滤镜功能源自SVG滤镜规范,SVG滤镜最早用来给矢量图添加类似PS中像素图的一些特效。
把这个滤镜功能引入到普通HTML元素中可以带来很有趣的效果(模糊、...深入理解Three.js(WebGL)贴图(纹理映射)和UV映射
本文将详细描述如何使用Three.js给3D对象添加贴图(Texture Map,也译作纹理映射,“贴图”的翻译要更直观,而“纹理映射”更准确。)。为了能够查看在线演示效...
三维向量的简单运算和实用意义
在WebGL的实际应用中我们广泛使用向量的几何运算来计算角度、距离,判断点线、点面之间的关系,比如物体之间的碰撞检测。本文简要介绍三维计算机图形学中常用的...
WebVR简介和常用资源链接
什么是WebVR这是一个实验性的JavaScript API,提供了在用户网页浏览器中访问虚拟现实设备的统一接口。当前主流VR设备如Oculus Rift DK2、谷歌的CardBoard、三星...
S3TC(S3 Texture Compression)纹理压缩格式详解
使用S3TC格式存储的压缩纹理是以4X4的纹理单元块(texel blocks)为基本单位存储的,每纹理单元块(texel blocks)有64bit或者128bit的纹理单元数据(texel data)。这...
如何实现SVG clipPath自适应被裁剪对象
CSS3中引入的clip-path(裁剪路径)属性是一个很强大的特性。
clip-path的含义如下图所示,好比剪纸一样,你用剪刀沿着某条路径把目标对象(图像或元素)裁...inline-block元素设置overflow:hidden属性导致相邻行内元素向下偏移
在表单修改界面中常会使用一个标签、一个内容加一个修改按钮来组成单行界面,如图1所示。那么在表单总长度受限的情况下,当中间的邮箱名称过长时,会遮盖到旁边...
div 、section 、article的区别和使用场景
div 、section 、article的区别和使用场景
主要区别,以及适用场合如下:
1、div在html早期版本就支持了,section和article是html5提出的两个雨衣话标... 更多...