Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Canvas 使用webgl绘制高分辨率画布_Canvas_Webgl_Snapshot_High Resolution - Fatal编程技术网

Canvas 使用webgl绘制高分辨率画布

Canvas 使用webgl绘制高分辨率画布,canvas,webgl,snapshot,high-resolution,Canvas,Webgl,Snapshot,High Resolution,我想要得到我的webgl画布的快照,我想要一个高分辨率的捕获,所以我增加了画布的大小。这会自动更改gl.draingBufferWidth和gl.draingBufferWidth。然后设置“视口”,然后渲染场景 我的代码在低分辨率(低于4000*4000)下正常工作,但在高分辨率下存在许多问题 如果分辨率稍高,快照不会完全显示。见附件。如果分辨率增加更多,则不会显示任何内容。最后,在某些分辨率下,我的webgl实例被销毁,我必须重新启动浏览器才能再次运行webgl 有没有办法从高分辨率的web

我想要得到我的webgl画布的快照,我想要一个高分辨率的捕获,所以我增加了画布的大小。这会自动更改
gl.draingBufferWidth
gl.draingBufferWidth
。然后设置“视口”,然后渲染场景

我的代码在低分辨率(低于4000*4000)下正常工作,但在高分辨率下存在许多问题

如果分辨率稍高,快照不会完全显示。见附件。如果分辨率增加更多,则不会显示任何内容。最后,在某些分辨率下,我的webgl实例被销毁,我必须重新启动浏览器才能再次运行webgl


有没有办法从高分辨率的webgl画布获取快照?我可以使用其他解决方案吗?

使用
gl.getParameter(gl.MAX\u renderbuffer\u size)
检查最大渲染缓冲大小。你的画布不能再大了。试图突破限制会使你失去上下文


如果想要更大的屏幕截图,可以分多个步骤/分幅渲染。调整投影变换以实现这一点应该相当容易。

4000x4000像素是4000x4000x4或64meg内存。8000x8000是256meg内存。浏览器不喜欢分配那么大的内存块,并且经常对页面设置限制。例如,您有一个8000x8000 WebGL画布,它需要2个缓冲区。页面上显示的drawingbuffer和纹理。drawingbuffer可能是抗锯齿。如果它是4倍MSAA,那么就需要一个gig的内存来缓冲。然后你拍一张截图,这样就又有了256毫克的内存。因此,是的,浏览器出于这样或那样的原因可能会杀死你的页面

除此之外,WebGL在大小上也有自己的限制。您可以查找有效或无效的限制。从中可以看出,大约40%的机器不能绘制大于4096的图形(尽管如果您需要的话)。这个数字只意味着硬件可以做什么。它仍然受到内存的限制

解决这个问题的一种方法是把图像分成几部分。你如何做到这一点将取决于你的应用程序。如果所有渲染都使用相当标准的透视矩阵,则可以使用稍微不同的数学来渲染视图的任何部分。大多数三维数学库都有一个
透视
函数,其中大多数库也有相应的
平截头体
函数,该函数稍微灵活一些

下面是一个相当标准风格的WebGL简单示例,它使用典型的
透视图
函数绘制了一个立方体

“严格使用”;
常数vs=`
均匀mat4 u_世界视图投影;
属性向量4位置;
属性向量3正常;
可变vec3 v_正常;
void main(){
v_normal=正常;
gl_位置=u_世界视图投影*位置;
}
`;
常数fs=`
精密中泵浮子;
可变vec3 v_正常;
void main(){
gl_FragColor=vec4(v_normal*.5+.5,1);
}
`;
常数m4=twgl.m4;
const gl=document.querySelector(“canvas”).getContext(“webgl”);
const programInfo=twgl.createProgramInfo(gl[vs,fs]);
const bufferInfo=twgl.primitives.createCubeBufferInfo(gl,2);
twgl.resizeCanvasToDisplaySize(总图画布);
总图视口(0,0,总图画布宽度,总图画布高度);
总帐启用(总帐深度测试);
总账启用(总账消隐面);
gl.clearColor(0.2,0.2,0.2,1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
常数fov=30*Math.PI/180;
const aspect=gl.canvas.clientWidth/gl.canvas.clientHeight;
常数zNear=0.5;
常数zFar=10;
常量投影=m4.透视图(视野、纵横比、zNear、zFar);
常数眼=[1,4,-6];
常量目标=[0,0,0];
const up=[0,1,0];
常量摄影机=m4。注视(眼睛、目标、向上);
常量视图=m4。反向(摄像头);
const viewProjection=m4.乘法(投影,视图);
const world=m4.rotationY(Math.PI*.33);
总账使用程序(programInfo.program);
twgl.setBuffersAndAttributes(总帐、程序信息、缓冲信息);
twgl.设置制服(程序信息{
u_worldViewProjection:m4.乘法(viewProjection,world),
});
twgl.drawBufferInfo(总账,bufferInfo)


您提到了一个屏幕截图,但没有添加它。为什么要投否决票?最大画布大小由RENDERBUFFER_大小决定,而不是纹理_大小。我只是猜测下一票是因为这没有回答问题?看起来这个答案基本上只是说“解决方案存在”,然后让提问者自己找出答案?