| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/es/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL | [Back] [Original] |
Get to know MDN better
Esta pgina ha sido traducida del ingls por la comunidad. Aprende ms y nete a la comunidad de MDN Web Docs.
Ahora que nuestro programa de prueba tiene un cubo, asignemos una textura en lugar de tener sus caras de un color solido.
La primera cosa que debemos hacer es aadir el codigo para cargar nuestra textura. en nuestro caso, estaremos usando una unica textura, asignada en las seis caras de nuestro cubo rotador, pero la misma tecnica puede ser utilizada para cualquier cantidad de texturas.
Nota: Es importante sealar que la carga de texturas sigue reglas de dominio-cruzado; Es decir, slo puede cargar texturas de sitios para los que su contenido tiene aprobacin de CORS. Vea las texturas entre dominios a continuacin para ms detalles.
El codigo que carga la textura se ve como esto:
function initTextures() {
cubeTexture = gl.createTexture();
cubeImage = new Image();
cubeImage.onload = function () {
handleTextureLoaded(cubeImage, cubeTexture);
};
cubeImage.src = "cubetexture.png";
}
function handleTextureLoaded(image, texture) {
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(
gl.TEXTURE_2D,
gl.TEXTURE_MIN_FILTER,
gl.LINEAR_MIPMAP_NEAREST,
);
gl.generateMipmap(gl.TEXTURE_2D);
gl.bindTexture(gl.TEXTURE_2D, null);
}
La rutina initTextures() comienza por crear el GL texture cubeTexture llamando la rutina GL createTexture(). Para cargar la textura desde un archivo de imagen, este luego crea un Objeto Imagen y carga en l el archivo de imagen que deseamos utilizar como nuestra textura. La rutina handleTextureLoaded() corre cuando la textura ha terminado de cargar.
Para realmente crear la textura, especificamos que la nueva textura es la textura actual en la que queremos operar vinculndola a gl.TEXTURE_2D. Despues de esto, la imagen cargada es pasada a texImage2D() para escribir la informacion de la imagen en la textura.
Nota: El alto y hancho de las texturas deben, en la mayora de las circunstancias, ser una potencia de dos pxeles (es decir, 1, 2, 4, 8, 16, etc.) en cada dimensin. Para la excepcin, vea la seccin: "Texturas no potencia de dos", a continuacin.
Las siguientes dos lneas setean el filtrado para la textura; Esto controla cmo se filtra la imagen mientras se escala. En este caso estamos usando linear filtering cuando escala la imagen, y mipmap cuando se hace mas pequea. Entonces el mipmap es generado llamando generateMipMap(), Y terminamos dicindole a WebGL que hemos terminado de manipular la textura vinculando null a gl.TEXTURE_2D.
Generalmente hablando, Utilizar texturas cuyos lados son una potencia de dos es ideal. Estn almacenadas eficientemente en la memoria de video y no estn restringidas en cmo podran ser utilizadas. Las texturas creadas por el artista deben ser escaladas hacia arriba o hacia abajo a una potencia cercana a dos y, realmente, debera haber sido creada en potencia-de-dos para empezar. Cada lado debe ser: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 2048 pxeles. Muchos dispositivos, pero no todos, pueden soportar 4096 pxeles; Algunos pueden soportar 8192 e incluso ms.
Ocasionalmente, es difcil utilizar texturas en potencia-de-dos dada una circunstancia especifica. Si la fuente es alguna tercera parte, A menudo los mejores resultados vienen de modificar las imgenes usando canvas HTML5 en tamaos de potencia-de-dos antes de que se pasen a WebGL; Las coordenadas UV tambin pueden requerir ajuste si el estiramiento es notorio.
Pero, Si tiene que tener una textura no-potencia-de-dos (NPOT = no-power-of-two), WebGL incluye un limitado soporte nativo. Las texturas NPOT son en su mayora tiles si las dimensiones de la textura debe ser la misma resolucin que otra cosa, como la resolucin de tu monitor, o si no vale la pena molestarse por las sugerencias anteriores. Resumiendo: estas texturas no se pueden usar con mipmapping y no deben repetirse (tile o wrap).
Un ejemplo de una textura es tilear una imagen de unos ladrillos para cubrir una pared de ladrillos.
Mipmapping y "UV tiling" pueden ser desactivados utilizando texParameteri() y cuando creas tu textura utilizando bindTexture(). sto permitir las texturas NPOT a expensas de mipmapping, UV wrapping, UV tiling, y tu control sobre cmo el dispositivo proceder a manejar tu textura.
// gl.NEAREST is also allowed, instead of gl.LINEAR, as neither mipmap.
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
// Prevents s-coordinate wrapping (repeating).
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
// Prevents t-coordinate wrapping (repeating).
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
Una vez ms, con estos parmetros, los dispositivos compatibles con WebGL aceptarn automticamente cualquier resolucin para esa textura (hasta sus dimensiones mximas). Sin realizar la configuracin anterior, WebGL requiere que todas las muestras de texturas NPOT fallen al devolver el color "negro slido": rgba (0,0,0,1).
A este punto, la textura esta cargada y lista para usar. pero antes de utilizarla, Necesitamos asignar el mapeo de las coordenadas de textura a los vrtices de las caras de nuestro cubo. Esto reemplaza todo el cdigo previamente existente para configurar colores para cada una de las caras del cubo en initBuffers().
cubeVerticesTextureCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesTextureCoordBuffer);
var 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,
);
Primeramente, este codigo crea un GL buffer en el cual almacenaremos las coordenadas de la textura para cada cara, luego enlazamos ese buffer como el array en el cual escribiremos.
El array textureCoordinates define las coordenadas de textura correspondientes a cada vrtice de cada cara. Tenga en cuenta que las coordenadas de textura van de 0,0 a 1,0; Las dimensiones de las texturas se normalizan a un rango de 0,0 a 1,0 independientemente de su tamao real, con el propsito de mapeo de textura.
Una vez que hemos seteado la matriz de mapeo de textura, pasamos la matriz al bfer, de modo que GL tiene esos datos listos para su uso.
El shader y el cdigo que inicializa los shaders tambin necesita ser actualizado para utilizar la textura en vez de un color solido.
Primero, echemos un vistazo a un cambio muy sencillo que se necesita en initShaders():
textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
gl.enableVertexAttribArray(textureCoordAttribute);
gl.vertexAttribPointer(texCoordAttribute, 2, gl.FLOAT, false, 0, 0);
Esto reemplaza el cdigo que setea el atributo "vertex color" (color del vertice) con uno que contiene la coordenada de textura para cada vrtice.
A continuacin, necesitamos reemplazar el "vertex shader" de modo que en lugar de buscar datos de color, busque los datos de coordenadas de textura.
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying highp vec2 vTextureCoord;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoord = aTextureCoord;
}
</script>
El cambio clave aqu es que en lugar de buscar el color del vrtice (vertex color), estamos estableciendo las coordenadas de textura; Esto indicar la ubicacin dentro de la textura correspondiente al vrtice.
El fragment shader tambin debe actualizarse:
<script id="shader-fs" type="x-shader/x-fragment">
varying highp vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void) {
gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
}
</script>
En lugar de asignar un valor de color al fragment color, el fragment color se calcula recolectando el texel (es decir, el pxel dentro de la textura) que el muestreador dice que se corresponde mejor con la posicin del fragment.
El cambio a la funcin drawScene() es simple (excepto que por razones de claridad, he eliminado el cdigo que hace que el cubo se traslade a travs del espacio mientras se anima, en vez de eso, solo gira).
El cdigo para mapear colores a la textura se ha ido, sustituido por esto:
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, cubeTexture);
gl.uniform1i(gl.getUniformLocation(shaderProgram, "uSampler"), 0);
GL proporciona 32 registros de textura; La primera de ellas es gl.TEXTURE0. Vincularemos nuestra textura previamente cargada a ese registro, a continuacin, establecremos el shader sampler uSampler (especificado en el shader) para utilizar esa textura.
En este punto, el cubo giratorio debe estar listo.
Ver el cdigo completo | Abrir esta demo en una nueva pestaa
La carga de texturas WebGL esta sujeta a controles de acceso entre dominios. Para que su contenido cargue una textura de otro dominio, La aprobacion CORS debe ser obtenida. Ver control de acceso HTTP para mas detalles sobre CORS.
Ver este articulo hacks.mozilla.org para una explicacion de como usar imgenes CORS-approved como texturas WebGL , con un ejemplo auto-contenido.
Nota: El soporte CORS para texturas WebGL y el atributo crossOrigin para elementos de imagen se implementan en Gecko 8.0.
Canvas 2D contaminados (Solo lectura) no pueden ser utilizados como texturas WebGL. una 2D <canvas> se convierte en contaminada, por ejemplo, cuando una imagen de dominio cruzado (cross-domain) es dibujada en el.
Nota: El soporte de CORS para Canvas 2D drawImage se implementa en Gecko 9.0. Esto significa que el uso de una imagen de dominio cruzado con aprobacin de CORS ya no pinta el lienzo 2D, por lo que el lienzo 2D sigue siendo utilizable como fuente de una textura WebGL.
Nota:
El soporte de CORS para videos de dominio cruzado y el atributo de crossorigin para elementos <video> se implementa en Gecko 12.0.
This page was last modified on 27 mar 2025 by MDN contributors.
WebGLRenderingContextWebGLBufferWebGLFramebufferWebGLRenderbufferWebGLObjectWebGLProgramWebGLShaderWebGLTextureWebGLUniformLocationWebGLActiveInfoWebGLShaderPrecisionFormatWebGLContextEventWebGLQueryWebGLSamplerWebGLSyncWebGLTransformFeedbackWebGLVertexArrayObjectWebGL2RenderingContextWEBGL_compressed_texture_s3tcWEBGL_compressed_texture_s3tc_srgbWEBGL_compressed_texture_etc1WEBGL_compressed_texture_pvrtcWEBGL_debug_renderer_infoWEBGL_debug_shadersWEBGL_depth_textureOES_element_index_uintEXT_frag_depthWEBGL_lose_contextEXT_texture_filter_anisotropicEXT_sRGBOES_standard_derivativesOES_texture_floatWEBGL_draw_buffersOES_texture_float_linearEXT_shader_texture_lodOES_texture_half_floatOES_texture_half_float_linearWEBGL_color_buffer_floatEXT_color_buffer_half_floatOES_vertex_array_objectANGLE_instanced_arraysEXT_blend_minmaxEXT_disjoint_timer_queryOES_draw_buffers_indexedYour blueprint for a better internet.
Portions of this content are 19982026 by individual mozilla.org contributors. Content available under a Creative Commons license.
| Web Proxy Viewer | New URL | Original Page |