Niq*_*r31 0 html javascript canvas image webgl
我想在 WebGL 中绘制图像,但缩小了尺寸。当我不缩放它时,图像的质量很好,但如果我缩小它,那么图像的质量很差。
我从这里读到“在 WebGL 中处理高 DPI(视网膜)显示”: http: //www.khronos.org/webgl/wiki/HandlingHighDPI,我尝试做同样的事情。我在 WebGL 中的代码是:
Initializations:
var devicePixelRatio = window.devicePixelRatio || 1;
gl.canvas.style.width = "800px";
gl.canvas.style.height = "600px";
canvas.width = Math.round(800 * devicePixelRatio);
canvas.height = Math.round(600 * devicePixelRatio);
For drawing:
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
matrix = m3.scale(matrix, 28/800, 35/600); // matrix for scaling texture
Textures:
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
Run Code Online (Sandbox Code Playgroud)
但这并不具有与 HTML 图像相同的质量。我的 HTML 代码是:
setTimeout(function() {
var imagine = new Image();
imagine.src = 'Tank.png';
imagine.width = '28';
imagine.height = '35';
document.body.appendChild(imagine);
}, 1000);
Run Code Online (Sandbox Code Playgroud)
我在画布中的代码是:
var imagine = new Image();
imagine.src = 'Tank.png';
imagine.width = '28';
imagine.height = '35';
imagine.onload = function() {
context.drawImage(imagine, 0, 0, 28, 35);
}
context = canvas.getContext('2d');
Run Code Online (Sandbox Code Playgroud)
图像质量之间的差异如下(质量:WebGL < Canvas < HTML)
我知道这并不是很大的区别,但我真的想以高质量展示图片。在 HTML 中,图片更加流畅。我观察到,如果我放大 Chrome 浏览器,来自 HTML 的图片质量会提高,但 WebGL 图片仍保持相同的分辨率,并且质量会下降。如果我刷新页面,更新 WebGL 的 devicePixelRatio,那么图片的质量会更好,但我的浏览器在 500% 缩放时工作速度会变慢,我想是因为它使画布更大并且必须绘制更多内容。但在 HTML 中,如果我以 500% 缩放移动图像,则没有问题,图像移动良好且质量良好。
在这种情况下 - WebGL 图像渲染质量较差- 图像未缩放,但我需要缩小图片。
与这种情况相比 -画布绘制图像质量- 我在所有三个程序中将值设置为整数。
最后一个问题:
如何在 webGL 中以与在 HTML 中相同的质量(看不到这些轨道中的线条)绘制图像,并且即使浏览器放大也能获得良好的质量?我还有什么其他的可能性来绘制它们?我应该使用什么技术?我想使用 WebGL,因为它具有 HTML 所没有的一些功能,并且我想从头开始绘制一些东西,例如线条或点。
编辑1:这是正常分辨率的图片。
在这张图中,铁轨的线条似乎不是直的,而是交叉的。如果您可以仔细观察 Canvas 和 WebGL 中的图像,就会发现轨道的第一条线(第一条在左边,第一条在右边)是直的。而且,使用Canvas的图片有更多的直线轨迹,甚至是最后的轨迹。HTML 的最后一个图像具有相同形状的所有轨道。
抱歉,因为我放了很小的照片。这是因为我需要这个比例,并且我需要图片不要更大。如果我要绘制更大的图片,那么 devicePixelRatio 将使图片看起来更好,但我不使用正常尺寸的图片。这样的话,这个问题就可以通过devicePixelRatio来解决。对于较小的尺寸,这种使用 devicePixelRatio 的方法对我没有帮助。这就是为什么我正在寻找另一种解决方案。
如果图像经过变换和动画处理,则最好使用线性插值,原始图像至少比渲染结果大 2 倍。
确保画布(2D 或 WebGL)与设备像素对齐,并且与物理设备像素一对一匹配。
如果它是 1 或 2 以外的任何其他值(2 表示 HDPI 或视网膜) ,请勿使用devicePixelRatio,因为其他值意味着页面已缩放,并且您无法获得一对一的像素与设备像素匹配。尝试缩放画布(2D 或 WebGL)只会降低质量。
这最适用于绘制到像素边界的轴对齐渲染图像。然而,它对于缩放、旋转和/或未对齐渲染仍然有一些好处。
高质量画布(2d 或 webGL)图像渲染最重要的部分是原始图像大小与渲染结果之间的关系。
如果将图像缩小到 28 x 35 像素,则原始图像必须为 2* (68, 92) 4* (136, 184) 等...最终渲染结果大小的 2 倍幂。 注意您必须考虑较大图像的 GPU RAM 成本。
图像中必须尽可能保持清晰的重要细节必须与渲染的像素边缘对齐,否则最终会得到模糊的细节。
下图是最终尺寸的16*。它上面有一个棋盘(每个正方形 16 × 16 像素),用于显示渲染像素的大小。
注意履带、车身、枪管、炮塔的边缘如何与最终缩小的像素对齐。
下图显示了渲染结果,像素对齐(WebGL 顶部两行在 2D 中具有相同的结果)
从左到右是原始源图像的尺寸,是最终尺寸的2倍到16倍。
每行使用不同的像素查找
最近的。最终渲染最接近每个像素左上角的像素的最快渲染
线性。默认为 2d(平滑 = true),webGL ( gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR))。像素颜色是最终像素附近(下、右、下、右下)的 4 个像素的线性插值。
对数的意思。仅限自定义 WebGL。片段着色器使用渲染像素下所有像素的总光子计数来计算最终的 RGB 像素颜色。对于原始大小的 2 倍 GPU 成本与线性大致相同,对于 16 倍仅适用于高端设备,或低图像渲染计数(每像素比线性慢 64 倍)
对数平均值+。使用与 Log Mean 相同的片段着色器进行渲染,但使用修改后的锐化卷积滤波器对原始数据进行预处理(及时)以在2/3 * invScale(Log 计算)处锐化,以增加低对比度边界处的视觉对比度。成本是一次性初始成本。
就个人而言,对于实时项目,我使用第二行第一列 2 * 线性,在 HDPI 或高渲染计数上渲染时,我使用最简单的 1 * 线性(未显示)。
大多数人无法区分第二行、第三行和最后一行。可以不放大图像吗?
下图显示了从左到右 2 次到 16 次的相同方法,然后是线性行、最近行和对数平均值、+。
本答案中的所有图像都是在 GPU 加速的 Chrome 80 Win 10 x64 上创建的。OP 提供的原始坦克参考图像。
我刚刚注意到,当我完成时,Nearest旋转的图像在外边缘都有抗锯齿功能。这是我的一个错误,因为我忘记给图像一些透明的填充。抗锯齿是由于多边形边缘而不是像素gl.TEXTURE_MIN_FILTER, gl.LINEAR查找过程的一部分。需要修复的工作量很大,抱歉。
| 归档时间: |
|
| 查看次数: |
2089 次 |
| 最近记录: |