https://webglfundamentals.org/webgl/lessons/webgl-cors-permission.html
https://github.com/Myoungmin/WebGL_Fundamentals
WebGL - Cross Origin Images
WebGL에서는 텍스처로 사용하기 위해 이미지를 다운로드한 다음 GPU에 업로드하는 것이 일반적이다.
일반적인 이미지를 다운로드 방법
// 텍스처 정보 { width: w, height: h, texture: tex } 생성합니다.
// 텍스처는 1x1 픽셀로 시작하고 이미지가 로드되면 업데이트됩니다.
function loadImageAndCreateTextureInfo(url) {
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
// 텍스처를 1x1 파란 픽셀로 채우기
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
1,
1,
0,
gl.RGBA,
gl.UNSIGNED_BYTE,
new Uint8Array([0, 0, 255, 255])
);
// 모든 이미지가 2의 거듭제곱이 아니라고 가정
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.LINEAR);
var textureInfo = {
width: 1, // 로드될 때까지 크기를 모름
height: 1,
texture: tex,
};
var img = new Image();
img.addEventListener('load', function() {
textureInfo.width = img.width;
textureInfo.height = img.height;
gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
});
img.src = url;
return textureInfo;
}
문제는 이미지에 개인 데이터가 있을 수 있다는 것이다.
웹 페이지에는 페이지를 직접 제어하지 않는 광고와 기타 요소들이 있으므로 브라우저는 이러한 개인 이미지를 볼 수 없도록 해야한다.
이미지가 브라우저에 표시되더라도 스크립트는 이미지 내부의 데이터를 볼 수 없기 때문에 <img src="private.jpg">만 사용하는 것은 괜찮다.
하지만 다른 도메인에서 가져와 그린 이미지라면 브라우저는 캔버스를 오염되었다고 표시하고 ctx.getImageData를 호출할 때 보안 오류가 발생한다.
WebGL은 더 나아가 같은 도메인이 아닌 모든 이미지를 금지한다.
CORS 입력하여 다른 도메인 이미지를 가져오기
CORS(Cross Origin Resource Sharing)는 웹 페이지에 이미지 사용 권한을 이미지 서버에 요청하는 방법이다.
이를 위해 crossOrigin 속성을 특정값으로 설정한 다음, 브라우저가 서버에서 이미지를 가져오려고 시도할 때, 동일한 도메인이 아니라면, 브라우저는 CORS 권한을 요청한다.
img.crossOrigin = ""; // CORS 권한 요청
crossOrigin에 설정할 수 있는 값 3가지
- "권한을 요청하지 않음"을 의미하는 기본값인 "undefined"
- "권한을 요청하지만 추가 정보를 보내지 않음"을 의미하는 "anonymous"
- "서버가 권한을 부여할지 말지 결정하기 위해 살펴보는 쿠키와 기타 정보 전송"을 의미하는 "use-credentials"
그 외 다른 값으로 crossOrigin을 설정하면 anonymous로 설정한 것과 같다.
로드하려는 이미지가 동일한 origin에 있는지 확인하고, 다르다면 crossOrigin 속성을 설정하는 함수
function requestCORSIfNotSameOrigin(img, url) {
if ((new URL(url, window.location.href)).origin !== window.location.origin) {
img.crossOrigin = "";
}
}
- 권한을 요청한다고 해서 권한이 부여되는 것은 아니다.
- Github page, flickr.com, imgur.com 등은 권한을 부여하지만, 대부분의 웹 사이트는 그렇지 않다.
- 권한을 부여하기 위해 서버는 이미지를 보낼 때 특정 헤더를 보낸다.
- 만약 다른 도메인의 이미지라면 crossOrigin 속성을 설정해야 하고 그렇지 않으면 서버가 올바른 헤더를 보내도 이미지를 사용할 수 없다.
https://myoungmin.github.io/WebGL_Fundamentals/
'WebGL' 카테고리의 다른 글
WebGL Fundamentals > Directional Lighting (0) | 2022.07.12 |
---|---|
WebGL Fundamentals > Rendering to a Texture (0) | 2022.07.08 |
WebGL Fundamentals > Using 2 or More Textures (0) | 2022.07.08 |
WebGL Fundamentals > Data Textures (0) | 2022.07.08 |
WebGL Fundamentals > WebGL Textures (0) | 2022.07.07 |