Using textures in WebGL
СейÑÐ°Ñ Ð½Ð°Ñа пÑогÑамма ÑиÑÑÐµÑ Ð²ÑаÑаÑÑийÑÑ Ð¾Ð±ÑÑмнÑй кÑб - давайÑе наÑÑнем на него ÑекÑÑÑÑÑ Ð²Ð¼ÐµÑÑо заливки гÑаней одним ÑвеÑом.
ÐагÑÑзка ÑекÑÑÑÑ
СнаÑала нÑжно добавиÑÑ ÐºÐ¾Ð´ Ð´Ð»Ñ Ð·Ð°Ð³ÑÑзки ÑекÑÑÑÑ. РнаÑем ÑлÑÑае Ð¼Ñ Ð±Ñдем иÑполÑзоваÑÑ Ð¾Ð´Ð½Ñ ÑекÑÑÑÑÑ, наÑÑнÑÑÑÑ Ð½Ð° вÑе ÑеÑÑÑ Ð³Ñаней вÑаÑаÑÑегоÑÑ ÐºÑба, но ÑÑÐ¾Ñ Ð¿Ð¾Ð´Ñ Ð¾Ð´ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸ÑполÑзован Ð´Ð»Ñ Ð·Ð°Ð³ÑÑзки лÑбого колиÑеÑÑва ÑекÑÑÑÑ.
ÐÑимеÑание: Ðажно помниÑÑ, ÑÑо загÑÑзка ÑекÑÑÑÑ ÑледÑÐµÑ Ð¿Ñавилам кÑоÑÑ-доменноÑÑи, ÑÑо ознаÑаеÑ, ÑÑо Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе загÑÑжаÑÑ ÑекÑÑÑÑÑ ÑолÑко Ñ ÑайÑов, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ Ð²Ð°Ñ ÐºÐ¾Ð½ÑÐµÐ½Ñ ÑвлÑеÑÑÑ CORS довеÑеннÑм. См. подÑобноÑÑи в ÑекÑии "ÐÑоÑÑ-доменнÑе ÑекÑÑÑÑÑ" ниже.
Ðод Ð´Ð»Ñ Ð·Ð°Ð³ÑÑзки ÑекÑÑÑÑ Ð²ÑглÑÐ´Ð¸Ñ Ñак::
//
// ÐниÑиализаÑÐ¸Ñ ÑекÑÑÑÑÑ Ð¸ загÑÑзка изобÑажениÑ.
// Ðогда загÑÑзка изобÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð·Ð°Ð²ÐµÑÑена - копиÑÑем его в ÑекÑÑÑÑÑ.
//
function loadTexture(gl, url) {
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// Так как изобÑажение бÑÐ´ÐµÑ Ð·Ð°Ð³ÑÑжено из инÑеÑнеÑа,
// Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ Ð²ÑÐµÐ¼Ñ Ð´Ð»Ñ Ð¿Ð¾Ð»Ð½Ð¾Ð¹ загÑÑзки.
// ÐоÑÑÐ¾Ð¼Ñ ÑнаÑала Ð¼Ñ Ð¿Ð¾Ð¼ÐµÑаем в ÑекÑÑÑÑÑ ÐµÐ´Ð¸Ð½ÑÑвеннÑй пикÑелÑ, ÑÑобÑ
// ÐµÑ Ð¼Ð¾Ð¶Ð½Ð¾ бÑло иÑполÑзоваÑÑ ÑÑазÑ. ÐоÑле завеÑÑÐµÐ½Ð¸Ñ Ð·Ð°Ð³ÑÑзки
// изобÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð¼Ñ Ð¾Ð±Ð½Ð¾Ð²Ð¸Ð¼ ÑекÑÑÑÑÑ.
const level = 0;
const internalFormat = gl.RGBA;
const width = 1;
const height = 1;
const border = 0;
const srcFormat = gl.RGBA;
const srcType = gl.UNSIGNED_BYTE;
const pixel = new Uint8Array([0, 0, 255, 255]); // непÑозÑаÑнÑй Ñиний
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
width, height, border, srcFormat, srcType,
pixel);
const image = new Image();
image.onload = function() {
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
srcFormat, srcType, image);
// У WebGL1 инÑе ÑÑÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ðº изобÑажениÑм, имеÑÑим ÑÐ°Ð·Ð¼ÐµÑ ÑÑепени 2,
// и к не имеÑÑим ÑÐ°Ð·Ð¼ÐµÑ ÑÑепени 2, поÑÑÐ¾Ð¼Ñ Ð¿ÑовеÑÑем, ÑÑо изобÑажение
// Ð¸Ð¼ÐµÐµÑ ÑÐ°Ð·Ð¼ÐµÑ ÑÑепени 2 в обеиÑ
измеÑениÑÑ
.
if (isPowerOf2(image.width) && isPowerOf2(image.height)) {
// Ð Ð°Ð·Ð¼ÐµÑ ÑооÑвеÑÑÑвÑÐµÑ ÑÑепени 2. СоздаÑм MIP'Ñ.
gl.generateMipmap(gl.TEXTURE_2D);
} else {
// Ð Ð°Ð·Ð¼ÐµÑ Ð½Ðµ ÑооÑвеÑÑÑвÑÐµÑ ÑÑепени 2.
// ÐÑклÑÑаем MIP'Ñ Ð¸ ÑÑÑанавливаем наÑÑжение по кÑаÑм
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);
}
};
image.src = url;
return texture;
}
function isPowerOf2(value) {
return (value & (value - 1)) == 0;
}
ФÑнкÑÐ¸Ñ loadTexture() наÑинаеÑÑÑ Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð±ÑекÑа WebGL texture вÑзовом ÑÑнкÑии createTexture(). СнаÑала ÑÑнкÑÐ¸Ñ ÑоздаÑÑ ÑекÑÑÑÑÑ Ð¸Ð· единÑÑвенного голÑбого пикÑелÑ, иÑполÑзÑÑ texImage2D(). Таким обÑазом ÑекÑÑÑÑа Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸ÑполÑзована ÑÑÐ°Ð·Ñ (как ÑплоÑной голÑбой ÑвеÑ) пÑи Ñом, ÑÑо загÑÑзка изобÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°Ð½ÑÑÑ Ð½ÐµÐºÐ¾ÑоÑое вÑемÑ.
ЧÑÐ¾Ð±Ñ Ð·Ð°Ð³ÑÑзиÑÑ ÑекÑÑÑÑÑ Ð¸Ð· Ñайла изобÑажениÑ, ÑÑнкÑÐ¸Ñ ÑоздаÑÑ Ð¾Ð±ÑÐµÐºÑ Image и пÑиÑÐ²Ð°Ð¸Ð²Ð°ÐµÑ Ð°ÑÑибÑÑÑ src адÑеÑ, Ñ ÐºÐ¾ÑоÑого Ð¼Ñ Ñ
оÑим загÑÑзиÑÑ ÑекÑÑÑÑÑ. ФÑнкÑиÑ, коÑоÑÑÑ Ð¼Ñ Ð½Ð°Ð·Ð½Ð°Ñили на ÑобÑÑие image.onload,бÑÐ´ÐµÑ Ð²Ñзвана поÑле завеÑÑÐµÐ½Ð¸Ñ Ð·Ð°Ð³ÑÑзки изобÑажениÑ. Ð ÑÑÐ¾Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð¼Ñ Ð²ÑзÑваем texImage2D(), иÑполÑзÑÑ Ð·Ð°Ð³ÑÑженное изобÑажение как иÑÑ
одник Ð´Ð»Ñ ÑекÑÑÑÑÑ. ÐаÑем Ð¼Ñ ÑÑÑанавливаем ÑилÑÑÑаÑÐ¸Ñ Ð¸ наÑÑжение, иÑÑ
Ð¾Ð´Ñ Ð¸Ð· Ñого, ÑвлÑеÑÑÑ Ð»Ð¸ ÑÐ°Ð·Ð¼ÐµÑ Ð¸Ð·Ð¾Ð±ÑÐ°Ð¶ÐµÐ½Ð¸Ñ ÑÑепенÑÑ 2 или неÑ.
Ð WebGL1 изобÑÐ°Ð¶ÐµÐ½Ð¸Ñ ÑазмеÑа, не ÑвлÑÑÑегоÑÑ ÑÑепенÑÑ 2, могÑÑ Ð¸ÑполÑзоваÑÑ ÑолÑко NEAREST или LINEAR ÑилÑÑÑаÑиÑ, и Ð´Ð»Ñ Ð½Ð¸Ñ
нелÑÐ·Ñ ÑоздаÑÑ mipmap. Также Ð´Ð»Ñ ÑакиÑ
изобÑажений Ð¼Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ ÑÑÑановиÑÑ Ð½Ð°ÑÑжение CLAMP_TO_EDGE. С дÑÑгой ÑÑоÑонÑ, еÑли изобÑажение Ð¸Ð¼ÐµÐµÑ ÑÐ°Ð·Ð¼ÐµÑ ÑÑепени 2 по обеим оÑÑм, WebGL Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑоизводиÑÑ Ð±Ð¾Ð»ÐµÐµ каÑеÑÑвеннÑÑ ÑилÑÑÑаÑиÑ, иÑполÑзоваÑÑ mipmap и ÑÐµÐ¶Ð¸Ð¼Ñ Ð½Ð°ÑÑÐ¶ÐµÐ½Ð¸Ñ REPEAT или MIRRORED_REPEAT.
ÐÑимеÑом повÑоÑÑÑÑейÑÑ ÑекÑÑÑÑÑ ÑвлÑеÑÑÑ Ð¸Ð·Ð¾Ð±Ñажение неÑколÑÐºÐ¸Ñ ÐºÐ¸ÑпиÑей, коÑоÑое ÑазмножаеÑÑÑ Ð´Ð»Ñ Ð¿Ð¾ÐºÑÑÑÐ¸Ñ Ð¿Ð¾Ð²ÐµÑÑ Ð½Ð¾ÑÑи и ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¸Ð·Ð¾Ð±ÑÐ°Ð¶ÐµÐ½Ð¸Ñ ÐºÐ¸ÑпиÑной ÑÑенÑ.
Ðипмаппинг и UV-повÑоÑение могÑÑ Ð±ÑÑÑ Ð¾ÑклÑÑÐµÐ½Ñ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ texParameteri(). Так Ð²Ñ ÑможеÑе иÑполÑзоваÑÑ ÑекÑÑÑÑÑ Ñ ÑазмеÑом, не ÑвлÑÑÑимÑÑ ÑÑепенÑÑ 2 (NPOT - non-power-of-two), Ñеной оÑклÑÑÐµÐ½Ð¸Ñ Ð¼Ð¸Ð¿Ð¼Ð°Ð¿Ð¿Ð¸Ð½Ð³Ð°, UV-наÑÑжениÑ, UV-повÑоÑениÑ, и вам ÑÐ°Ð¼Ð¾Ð¼Ñ Ð¿ÑидÑÑÑÑ ÐºÐ¾Ð½ÑÑолиÑоваÑÑ, как именно ÑÑÑÑойÑÑво бÑÐ´ÐµÑ Ð¾Ð±ÑабаÑÑваÑÑ ÑекÑÑÑÑÑ.
// Ñакже ÑазÑеÑено gl.NEAREST вмеÑÑо gl.LINEAR, но не mipmap. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); // Ðе допÑÑкаем повÑоÑÐµÐ½Ð¸Ñ Ð¿Ð¾ s-кооÑдинаÑе. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); // Ðе допÑÑкаем повÑоÑÐµÐ½Ð¸Ñ Ð¿Ð¾ t-кооÑдинаÑе. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
ÐовÑоÑим, ÑÑо Ñ ÑÑими паÑамеÑÑами ÑовмеÑÑимÑе WebGL ÑÑÑÑойÑÑва бÑдÑÑ Ð´Ð¾Ð¿ÑÑкаÑÑ Ð¸ÑполÑзование ÑекÑÑÑÑ Ñ Ð»ÑбÑм ÑазÑеÑением (вплоÑÑ Ð´Ð¾ макÑималÑного). Ðез подобной наÑÑÑойки WebGL поÑеÑÐ¿Ð¸Ñ Ð½ÐµÑдаÑÑ Ð¿Ñи загÑÑзке NPOT-ÑекÑÑÑÑ, и веÑнÑÑ Ð¿ÑозÑаÑнÑй ÑÑÑнÑй ÑÐ²ÐµÑ rgba(0,0,0,0).
ÐÐ»Ñ Ð·Ð°Ð³ÑÑзки изобÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ð¼ вÑзов loadTexture() в ÑÑнкÑÐ¸Ñ main(). Ðод можно ÑазмеÑÑиÑÑ Ð¿Ð¾Ñле вÑзова initBuffers(gl).
// ÐагÑÑзка ÑекÑÑÑÑÑ const texture = loadTexture(gl, 'cubetexture.png');
ÐÑобÑажение ÑекÑÑÑÑÑ Ð½Ð° гÑанÑÑ
СейÑÐ°Ñ ÑекÑÑÑÑа загÑÑжена и гоÑова к иÑполÑзованиÑ. Ðо ÑнаÑала Ð¼Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ ÑÑÑановиÑÑ ÑооÑвеÑÑÑвие Ð¼ÐµÐ¶Ð´Ñ ÐºÐ¾Ð¾ÑдинаÑами ÑекÑÑÑÑÑ Ð¸ гÑанÑми наÑего кÑба. ÐÑжно замениÑÑ Ð²ÐµÑÑ Ð¿ÑедÑдÑÑий код, коÑоÑÑй ÑÑÑанавливал ÑвеÑа гÑаней в initBuffers().
const textureCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordBuffer);
const textureCoordinates = [
// Front
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Back
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Top
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Bottom
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Right
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// Left
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates),
gl.STATIC_DRAW);
...
return {
position: positionBuffer,
textureCoord: textureCoordBuffer,
indices: indexBuffer,
};
СнаÑала Ð¼Ñ ÑоздаÑм WebGL бÑÑеÑ, в коÑоÑом ÑÐ¾Ñ ÑанÑем кооÑдинаÑÑ ÑекÑÑÑÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ гÑани, заÑем ÑвÑзÑваем его Ñ Ð¼Ð°ÑÑивом, в коÑоÑÑй бÑдем запиÑÑваÑÑ Ð·Ð½Ð°ÑениÑ.
ÐаÑÑив textureCoordinates опÑеделÑÐµÑ ÐºÐ¾Ð¾ÑдинаÑÑ ÑекÑÑÑÑÑ, ÑооÑвеÑÑÑвÑÑÑие каждой веÑÑине каждой гÑани. ÐамеÑÑÑе, ÑÑо кооÑдинаÑÑ ÑекÑÑÑÑÑ Ð»ÐµÐ¶Ð°Ñ Ð² пÑомежÑÑке Ð¼ÐµÐ¶Ð´Ñ 0.0 и 1.0. РазмеÑноÑÑÑ ÑекÑÑÑÑÑ Ð½Ð¾ÑмализÑеÑÑÑ Ð² пÑеделаÑ
Ð¼ÐµÐ¶Ð´Ñ 0.0 и 1.0, незавиÑимо Ð¾Ñ ÑеалÑного ÑазмеÑа изобÑажениÑ.
ÐоÑле опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¼Ð°ÑÑива кооÑÐ´Ð¸Ð½Ð°Ñ ÑекÑÑÑÑÑ, Ð¼Ñ ÐºÐ¾Ð¿Ð¸ÑÑем его в бÑÑеÑ, и ÑепеÑÑ WebGL Ð¸Ð¼ÐµÐµÑ Ð´Ð°Ð½Ð½Ñе Ð´Ð»Ñ Ð¾ÑÑиÑовки.
Ðбновление ÑейдеÑов
ÐÑ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¾Ð±Ð½Ð¾Ð²Ð¸ÑÑ ÑейдеÑнÑÑ Ð¿ÑогÑаммÑ, ÑÑÐ¾Ð±Ñ Ð¾Ð½Ð° иÑполÑзовала ÑекÑÑÑÑÑ, а не ÑвеÑа.
ÐеÑÑиннÑй ÑейдеÑ
ÐаменÑем веÑÑиннÑй ÑейдеÑ, ÑÑÐ¾Ð±Ñ Ð¾Ð½ полÑÑал кооÑдинаÑÑ ÑекÑÑÑÑÑ Ð²Ð¼ÐµÑÑо ÑвеÑа.
const vsSource = `
attribute vec4 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
varying highp vec2 vTextureCoord;
void main(void) {
gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
vTextureCoord = aTextureCoord;
}
`;
ÐлÑÑевое изменение в Ñом, ÑÑо вмеÑÑо полÑÑÐµÐ½Ð¸Ñ ÑвеÑа веÑÑинÑ, Ð¼Ñ Ð¿Ð¾Ð»ÑÑаем кооÑдинаÑÑ ÑекÑÑÑÑÑ Ð¸ пеÑедаÑм Ð¸Ñ Ð² веÑÑиннÑй ÑейдеÑ, ÑообÑÐ°Ñ Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ ÑоÑки внÑÑÑи ÑекÑÑÑÑÑ, коÑоÑÐ°Ñ ÑооÑвеÑÑÑвÑÐµÑ Ð²ÐµÑÑине.
ФÑагменÑнÑй ÑейдеÑ
Также нÑжно обновиÑÑ ÑÑагменÑнÑй ÑейдеÑ:
const fsSource = `
varying highp vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void) {
gl_FragColor = texture2D(uSampler, vTextureCoord);
}
`;
ÐмеÑÑо Ð·Ð°Ð´Ð°Ð½Ð¸Ñ ÑвеÑового знаÑÐµÐ½Ð¸Ñ ÑвеÑÑ ÑÑагменÑа, ÑÐ²ÐµÑ ÑÑагменÑа ÑаÑÑÑиÑÑваеÑÑÑ Ð¸Ð· ÑекÑÐµÐ»Ñ (пикÑÐµÐ»Ñ Ð²Ð½ÑÑÑи ÑекÑÑÑÑÑ), оÑновÑваÑÑÑ Ð½Ð° знаÑении vTextureCoord, коÑоÑое инÑеÑполиÑÑеÑÑÑ Ð¼ÐµÐ¶Ð´Ñ Ð²ÐµÑÑинами (как Ñанее инÑеÑполиÑовалоÑÑ Ð·Ð½Ð°Ñение ÑвеÑа).
ÐÑÑибÑÑÑ Ð¸ uniform-пеÑеменнÑе
Так как Ð¼Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ð»Ð¸ аÑÑибÑÑÑ Ð¸ добавили uniform-пеÑеменнÑе, нам нÑжно полÑÑиÑÑ Ð¸Ñ ÑаÑположение
const programInfo = {
program: shaderProgram,
attribLocations: {
vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
textureCoord: gl.getAttribLocation(shaderProgram, 'aTextureCoord'),
},
uniformLocations: {
projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'),
modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'),
uSampler: gl.getUniformLocation(shaderProgram, 'uSampler'),
},
};
РиÑование ÑекÑÑÑÑиÑованного кÑба
Сделаем неÑколÑко пÑоÑÑÑÑ
изменений в ÑÑнкÑии drawScene().
Ðо-пеÑвÑÑ , ÑдалÑем код, коÑоÑÑй опÑеделÑл ÑвеÑовÑе бÑÑеÑÑ, и заменÑем его на:
// УказÑваем WebGL, как извлеÑÑ ÑекÑÑÑÑнÑе кооÑдинаÑÑ Ð¸Ð· бÑÑÑеÑа
{
const num = 2; // ÐºÐ°Ð¶Ð´Ð°Ñ ÐºÐ¾Ð¾ÑдинаÑа ÑоÑÑÐ¾Ð¸Ñ Ð¸Ð· 2 знаÑений
const type = gl.FLOAT; // даннÑе в бÑÑеÑе имеÑÑ Ñип 32 bit float
const normalize = false; // не ноÑмализÑем
const stride = 0; // ÑколÑко Ð±Ð°Ð¹Ñ Ð¼ÐµÐ¶Ð´Ñ Ð¾Ð´Ð½Ð¸Ð¼ набоÑом даннÑÑ
и ÑледÑÑÑим
const offset = 0; // ÑÑаÑÑÐ¾Ð²Ð°Ñ Ð¿Ð¾Ð·Ð¸ÑÐ¸Ñ Ð² байÑаÑ
внÑÑÑи набоÑа даннÑÑ
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.textureCoord);
gl.vertexAttribPointer(programInfo.attribLocations.textureCoord, num, type, normalize, stride, offset);
gl.enableVertexAttribArray(programInfo.attribLocations.textureCoord);
}
ÐаÑем добавлÑем код, коÑоÑÑй оÑобÑÐ°Ð¶Ð°ÐµÑ ÑекÑÑÑÑÑ Ð½Ð° гÑанÑÑ , пÑÑмо пеÑед оÑÑиÑовкой:
// УказÑваем WebGL, ÑÑо Ð¼Ñ Ð¸ÑполÑзÑем ÑекÑÑÑÑнÑй ÑегиÑÑÑ 0 gl.activeTexture(gl.TEXTURE0); // СвÑзÑваем ÑекÑÑÑÑÑ Ñ ÑегиÑÑÑом 0 gl.bindTexture(gl.TEXTURE_2D, texture); // УказÑваем ÑейдеÑÑ, ÑÑо Ð¼Ñ ÑвÑзали ÑекÑÑÑÑÑ Ñ ÑекÑÑÑÑнÑм ÑегиÑÑÑом 0 gl.uniform1i(programInfo.uniformLocations.uSampler, 0);
WebGL Ð¸Ð¼ÐµÐµÑ Ð¼Ð¸Ð½Ð¸Ð¼Ñм 8 ÑекÑÑÑÑнÑÑ
ÑегиÑÑÑов; пеÑвÑй из ниÑ
gl.TEXTURE0. ÐÑ ÑказÑваем, ÑÑо Ñ
оÑим иÑполÑзоваÑÑ ÑегиÑÑÑ 0. ÐаÑем Ð¼Ñ Ð²ÑзÑваем ÑÑнкÑÐ¸Ñ bindTexture(), коÑоÑÐ°Ñ ÑвÑзÑÐ²Ð°ÐµÑ ÑекÑÑÑÑÑ Ñ TEXTURE_2D ÑегиÑÑÑа 0. ÐÐ°ÐºÐ¾Ð½ÐµÑ Ð¼Ñ ÑообÑаем ÑейдеÑÑ, ÑÑо Ð´Ð»Ñ uSampler иÑполÑзÑеÑÑÑ ÑекÑÑÑÑнÑй ÑегиÑÑÑ 0.
РзавеÑÑение, добавлÑем аÑгÑÐ¼ÐµÐ½Ñ texture в ÑÑнкÑÐ¸Ñ drawScene().
drawScene(gl, programInfo, buffers, texture, deltaTime);
...
function drawScene(gl, programInfo, buffers, texture, deltaTime) {
СейÑÐ°Ñ Ð²ÑаÑаÑÑийÑÑ ÐºÑб должен имеÑÑ ÑекÑÑÑÑÑ Ð½Ð° гÑанÑÑ .
ÐоÑмоÑÑеÑÑ ÐºÐ¾Ð´ пÑимеÑа полноÑÑÑÑ | ÐÑкÑÑÑÑ Ð´ÐµÐ¼Ð¾ в новом окне
ÐÑоÑÑ-доменнÑе ÑекÑÑÑÑÑ
ÐагÑÑзка кÑоÑÑ-доменнÑÑ ÑекÑÑÑÑ ÐºÐ¾Ð½ÑÑолиÑÑеÑÑÑ Ð¿Ñавилами кÑоÑÑ-доменного доÑÑÑпа. ЧÑÐ¾Ð±Ñ Ð·Ð°Ð³ÑÑзиÑÑ ÑекÑÑÑÑÑ Ñ Ð´ÑÑгого домена, она должна бÑÑÑ CORS довеÑенной. См. деÑали в ÑÑаÑÑе HTTP access control.
Ð ÑÑаÑÑе на hacks.mozilla.org еÑÑÑ Ð¾Ð±ÑÑÑнение Ñ Ð¿ÑимеÑом, как иÑполÑзоваÑÑ Ð¸Ð·Ð¾Ð±ÑÐ°Ð¶ÐµÐ½Ð¸Ñ CORS Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ WebGL ÑекÑÑÑÑ.
ÐÑимеÑание:
ÐоддеÑжка CORS Ð´Ð»Ñ ÑекÑÑÑÑ WebGL и аÑÑибÑÑ crossOrigin Ð´Ð»Ñ ÑлеменÑов изобÑажений ÑÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ñ Ð² Gecko 8.0.
Tainted (ÑолÑко-длÑ-запиÑи) 2D canvas нелÑÐ·Ñ Ð¸ÑполÑзоваÑÑ Ð² каÑеÑÑве ÑекÑÑÑÑ WebGL. ÐапÑимеÑ, 2D <canvas> ÑÑановиÑÑÑ "tainted", когда на ней оÑÑиÑовано кÑоÑÑ-доменное изобÑажение.
ÐÑимеÑание:
ÐоддеÑжка CORS Ð´Ð»Ñ Canvas 2D drawImage Ñеализована в Gecko 9.0. ÐÑо знаÑиÑ, ÑÑо иÑполÑзование CORS довеÑеннÑÑ
кÑоÑÑ-доменнÑÑ
изобÑажений болÑÑе не Ð´ÐµÐ»Ð°ÐµÑ 2D canvas "tained" (ÑолÑко-длÑ-запиÑи), и Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе иÑполÑзоваÑÑ ÑакÑÑ 2D canvas как иÑÑ
одник Ð´Ð»Ñ ÑекÑÑÑÑ WebGL.
ÐÑимеÑание:
ÐоддеÑжка CORS Ð´Ð»Ñ ÐºÑоÑÑ-доменного видео и аÑÑибÑÑ crossorigin Ð´Ð»Ñ HTML-ÑлеменÑа <video> ÑÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ñ Ð² Gecko 12.0.