Three.js 如何使用threejs在iPhone上启用retina resolution render.setSize

Three.js 如何使用threejs在iPhone上启用retina resolution render.setSize,three.js,mobile-safari,Three.js,Mobile Safari,使用threejs,可以绘制两倍大的画布,但是如何使用css缩小画布,使其以iPhone的正确分辨率显示呢 renderer.setSize(window.innerWidth、window.innerHeight) 结果是像素化的图像,这起作用: renderer.setSize(window.innerWidth*2,window.innerHeight*2) 然后画布对于屏幕来说太大了,我似乎无法让css正确地缩小它。更不用说在带有视网膜显示器的笔记本电脑上做这件事了,那简直是太可怕了。这

使用threejs,可以绘制两倍大的画布,但是如何使用css缩小画布,使其以iPhone的正确分辨率显示呢

renderer.setSize(window.innerWidth、window.innerHeight)

结果是像素化的图像,这起作用:

renderer.setSize(window.innerWidth*2,window.innerHeight*2)

然后画布对于屏幕来说太大了,我似乎无法让css正确地缩小它。更不用说在带有视网膜显示器的笔记本电脑上做这件事了,那简直是太可怕了。这是因为它使用WebGL绘制屏幕吗


如何在3J中容纳这些不同的像素密度?

您可以使用类似的方法,根据设备支持的内容设置像素比率:

renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
确保画布的大小不是文档大小的两倍,将使用一些CSS,如下所示:

canvas {
  display: block;
}

有很多方法可以做到这一点。下面是另一个示例-

您可以使用类似的方法,根据设备支持的内容设置像素比率:

renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
确保画布的大小不是文档大小的两倍,将使用一些CSS,如下所示:

canvas {
  display: block;
}

有很多方法可以做到这一点。下面是另一个例子-

如果是我,我会让CSS设置画布的大小。然后我会问浏览器画布的大小

const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
并使用

renderer.setSize(desiredWidth, desiredHeight, false);
最后传递
false
非常重要,这样three.js就不会把CSS搞砸

此外,我从不使用
setPixelRatio
,因为它只会导致错误和歧义。相反,我会计算出我想要的尺寸,然后使用这个尺寸。范例

const pixelRatio = window.devicePixelRatio;
const desiredWidth = canvas.clientWidth * pixelRatio | 0;
const desiredHeight = canvas.clientHeight * pixelRatio | 0;
renderer.setSize(desiredWidth, desiredHeight, false);
为什么要使用CSS并查找大小? 通过使用CSS,您的代码在所有情况下都能工作。如果您希望画布全屏显示,或者希望画布成为段落中的图表,或者希望画布在flexbox或网格中可拉伸,无论您如何操作,都可以获得正确的大小

为什么不使用
setPixelRatio
? 当您使用setPixelRatio时,您现在拥有的画布drawingbuffer的大小与您指定的大小不同。在许多情况下,您需要知道实际尺寸。这包括使用特定类型的效果、读取GPU拾取的像素、可能的截图、用点绘制等等。。。当您使用
setPixelRatio
时,您真的不知道画布drawingbuffer的最终大小。是的,你相信代码只会乘以设备像素比,但它会取整吗?四舍五入明天会改变吗?你不知道。所以不使用它你就知道画布的大小了。它始终是调用
setSize
时指定的大小。这意味着您可以在任何地方使用该尺寸。你不必猜测什么时候使用指定的大小合适,什么时候需要做不同的计算。请注意,如果您做了错误的计算,那么您的应用程序可能会在像素比为1的设备上运行,但在其他像素比的设备上失败。如果不使用
setPixelRatio
,这些错误将变得不可能

您可能根本不想设置像素比率 如果像素比率为2,设备需要绘制4倍像素,就像像素比率为1一样。如果像素比率为3,则绘制9倍的像素。一些设备甚至具有3.5或4的设备像素比,即像素的16倍。这会使你的页面运行非常慢。仅仅因为设备的像素比率高而盲目地设置像素比率会导致页面变慢。很少有本土游戏会这样做,因为它们运行得太慢了。不设置它通常是合适的

例如:

html,正文{
保证金:0;
身高:100%;
}
#c{
宽度:100%;
身高:100%;
显示:块;
}

将*作为三个源导入'https://threejsfundamentals.org/threejs/resources/threejs/r113/build/three.module.js';
函数main(){
const canvas=document.querySelector(“#c”);
const renderer=new THREE.WebGLRenderer({canvas});
常数fov=75;
const aspect=2;//画布默认值
常数近=0.1;
常数far=5;
常量摄影机=新的三个透视摄影机(视野、方位、近距离、远距离);
摄像机位置z=2;
const scene=new THREE.scene();
{
常量颜色=0xFFFFFF;
常数强度=1;
恒定光=新的三个方向光(颜色、强度);
灯。位置。设置(-1,2,4);
场景。添加(灯光);
}
常数boxWidth=1;
const-boxHeight=1;
常数boxDepth=1;
const geometry=新的三个.BoxGeometry(boxWidth、boxHeight、boxDepth);
函数makeInstance(几何体、颜色、x){
const material=新的3.MeshPhongMaterial({color});
常量立方体=新的三个网格(几何体、材质);
场景.添加(立方体);
立方体位置x=x;
返回立方体;
}
常数立方=[
makeInstance(几何体,0x44aa88,0),
makeInstance(几何体,0x8844aa,-2),
makeInstance(几何体,0xaa8844,2),
];
函数resizeRenderToDisplaySize(渲染器){
const canvas=renderer.domeElement;
const pixelRatio=window.devicePixelRatio;
常量宽度=canvas.clientWidth*像素比率| 0;
常数高度=canvas.clientHeight*像素比率| 0;
const needResize=canvas.width!==width | | canvas.height!==height;
如果(需要调整大小){
设置大小(宽度、高度、假);
}
返回需要调整大小;
}
函数渲染(时间){
时间*=0.001;
if(ResizeRenderToDisplaySize(渲染器)){
const canvas=renderer.domeElement;
camera.aspect=canvas.clientWidth/canvas.clientHeight;
camera.updateProjectMatrix();
}
cubes.forEach((cube,ndx)=>{
恒速=1+ndx*.1;
恒速=时间*速度;
立方体旋转x=旋转;
cube.rotation.y=rot;
});
渲染器。渲染(场景、摄影机);
请求动画帧(渲染);
}
请求动画帧(渲染);
}
main();

如果是我,我会让CSS设置画布的大小。然后我会问