HTML, Canvas 및 WebGL 간의 품질 차이 (Quality differences between HTML, Canvas and WebGL)


문제 설명

HTML, Canvas 및 WebGL 간의 품질 차이 (Quality differences between HTML, Canvas and WebGL)

WebGL로 이미지를 그리고 싶지만 축소되었습니다. 크기를 조정하지 않으면 이미지 품질이 좋지만 크기를 줄이면 품질이 떨어집니다.

'Handling High DPI(Retina) display in WebGL'에 대해 다음에서 읽었습니다. 여기: 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);

하지만 이것은 HTML 이미지와 같은 품질을 가지고 있지 않았습니다. HTML의 내 코드:

        setTimeout(function() {

            var imagine = new Image();
            imagine.src = 'Tank.png';
            imagine.width = '28';
            imagine.height = '35';
            document.body.appendChild(imagine);

        }, 1000);

캔버스의 내 코드:

        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');



이미지 품질의 차이는 아래 ( 품질: WebGL <캔버스

WebGL Canvas HTML

큰 차이는 아니지만 좋은 품질의 사진을 보여줍니다. HTML에서는 그림이 더 부드럽습니다. Chrome 브라우저를 확대하면 HTML의 그림이 품질이 향상되는 것을 관찰했습니다. 그러나 WebGL 사진은 동일한 해상도로 유지되며 품질이 저하됩니다. 그리고 페이지를 새로고침하여 WebGL용 devicePixelRatio를 업데이트하면 사진의 품질은 더 좋아지지만 내 브라우저는 500% 확대/축소에서 느리게 작동합니다. 캔버스를 더 크게 만들고 더 많이 그려야 하기 때문이라고 생각합니다. 하지만 HTML에서는 500% 줌으로 이미지를 움직이면 문제가 없고, 이미지도 잘 움직이고 화질도 좋습니다.


여기서 상황 ‑ WebGL 이미지 렌더링 품질이 좋지 않음 ‑ 이미지 크기가 조정되지 않았지만 크기 조정이 필요합니다. 다운 사진.

이 상황과 비교 ‑ canvas drawImage 품질 ‑ 세 프로그램 모두에서 값을 정수로 입력했습니다.



마지막 질문:

HTML에서와 같은 품질로 webGL에서 이미지를 그리고(해당 트랙에서 해당 선이 보이지 않음) 브라우저 확대 시에도 좋은 품질을 얻으려면 어떻게 해야 합니까? 내가 그들을 그릴 수 있는 다른 가능성은 무엇입니까? 어떤 기술을 사용해야 합니까? WebGL에는 HTML에 없는 몇 가지 기능이 있기 때문에 사용하고 싶었고 선이나 점과 같이 처음부터 몇 가지를 그리고 싶었습니다.


편집 1: 이것은 일반 해상도의 사진입니다.


enter image description here

Rendering

The next image show the rendered results, pixel aligned (WebGL top tow rows have same result in 2D)

From left to right is the size of the original source image, 2 times to 16 times the final size.

Each row uses a different pixel lookup

  • Nearest. The fastest rendering the pixel nearest the top left of each pixel the final render

  • Linear. Default for 2d (smoothing = true), webGL (gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)). The pixel color is a linear interpolation of the 4 pixels near (under, right, below, below right) the final pixel.

  • Log mean. Custom WebGL only. The fragment shader uses the total photon count of all pixels under the rendered pixel to calculate the final RGB pixel color. For original 2 times the size GPU cost is about the same as Linear, For 16 times is only for the high end devices, or low image rendering counts (64 times slower than linear per pixel)

  • Log Mean +. Uses same fragment shader as Log Mean to render but pre processes (Just in time) the original using a modified sharpen convolution filter to sharpen at 2/3 * invScale (Log calcs) to increase the visual contrast at low contrast boundaries. The Cost is a one time init cost.

enter image description here

Personally for real‑time projects I use second row first column 2 * linear, and when rendering on HDPI or high render counts I use the simplest 1 * linear (not shown).

Most people can not tell the difference between the 2nd, 3rd and last rows. Can you without zooming in on the image?

Rotation

The next image shows the same method from 2 times to 16 times left to right, then rows linear, nearest, and log mean, +.

enter image description here

Notes

  • Log RGB image processing only has a significant improvement with highly saturated images with high colour contrast. The tank image has very low colour contrast and thus does not get much benefit from Log Mean. The next image shows from left to right nearest, linear, and log mean of high colour contrast version.

enter image description here

  • All images in this answer were created on GPU accelerated Chrome 80 Win 10 x64. Original tank reference image by the OP.

  • I just noticed, as I finish, that the Nearest rotated images all have anti‑aliasing on the outer edges. This is an error on my part as I forgot to give the image some transparent padding. The anti‑aliasing is due to the polygon edge and not part of the pixel gl.TEXTURE_MIN_FILTER, gl.LINEAR lookup process. To much work to fix, sorry.

방법 2:

If you want your pictures to be drawn more smooth, then you could use mipmaps! Try to make the pictures to have both dimensions a power at 2 and after you can generate mipmaps, like this:

gl.generateMipmap(gl.TEXTURE_2D);

With mipmaps you can choose what WebGL does by setting the texture filtering for each texture. And if you want to your image to be smooth, then you have to change the texture filtering to be LINEAR_MIPMAP_LINEAR. So after you generate the mipmaps you have to write:

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);

The pictures with the differences are below ( LINEAR vs LINEAR_MIPMAP_LINEAR ):

LINEARLINEAR_MIPMAP_LINEAR

In first picture the tracks are asymmetric, but the second picture is drawn smooth. I think that the second picture looks more like the HTML picture that you provided.


There is a great tutorial about WebGL Textures: https://webglfundamentals.org/webgl/lessons/webgl‑3d‑textures.html. There is written that this type of texture filtering is the slowest and it takes 33% more memory, so be aware of that!

(by Niqusor31Blindman67Niqusor31)

참조 문서

  1. Quality differences between HTML, Canvas and WebGL (CC BY‑SA 2.5/3.0/4.0)

#image #html #canvas #webgl #javascript






관련 질문

이미지가 추가될 때 div 높이가 과도하게 늘어남 (div height overstretching when image is appended)

MS-Outlook 임베디드 이미지를 가져오고 MS-Access VBA를 사용하여 파일 시스템에 저장 (Getting MS-Outlook embedded images and saving them within the file system using MS-Access VBA)

Android 이미지 갤러리 이미지 자르기 및 ImageView 설정 (Android Image Gallery Crop Image and set ImageView)

Facebook은 드래그하여 이미지를 닫는 데 어떤 라이브러리를 사용합니까? (What library does Facebook use for dismiss image by dragging?)

이미지를 Picturebox(VB6의 이미지)에서 문자열(Base64)로 변환하는 방법은 무엇입니까? (How to convert Image from a Picturebox(Image in VB6) to String(Base64)?)

HTML, Canvas 및 WebGL 간의 품질 차이 (Quality differences between HTML, Canvas and WebGL)

TBitmapImage는 Inno Setup 6에서 크기 조정된 디스플레이의 크기보다 크게 렌더링됩니다. (TBitmapImage is rendered larger than its size on scaled display in Inno Setup 6)

이미지 URL이 실제 이미지를 가리키는지 확인합니다. 문제를 일으키는 URL의 공백 (Check if an image URL points to an actual image. Space in URL in causing issue)

android studio에서 인텐트를 통해 여러 콘텐츠를 보내는 방법 (how can i send multiple contents through intent in android studio)

Squarespace 사이트용 CSS로 이미지의 위치를 완벽하게 제어 (Fully Control The Location of an Image with CSS for Squarespace site)

iText7을 사용하여 PDFButtonFormField에 이미지를 추가할 때 종횡비를 유지하는 방법 (How to Maintain Aspect Ratio when Adding an Image to a PDFButtonFormField using iText7)

png 이미지에서 픽셀 색상 추출 (extracting pixel color from png image)







코멘트