three.js中场景模糊、纹理失真的问题
1. 概述
在three.js场景中,有时会遇到场景模糊,纹理失真的现象,似乎three.js并没有用到纹理图片应有的分辨率。可以通过相关设置来解决这个问题。
2. 方案
2.1. 开启反走样
three.js创建的WebGLRenderer对象有抗锯齿选项的支持:
var renderer = new THREE.WebGLRenderer({
antialias: true, //抗锯齿
});
这个选项默认是关闭的,所以需要显式开启一下。
2.2. 开启HiDPI设置
如果开启抗锯齿后仍然显示比较模糊,那么可能就是使用的是HiDPI (High Dots Per Inch) 设备显示造成的,HiDPI设备能在较小尺寸下显示出较高分辨率,也就是每一个屏幕上的物理像素其实是由多个像素显示出来的,所以需要设置一下设备像素比率:
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
其实关于HiDPI的讨论还是挺多的,比如说有个缩放与布局设置:
这个设置会更改window.devicePixelRatio的值,如果程序不做相关的设置,那么程序的UI显示出来就会是模糊的。现代程序组件一般都会自动做出相关的调整,在WebGL中则需要显式设置一下。
3. 结果
测试代码:
'use strict';
function init() {
//console.log("Using Three.js version: " + THREE.REVISION);
// create a scene, that will hold all our elements such as objects, cameras and lights.
var scene = new THREE.Scene();
// create a camera, which defines where we're looking at.
var camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
// create a render and set the size
var renderer = new THREE.WebGLRenderer({
antialias: true, //抗锯齿
});
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// add the output of the renderer to the html element
document.getElementById("webgl-output").appendChild(renderer.domElement);
var loader = new THREE.TextureLoader();
loader.setCrossOrigin('Anonymous');
var basePath = "1.jpg";
loader.load(basePath, function (texture) {
// create the ground plane
var planeGeometry = new THREE.PlaneGeometry(2, 2);
// var planeMaterial = new THREE.MeshBasicMaterial({
// color: 0xAAAAAA
// });
var planeMaterial = new THREE.MeshBasicMaterial({
map: texture
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
// add the plane to the scene
scene.add(plane);
renderer.render(scene, camera);
});
}
关闭反走样以及HiDPI:
开启反走样以及HiDPI之后显示效果有所改善: