2017-05-06 7 views
2

HTML5 캔버스의 이미지에 간단한 필터 효과를 적용하여 현재 재생 중입니다. 여기에 정의 된 기술과 유사 : 왜 CSS3 필터 효과가 HTML5 Canvas보다 더 효과적입니까?

HTML5 Canvas image contrast 그리고이 HTML5 Rocks! blog post

에서

그러나,이 특별한 접근 방식은 모든 픽셀과 다시 그릴 전에 수정을 적용을 반복하는이 이상이 필요합니다. 내 특정 사용 사례에 대해 내 이미지 (650px PNG로 650px)를 다시 그리려면 150ms +가 필요합니다.

CSS3's filter property (명암 또는 밝기)을 사용하여 동일한 효과를 적용하는 데 10ms 미만이 걸립니다.

내 질문은 : CSS3의 필터 속성은 어떻게 "내부적으로"작동합니까? 그리고 그것은 왜 훨씬 더 효과적입니까? Canvas에서 비슷한 성능을 얻을 수있는 방법이 있습니까?

답변

2

캔버스는 API를 통해 노출됩니다. 자바 스크립트는 런타임입니다. 자바 스크립트에서 픽셀 단위로 액세스하는 2D 그리드를 조작하려는 경우 요즘은 많이 최적화되었지만 런타임에서부터 버퍼까지 모든 액세스가 페널티로 처리됩니다 캔버스에 현재 저장된 이미지가 각 픽셀에 대해 입니다. 이 문제는 JavaScript로 필터 코드를 표현한다는 사실에 달려 있으며 최적화 되었더라도 런타임의 성질에 따라 처벌 될 수없는 처벌이 필요합니다.

CSS3 필터는 다소 로컬에 저장된 이미지에 액세스하는 GPU 쉐이더 프로그램은, 예를 들어, GPU 직접 실행하는 것을 의미 벌크 동일한 변환 할 수있는 블랙 박스 GPU의 메모리 및 GPU benefiting from its SIMD-class instructions으로 설계되어 전체 픽셀 행렬을 처리하는 경우으로 처리됩니다. 또한 로컬 메모리에 액세스하는 네이티브 코드 - 세부 사항에 익숙해지면서 얻을 수있는 최대한 빨리.

GPU를 지원하지 않고도 CPU에서 실행되는 경우에도 바이트 코드없이 RAM의 이미지를 직접 조작하는 기본 필터 커널과 더 중요한 것은 JavaScript를 전혀 고려하지 않고 말하는 것입니다. 원하는 필터를 선언하면 사용자 에이전트는 캔버스 이미지에서 필터 프로그램을 호출합니다. CPU는 또한 데이터 벡터에서 작업 할 수있는 SIMD 명령어를 가지고있어서 분명히 큰 도움이됩니다. 필터 코드는 사용자 이름이 아니며 이름으로 만 참조 할 수 있습니다.

CSS에서 사용할 수있는 것과 같은 종류의 블랙 박스 필터를 캔버스 픽셀 데이터 에 직접 적용하면 CSS와 동일한 속도를 얻을 수 있습니다. 가장 중요한 장애물 JavaScript 코드로 표현 된 픽셀 단위의 액세스 속도를 줄이기 위해 따라서 JavaScript에 관한 것만이 아니라 입니 다 데이터 액세스입니다. 이 경우 커널을 대량으로 데이터에 적용하면 더 높은 수준의 커널 코드를 직접 작성하는 것보다 항상 빠릅니다. 간단히 말하면, 아래 마지막 지점으로 안내합니다.

이제, 자바 스크립트 인터프리터는 은 픽셀 단위 - 인 - 어 - 루프를 이해할 수 있다면 그것은 당신의 모든 아마 SIMD 심지어 GPU shaders을 이용하여 네이티브 코드로 모두 변환 할 수 있다는 점에서 조작 자유 형식의 JavaScript 필터 코드를 사용하면 성능 차이를 줄일 수 있습니다.하지만 복잡성을 JavaScript 컴파일러/인터프리터로 옮겨야 할 것입니다. 그런 규모로 최적화하는 문제는 아직 컴퓨터 과학에서 문제를 완전히 해결 한 것이 아닙니다. 어쩌면 인공 지능과 기계 학습이 도움이 될 것입니다. 나는 그것에 대해 추측하지 않을 것입니다. 당신이 말하고 있지 않다는 것을 알고 있습니다. JIT-compiling JavaScript를 동등한 원시 코드로 변환하는 JavaScript는 수년간의 규범이었습니다. 자유 형식의 JavaScript 코드를 알려진 또는 아마도 임의의 이미지 커널을 닮은 것으로 인식하고 있습니다. 인간이. 그런 다음 동일한 결과를 제공하지만 컴파일러가 최적의 성능을 제공한다고 생각하는 결과를 산출하는 런타임 대응 코드로 해당 코드를 대체합니다. 실제로

, 내가 생각하는 당신 최적화 캔버스 기반의 자바 스크립트 순진 픽셀 단위 필터, 당신은 Canvas API (나는 분명한 이유, MDN -authorative 소스 생각에 더 깊이 살펴 경우). 이미지 데이터는 CanvasRenderingContext2D.getImageData() 메서드 호출에서 얻을 수있는 Uint8ClampedArray 유형을 통해 액세스 할 수 있습니다. 이 배열 유형은 filter, forEach, map, reduce 등 흥미로운 "대량"함수를 가지고 있습니다. 캔버스 API 문서를 탐색 할 때 demoscene 사람의 사고 방식을 가정 할 때 "해커"와 같은 생각을해야합니다. 그들이 당신에게 줄 수있는 관점에서 사용 가능한 방법과 데이터 유형. 이렇게하는 것에 대한 보상은 상당 할 수 있습니다.

충분하지 않은 경우 캔버스는 OpenGL의 하위 집합 인 API 인 WebGL으로 렌더링 할 수 있습니다. 일반적으로 GPU에서만 실행되도록 구현되었습니다. 셰이더는 WebGL의 일부가되도록 보장되어 있습니다. 즉, WebGL을 사용하여 모든 종류의 고급 초고속 캔버스 필터 프로그램에 대한 무료 티켓을 얻었습니다.이 프로그램은 사용자가 직접 작성하지만 GPU에서 일반적으로 실행되는 프로그램입니다.

+0

나는이 말은 아니지만 ... 와우. 세부 사항 및 설명에 놀랐습니다. 나는 너의 시간을 크게 주셔서 감사합니다! –

+0

실제로 브라우징하는 동안 귀하의 질문을 보았습니다.이 질문에 관심이 있고 그래픽 처리와 관련된 일부 배경에서 오는 순수한 바보 같은 행운이었습니다. 모든 종류의 대답을 쓸 수있는 모든 것을 느꼈습니다. 유용하다고 생각해서 다행입니다. 확실히 더 많은 것이 있습니다. 그러나 나는 이미 시작을위한 텍스트 벽이 너무 많을 까봐 걱정했습니다. API를 잘 살펴보십시오 (f. https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API (* semi * -authorative source, 마음에 두십시오.) 나는 실제로 그것을 개선하기 위해 나중에 답변에 더 많은 것을 추가하고자 할 것입니다. – amn