Textura WebGL: pegar una imagen en una superficie rectangular

Tabla de contenido

Para realizar un mapeo de texturas en WebGL, debe seguir los siguientes cuatro pasos: 

1. Prepare imágenes de texturas asignadas a la geometría.

2. Configure el método de mapeo de textura para la geometría.

3. Cargue la imagen de textura y configúrela un poco para usarla en WebGL.

4. Extraiga el texel correspondiente de la textura en el sombreador de fragmentos y asigne el color del texel al fragmento.

Coordenadas de textura

Pegar imagen de textura en geometría

Código de muestra

Este programa se divide principalmente en cinco partes.

1. El sombreador de vértices recibe las coordenadas de textura del vértice, las rasteriza y las pasa al sombreador de fragmentos.

2. El sombreador de fragmentos extrae el color del texel de la imagen de textura en función de las coordenadas de textura del fragmento y lo asigna al fragmento actual.

3. Establezca las coordenadas de textura de los vértices (initVertexBuffers()).

4. Prepare la imagen de textura que se cargará y deje que el navegador la lea (initTextures()).

5. Escuche el evento de carga de la imagen de textura y, una vez que se complete la carga, use la textura (loadTexture ()) en el sistema WebGL.

Establecer coordenadas de textura (initVertexBuffers())

Configurar y cargar texturas (initTextures()) 

 Especificación del método gl.createTexture().

Especificación del método gl.deleteTexture()

Cargar imágenes de textura de forma asincrónica

Configurar texturas para WebGL (loadTexture()) 

Inversión del eje Y de la imagen

Especificación del método gl.pixelStorei()

 Activar unidad de textura (gl.activeTexture())

 Especificación del método gl.activeTexture()

Vincular objeto de textura (gl.bindTexture()) 

 Especificación del método gl.bindTexture()

Configurar los parámetros del objeto de textura (gl.texParameteri())

Especificación del método gl.texParameteri()

pname puede especificar 4 parámetros de textura. 

Parámetros de textura y sus valores predeterminados.

Constantes de tipo de textura no piramidal que se pueden asignar a gl.TEXTURE_MAG_FILTER y gl.TEXTURE_MIN_FILTER.

Constantes que se pueden asignar a gl.TEXTURE_WRAP_S y gl.TEXTURE_WRAP_T

Asignar imagen de textura al objeto de textura (gl.texImage2D())

Especificación del método gl.texImage2D()

Formato de datos de texto.

Pasar la unidad de textura al sombreador de fragmentos (gl.uniform1i()) 

Tipo de datos específico de texturas.

Transfiera coordenadas de textura del sombreador de vértices al sombreador de fragmentos 

Obtener el color del píxel de textura en el sombreador de fragmentos (texture2D()) 

especificación del método textura2D()

Valor de retorno del método textura2D()

Ejercicio: Modifique las coordenadas de textura para cambiar los efectos de mapeo de texturas


El problema surge si quieres crear una pared de ladrillos realista como la que se muestra a continuación. Quizás te sientas tentado a crear muchos triángulos, especificando sus colores y posiciones para simular baches en la pared. Si haces esto, quedarás atrapado en un mar de sufrimiento tedioso y sin sentido.

Quizás ya sepas que en los gráficos tridimensionales existe una tecnología muy importante que puede solucionar este problema, y ​​es el mapeo de texturas . El mapeo de texturas es en realidad muy simple: consiste en mapear (pegar) una imagen (como una pegatina) en la superficie de una figura geométrica. Pegue una imagen del mundo real en un rectángulo formado por dos triángulos para que la superficie del rectángulo se parezca a la imagen. En este momento, esta imagen también se puede llamar imagen de textura o textura . ,

La función del mapeo de texturas es pintar cada fragmento previamente rasterizado con el color apropiado en función de la imagen de la textura. Los píxeles que componen una imagen de textura también se denominan texels (elementos de textura) y el color de cada texel está codificado en formato RGB o RGBA, como se muestra en la siguiente figura.

Para realizar un mapeo de texturas en WebGL, debe seguir los siguientes cuatro pasos: 

1. Prepare imágenes de texturas asignadas a la geometría.

2. Configure el método de mapeo de textura para la geometría.

3. Cargue la imagen de textura y configúrela un poco para usarla en WebGL.

4. Extraiga el texel correspondiente de la textura en el sombreador de fragmentos y asigne el color del texel al fragmento.

Para comprender mejor la mecánica del mapeo de texturas, escribamos un programa de muestra que adjunte una imagen de textura a una superficie rectangular. Ejecute el código en el navegador y el resultado se muestra a continuación. 

 

A continuación, echemos un vistazo más de cerca a los pasos 1 a 4 anteriores. La imagen de textura preparada en el paso 1 puede ser una imagen en cualquier formato admitido por el navegador. puedes usar cualquier foto

El segundo paso es especificar el método de mapeo, que consiste en determinar cómo el color de "un determinado fragmento de la geometría" depende de "qué (o varios) píxeles en la imagen de textura" (es decir, el mapeo del primero a este último). Usamos las coordenadas de vértice de la forma para determinar qué parte de la pantalla está cubierta por la imagen de textura, y las coordenadas de textura (coordenadas de textura) para determinar qué parte de la imagen de textura cubrirá la geometría. Las coordenadas de textura son un nuevo sistema de coordenadas. Echemos un vistazo más de cerca.

Coordenadas de textura

Las coordenadas de textura son coordenadas en la imagen de textura, a través de las cuales se puede obtener el color del texel en la imagen de textura. El sistema de coordenadas de textura en el sistema WebGL es bidimensional, como se muestra en la siguiente figura. Para distinguir las coordenadas de textura de las coordenadas x e y ampliamente utilizadas, WebGL nombra las coordenadas de textura usando s y t (sistemas de coordenadas st/uv)

Como se muestra en la figura anterior, las coordenadas de las cuatro esquinas de la imagen de textura son la esquina inferior izquierda (0.0, 0.0), la esquina inferior derecha (1.0, 0.0), la esquina superior derecha (1.0, 1.0) y la esquina superior. esquina izquierda (0.0, 1.0). Las coordenadas de textura son muy comunes porque los valores de las coordenadas no tienen nada que ver con el tamaño de la imagen en sí, ya sea una imagen de 128 × 128 o 128 × 256, las coordenadas de textura de la esquina superior derecha siempre son (1.0, 1.0 ).

Pegar imagen de textura en geometría

Como se mencionó anteriormente, en WebGL, determinamos cómo pegar la imagen de textura a través de la relación de mapeo entre las coordenadas de textura de la imagen de textura y las coordenadas de vértice de la forma geométrica, como se muestra en la siguiente figura.

Aquí asignamos coordenadas de textura (0.0, 1.0) a coordenadas de vértice (-0.5, -0.5, 0.0), coordenadas de textura (1.0, 1.0) a coordenadas de vértice (0.5, 0.5, 0.0), etc. Al establecer la relación correspondiente entre los cuatro vértices del rectángulo y las coordenadas de textura, se obtiene el resultado que se muestra en la figura de arriba (derecha). 

Ahora que debería tener una comprensión general de los principios del mapeo de texturas, echemos un vistazo a un programa de muestra.

Código de muestra

A continuación se muestra un programa de muestra. El proceso de mapeo de texturas requiere la cooperación tanto del sombreador de vértices como del sombreador de fragmentos: primero, las coordenadas de textura se especifican para cada vértice en el sombreador de vértices, y luego, en el sombreador de fragmentos, las coordenadas de textura de cada fragmento se obtienen del imagen de textura Extraiga el color texel de . El programa consta principalmente de cinco partes, que han sido marcadas en el código.

// 顶点着色器 (第一部分) p157
var VSHADER_SOURCE =
  'attribute vec4 a_Position;\n' +
  'attribute vec2 a_TexCoord;\n' +
  'varying vec2 v_TexCoord;\n' +
  'void main() {\n' +
  '  gl_Position = a_Position;\n' +
  '  v_TexCoord = a_TexCoord;\n' +
  '}\n';

// 片元着色器 (第二部分)
var FSHADER_SOURCE =
  '#ifdef GL_ES\n' +
  'precision mediump float;\n' +
  '#endif\n' +
  'uniform sampler2D u_Sampler;\n' +
  'varying vec2 v_TexCoord;\n' +
  'void main() {\n' +
  '  gl_FragColor = texture2D(u_Sampler, v_TexCoord);\n' +
  '}\n';

function main() {
  var canvas = document.getElementById('webgl');
  var gl = getWebGLContext(canvas);
  if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log('Failed to intialize shaders.');
    return;
  }
  // 设置顶点信息 (第三部分)
  var n = initVertexBuffers(gl);
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  // 配置纹理
  if (!initTextures(gl, n)) {
    console.log('Failed to intialize the texture.');
    return;
  }
}

function initVertexBuffers(gl) {
  var verticesTexCoords = new Float32Array([
    // 顶点坐标, 纹理坐标
    -0.5,  0.5,   0.0, 1.0,
    -0.5, -0.5,   0.0, 0.0,
     0.5,  0.5,   1.0, 1.0,
     0.5, -0.5,   1.0, 0.0,
  ]);
  var n = 4; // 顶点数
  // 创建缓冲区对象
  var vertexTexCoordBuffer = gl.createBuffer();
  // 将顶点坐标和纹理坐标写入缓冲区对象
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexTexCoordBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, verticesTexCoords, gl.STATIC_DRAW);
  var FSIZE = verticesTexCoords.BYTES_PER_ELEMENT;
  var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 4, 0);
  gl.enableVertexAttribArray(a_Position);  // 启用缓冲区对象的分配a_Position
  // 将纹理坐标分配给a_TexCoord并开启它
  var a_TexCoord = gl.getAttribLocation(gl.program, 'a_TexCoord');
  gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, FSIZE * 4, FSIZE * 2);
  gl.enableVertexAttribArray(a_TexCoord);  // 启用缓冲区对象的分配a_TexCoord
  return n;
}

// 第四部分
function initTextures(gl, n) {
  var texture = gl.createTexture();   // 创建纹理对象
  // 获取 u_Sampler 的存储位置
  var u_Sampler = gl.getUniformLocation(gl.program, 'u_Sampler');
  var image = new Image(); 
  // 注册图像加载事件的响应函数
  image.onload = function(){ loadTexture(gl, n, texture, u_Sampler, image); };
  // 浏览器开始加载图像
  image.src = '../resources/sky.jpg';
  return true;
}

// 第五部分
function loadTexture(gl, n, texture, u_Sampler, image) {
  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); // 对纹理图像进行y轴反转
  // 开启0号纹理单元
  gl.activeTexture(gl.TEXTURE0);
  /* 
    向target绑定纹理对象:通过 gl.activeTexture 方法激活了纹理单元0。然后,纹理对象 texture 使用 gl.bindTexture 方法将其绑定到当前激活的纹理单元上 gl.TEXTURE0。
    在 WebGL 中,首先需要激活一个纹理单元并将纹理对象绑定到该纹理单元上,然后才能指定纹理目标的类型。
  */
  gl.bindTexture(gl.TEXTURE_2D, texture);
  // 配置纹理参数
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  // 配置纹理对象
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
  // 将0号纹理传递给着色器
  gl.uniform1i(u_Sampler, 0);
  
  gl.clear(gl.COLOR_BUFFER_BIT);   // 清楚canvas
  gl.drawArrays(gl.TRIANGLE_STRIP, 0, n); // 绘制矩形
}

Este programa se divide principalmente en cinco partes.

1. El sombreador de vértices recibe las coordenadas de textura del vértice, las rasteriza y las pasa al sombreador de fragmentos.

2. El sombreador de fragmentos extrae el color del texel de la imagen de textura en función de las coordenadas de textura del fragmento y lo asigna al fragmento actual.

3. Establezca las coordenadas de textura de los vértices (initVertexBuffers()).

4. Prepare la imagen de textura que se cargará y deje que el navegador la lea (initTextures()).

5. Escuche el evento de carga de la imagen de textura y, una vez que se complete la carga, use la textura (loadTexture ()) en el sistema WebGL.

 Comencemos con la parte 3 (estableciendo coordenadas de textura para cada vértice usando initVertexBuffers()). Los sombreadores (las dos primeras partes) se ejecutarán después de que se haya cargado la imagen, por lo que se explican al final.

Establecer coordenadas de textura (initVertexBuffers())

Pasar coordenadas de textura al sombreador de vértices es lo mismo que pasar otros datos de vértice (como el color) al sombreador de vértices. Podemos escribir coordenadas de textura y coordenadas de vértice en el mismo búfer: defina la matriz verticesTexCoords para registrar las coordenadas de vértice y las coordenadas de textura de cada vértice en pares (línea 40), de la siguiente manera:

Se puede observar que las coordenadas de textura correspondientes al primer vértice (-0.5, 0.5) son (0.0, 1.0), las coordenadas de textura correspondientes al segundo vértice (-0.5, -0.5) son (0.0, 0.0) y las coordenadas de textura correspondientes al tercer vértice (Las coordenadas de textura correspondientes a 0.5, 0.5) son (1.0, 1.0), y las coordenadas de textura correspondientes al cuarto vértice (0.5, -0.5) son (1.0, 0.0).
Luego escribimos las coordenadas de vértice y las coordenadas de textura en el objeto de búfer, asignamos las coordenadas de vértice a la variable a_Position y la activamos (líneas 51 a 56). A continuación, obtenga la ubicación de almacenamiento de la variable a_TexCoord, asigne las coordenadas de textura en el búfer a la variable (líneas 58 a 59) y ábrala (línea 60).

Configurar y cargar texturas (initTextures()) 

La función initTextures() es responsable de configurar y cargar texturas (líneas 66 a 73): primero llame a gl.createTexture() para crear un objeto de textura (línea 63), que se utiliza para administrar texturas en el sistema WebGL. Luego llame a gl.getUniformLocation() para obtener la ubicación de almacenamiento de la variable uniforme u_Sampler (muestra) del sombreador de fragmentos, que se utiliza para recibir la imagen de textura (línea 68).

 Especificación del método gl.createTexture().

 Llamar a esta función creará un objeto de textura en el sistema WebGL, como se muestra en la siguiente figura. gl.TEXTURE0 a gl.TEXTURE7 son 8 unidades de textura que administran imágenes de textura (se explicarán en detalle más adelante), cada una de las cuales está asociada con gl.TEXTURE_2D, que es el objetivo de la textura al vincular la textura. Estos se explicarán en detalle más adelante.

Asimismo, puedes usar gl.deleteTexture() para eliminar un objeto de textura. Tenga en cuenta que si intenta eliminar un objeto de textura que ya se ha eliminado, no se informará ningún error y no habrá ningún impacto.

Especificación del método gl.deleteTexture()

 

A continuación, se solicita al navegador que cargue una imagen de textura para que la utilice WebGL, que se asignará al rectángulo. Para hacer esto necesitamos usar un objeto Imagen:

 

Este código crea un objeto Imagen y luego registra la función de respuesta al evento de carga loadTexture() para él. Esta función se llamará después de cargar la imagen. Finalmente, se notifica al navegador para que comience a cargar la imagen.

Debe usar el nuevo operador para crear un nuevo objeto Imagen, tal como cuando crea un nuevo objeto Array o un objeto Fecha (línea 114). La imagen es un tipo de objeto integrado en JavaScript, que generalmente se usa para procesar imágenes.

 

Dado que el proceso de carga de imágenes es asincrónico (se analiza en detalle más adelante), debemos escuchar el evento de finalización de la carga (evento onload): una vez que el navegador completa la carga de la imagen, la imagen cargada se entrega al sistema WebGL. Registrar la función de respuesta al evento de carga equivale a decirle al navegador que llame de forma asincrónica a la función loadTexture() (línea 71) después de completar la carga de la imagen de textura. 

 

La función loadTexture() recibe 5 parámetros, el último parámetro es la imagen recién cargada (es decir, el objeto Imagen). El primer parámetro gl es el contexto de dibujo WebGL, el parámetro n es el número de vértices, el parámetro textura es el objeto de textura creado previamente (línea 66) y u_Sampler es la ubicación de almacenamiento de la variable uniforme u_Sampler en el sombreador. 

Al igual que la etiqueta <img> en HTML, agregamos el atributo src al objeto Imagen y asignamos el atributo a la ruta y el nombre del archivo de imagen para indicarle al navegador que comience a cargar la imagen (línea 73). Tenga en cuenta que, por razones de seguridad, WebGL no permite el uso de imágenes de textura entre dominios:

Después de ejecutar la línea 73, el navegador comienza a cargar la imagen de forma asincrónica, mientras que el programa en sí (sin esperar a que la imagen termine de cargarse) continúa con la declaración de devolución en la línea 74 y sale. Luego, cuando el navegador complete la carga de la imagen en un momento determinado, llamará a la función de respuesta al evento loadTexture() para entregar la imagen cargada al sistema WebGL para su procesamiento.

Cargar imágenes de textura de forma asincrónica

WebGL se ejecuta en el navegador, no podemos leer la imagen directamente desde el disco, solo podemos obtener la imagen indirectamente a través del navegador. (Generalmente, el navegador inicia una solicitud al servidor, recibe la respuesta del servidor y obtiene la imagen de él). La ventaja de esto es que podemos usar imágenes en cualquier formato admitido por el navegador, pero la desventaja es que obtener el image El proceso se ha vuelto más complicado. Para obtener la imagen, debemos realizar dos pasos (solicitud del navegador y cargar la imagen en el sistema WebGL), y estos dos pasos se ejecutan de forma asincrónica (en segundo plano) y no bloquearán la ejecución actual del programa.

La siguiente figura muestra el proceso desde el paso [1] (notificar al navegador que cargue la imagen) hasta el paso [7] (llamar a loadTexture() después de cargar la imagen) en el programa de muestra.

En la figura anterior, los pasos [1] y [2] se ejecutan en orden, pero los pasos [2] a [7] no. En el paso [2], después de que solicitamos al navegador que cargara una imagen, el programa JavaScript no se detuvo y esperó a que se cargara la imagen, sino que continuó ejecutándose hacia adelante. (El mecanismo de este comportamiento se explicará en detalle más adelante). Mientras JavaScript continúa ejecutándose, el navegador solicita al servidor web que cargue una imagen [3]. Luego, cuando el navegador complete la carga de la imagen [4] y [5], notificará al programa JavaScript que la imagen se ha cargado. Este proceso se llama asincrónico. El proceso de carga asincrónica de la imagen de arriba es muy similar al proceso de visualización de imágenes en páginas web HTML. En una página web HTML, le indica al navegador desde qué URL especificada cargar la imagen especificando la URL del archivo de imagen para el atributo src de la etiqueta <img> (como se muestra a continuación). Este proceso es en realidad el paso [2] en la Figura 5.23.

Basta pensar en el rendimiento de las páginas web llenas de imágenes: cargar imágenes mediante el navegador es inherentemente un proceso asincrónico. En términos generales, el diseño y el texto de esas páginas web se muestran rápidamente y luego las imágenes se muestran gradualmente a medida que se cargan. Precisamente porque el proceso de carga y visualización de imágenes es asincrónico, podemos ver e interactuar con el texto de la página web tan pronto como abrimos la página web sin tener que esperar a que se carguen todas las imágenes.

Configurar texturas para WebGL (loadTexture()) 

La función loadTexture() se define de la siguiente manera:

La tarea principal de esta función es configurar la textura para su uso por WebGL. Usar objetos de textura es muy similar a usar buffers, así que echemos un vistazo. 

Inversión del eje Y de la imagen

Antes de usar la imagen, debes invertirla en Y.

Este método realiza una inversión del eje Y de la imagen. Como se muestra en la figura siguiente, la dirección del eje t en el sistema de coordenadas de textura WebGL es opuesta a la dirección del eje Y en el sistema de coordenadas de imágenes en PNG, BMP, JPG y otros formatos. Por lo tanto, solo invirtiendo el eje Y de la imagen se puede asignar correctamente la imagen al gráfico. (Como alternativa, puede invertir manualmente las coordenadas del eje T en el sombreador). 

Especificación del método gl.pixelStorei()

 Activar unidad de textura (gl.activeTexture())

WebGL utiliza múltiples texturas simultáneamente a través de un mecanismo llamado unidad de textura. Cada unidad de textura tiene un número de unidad que gestiona una imagen de textura. Incluso si su programa solo necesita usar una imagen de textura, debe especificar una unidad de textura para ella.

La cantidad de unidades de textura admitidas por el sistema depende del hardware y de la implementación de WebGL del navegador, pero de forma predeterminada, WebGL admite al menos 8 unidades de textura y algunos otros sistemas admiten más. Las variables integradas gl.TEXTRUE0, gl.TEXTURE1...gl.TEXTURE7 representan cada una una unidad de textura.

Antes de usar la unidad de textura, también necesita llamar a gl.activeTexture() para activarla, como se muestra en la siguiente figura. 

 Especificación del método gl.activeTexture()

 

Vincular objeto de textura (gl.bindTexture()) 

A continuación, debe indicarle al sistema WebGL qué tipo de textura está utilizando el objeto de textura. Antes de operar en el objeto de textura, debemos vincular el objeto de textura, que es muy parecido a un búfer: antes de operar en el objeto de búfer (como escribir datos), también debemos vincular el objeto de búfer. WebGL admite dos tipos de texturas, como se muestra a continuación.

El programa de ejemplo utiliza una imagen bidimensional como textura, por lo que se pasa gl.TEXTURE_2D (línea 86).

Vincular objetos de textura a unidades de textura y objetivos de textura

 Especificación del método gl.bindTexture()

 

Tenga en cuenta que este método completa dos tareas: abrir el objeto de textura y vincular el objeto de textura a la unidad de textura. (Primero debe vincular el objeto de textura a la unidad de textura y luego puede especificar el tipo de destino de textura y vincularlo). En este ejemplo, debido a que la unidad de textura 0 (gl.TEXTURE0) se ha activado, después de ejecutar la línea 86 Luego , el estado interno del sistema WebGL es como se muestra en la siguiente figura. 

De esta forma especificamos el tipo de objeto de textura (gl.TEXTURE_2D). De hecho, en WebGL, no puede operar objetos de textura directamente, debe vincular el objeto de textura a la unidad de textura y luego operar el objeto de textura operando la unidad de textura. 

Configurar los parámetros del objeto de textura (gl.texParameteri())

A continuación, debe configurar los parámetros del objeto de textura para establecer la forma específica en que la imagen de textura se asigna a los gráficos: cómo obtener el color del texel en función de las coordenadas de la textura y cómo rellenar la textura repetidamente . Usamos la función general gl.texParameteri() para establecer estos parámetros.

Especificación del método gl.texParameteri()

pname puede especificar 4 parámetros de textura. 
  • Método de amplificación (gl.TEXTURE_MAG_FILTER) : este parámetro indica cómo obtener el color del texel cuando el rango de dibujo de la textura es mayor que la textura misma. Por ejemplo, cuando asigna una imagen de textura de 16 × 16 a un espacio de 32 × 32 píxeles, el tamaño de la textura se convierte en el doble del tamaño original. WebGL necesita llenar los espacios entre píxeles causados ​​por la ampliación, y este parámetro indica el método específico para llenar estos espacios.

  • Método de minificación (gl.TEXTURE_MIN_FILTER) : este parámetro indica cómo obtener el color del texel cuando el rango de dibujo de la textura es más pequeño que la textura misma. Por ejemplo, si asigna una imagen de textura de 32 × 32 a un espacio de 16 × 16 píxeles, la textura tendrá la mitad del tamaño original. Para reducir la textura, WebGL necesita eliminar algunos píxeles en la imagen de textura. Este parámetro indica el método específico para eliminar píxeles.
  • Método de relleno horizontal (gl.TEXTURE_WRAP_S) : este parámetro indica cómo rellenar el área en el lado izquierdo o derecho de la imagen de textura.
  • Método de relleno vertical (gl.TEXTURE_WRAP_T) : este parámetro indica cómo rellenar el área encima y debajo de la imagen de textura.

La Tabla 5.3 a continuación muestra los valores predeterminados para cada parámetro de textura.

Parámetros de textura y sus valores predeterminados.


La Tabla 5.4 a continuación muestra las constantes que se pueden asignar a gl.TEXTURE_MAG_FILTER y gl.TEXTURE_MIN_FILTER;

Constantes de tipo de textura no piramidal que se pueden asignar a gl.TEXTURE_MAG_FILTER y gl.TEXTURE_MIN_FILTER.

 

La distancia de Manhattan es una distancia rectangular, una distancia de tablero de ajedrez. Por ejemplo, la distancia de Manhattan entre (x1, y1) y (x2, y2) es |x1-x2|+|y1-y2|

La Tabla 5.5 a continuación muestra las constantes que se pueden asignar a gl.TEXTURE_WRAP_S y gl.TEXTURE_WRAP_T.

Constantes que se pueden asignar a gl.TEXTURE_WRAP_S y gl.TEXTURE_WRAP_T

Como se muestra en la Tabla 5.3 , cada parámetro de textura tiene un valor predeterminado y, por lo general, puede usar el valor predeterminado sin llamar a gl.texParameteri(). Sin embargo, este ejemplo modifica el parámetro gl.TEXTURE_MIN_FILTER, cuyo valor predeterminado es un tipo de textura especial llamado MIPMAP (también conocido como pirámide). Una textura MIPMAP es en realidad una serie de texturas o una serie de versiones de diferente resolución de la imagen de textura original. En resumen, configuramos el parámetro gl.TEXTURE_MIN_FILTER en gl.LINEAR (línea 88). 

Una vez configurados los parámetros del objeto de textura, el estado interno del sistema WebGL se muestra en la siguiente figura.

 A continuación, asignamos la imagen de textura al objeto de textura.

Asignar imagen de textura al objeto de textura (gl.texImage2D())

Asignamos la imagen de textura al objeto de textura usando el método gl.texImage2D(), que también le permite decirle al sistema WebGL algunas propiedades sobre la imagen.

Especificación del método gl.texImage2D()

Llamamos a este método en la línea 90 del programa de muestra. 

En este momento, la imagen del objeto Imagen se pasa al sistema WebGL desde JavaScript y se almacena en el objeto de textura, como se muestra en la siguiente figura.

Asignar imagen al objeto de textura

 

 Eche un vistazo rápido a los valores de cada parámetro al llamar a este método. Simplemente use 0 para el parámetro de nivel, porque no usamos la textura piramidal. El parámetro de formato indica el formato de los datos de textura. El valor específico es como se muestra en la siguiente tabla. Debe seleccionar este parámetro de acuerdo con el formato de la imagen de textura. La imagen de textura utilizada en el programa de muestra está en formato JPG, que representa cada píxel con tres componentes de RGB, por lo que especificamos el parámetro como gl.RGB. Para imágenes en otros formatos, como imágenes en formato PNG, generalmente se usa gl.RGBA, gl.RGB generalmente se usa para imágenes en formato BMP y gl.LUMINANCE y gl.LUMINANCE_ALPHA generalmente se usan para imágenes en escala de grises, etc.

Formato de datos de texto.

Los lúmenes aquí representan el brillo que percibimos en la superficie de un objeto. Los lúmenes generalmente se calculan utilizando un promedio ponderado de los valores de los componentes de color rojo, verde y azul de la superficie del objeto.

El método gl.texImage2D() almacena la imagen de textura en un objeto de textura en el sistema WebGL. Una vez almacenada, debes indicarle al sistema el tipo de formato de la imagen de textura a través del parámetro internalformat . En WebGL, el formato interno debe ser el mismo que el formato.

El parámetro de tipo especifica el tipo de datos de textura; consulte la tabla a continuación. Normalmente utilizamos el tipo de datos gl.UNSIGNED_BYTE. Por supuesto, también se pueden utilizar otros tipos de datos, como gl.UNSIGNED_SHORT_5_6_5 (que comprime los tres componentes RGB en 16 bits). Estos últimos formatos de datos se utilizan a menudo para comprimir datos y reducir el tiempo que tarda el navegador en cargar imágenes.

Formato de datos de datos de textura.

Pasar la unidad de textura al sombreador de fragmentos (gl.uniform1i()) 

Una vez que la imagen de textura se pasa al sistema WebGL, se debe pasar al sombreador de fragmentos y asignarla a la superficie de los gráficos. Como se mencionó anteriormente, usamos variables uniformes para representar texturas porque la imagen de la textura no cambia con el fragmento.

La variable uniforme que representa el objeto de textura en el sombreador debe declararse como un tipo de datos especial dedicado a los objetos de textura, como se muestra en la siguiente tabla. El programa de muestra utiliza la textura bidimensional gl.TEXTURE_2D, por lo que el tipo de datos de la variable uniforme se establece en sampler2D. 

Tipo de datos específico de texturas.

En la función initTextures() (línea 78), obtenemos la dirección de almacenamiento de la variable uniforme u_Sampler (línea 108) y la pasamos como parámetro a la función loadTexture(). Debemos pasar el objeto de textura a u_Sampler especificando el número de unidad de textura (la n en gl.TEXTUREn). El único objeto de textura en este ejemplo está vinculado a gl.TEXTURE0, por lo que cuando se llama a gl.uniformi(), el segundo parámetro es 0. 

Después de ejecutar la línea 92, el estado interno del sistema WebGL se muestra a continuación, para que el sombreador de fragmentos finalmente pueda acceder a la imagen de textura.

Transfiera coordenadas de textura del sombreador de vértices al sombreador de fragmentos 

Dado que recibimos las coordenadas de textura del vértice a través de la variable de atributo a_TexCoord, es factible asignar los datos a la variable variable v_TexCoord y pasar las coordenadas de textura al sombreador de fragmentos. Quizás recuerde que se pueden usar variables variables del mismo nombre y tipo en el sombreador de fragmentos y el sombreador de vértices para transferir datos entre los dos. Las coordenadas de textura de los fragmentos entre vértices se interpolarán durante el proceso de rasterización, por lo que en el sombreador de fragmentos utilizamos las coordenadas de textura interpoladas.

Esto completa todos los preparativos para usar texturas en un sistema WebGL.

El trabajo restante es extraer el color del texel de la imagen de textura de acuerdo con las coordenadas de textura del fragmento y luego aplicarlo al fragmento actual.

Obtener el color del píxel de textura en el sombreador de fragmentos (texture2D()) 

El sombreador de fragmentos obtiene el color del texel de la imagen de textura (línea 19).

Utilice la función integrada de GLSL ES textura2D() para extraer colores de texto . Esta función es fácil de usar: solo necesita pasar dos parámetros: el número de unidad de textura y las coordenadas de textura para obtener el color del píxel en la textura. Esta función está incorporada, preste atención a sus tipos de parámetros y valor de retorno. 

especificación del método textura2D()

Valor de retorno del método textura2D()

 

Los parámetros de los métodos de mejora y reducción de textura determinarán cómo el sistema WebGL interpolará los fragmentos . Asignamos el valor de retorno de la función textura2D() a la variable gl_FragColor, y luego el sombreador de fragmentos tiñe el fragmento actual en este color. Finalmente, la imagen de la textura se asigna a la forma (un rectángulo en este caso) y finalmente se dibuja. 

Este es el paso final en el mapeo de texturas. En este punto, la textura ha sido cargada, configurada y asignada al gráfico, esperando a que la dibujes.

Como puede ver, el mapeo de texturas en WebGL es un proceso relativamente complicado, en parte porque debe dejar que el navegador cargue la imagen de la textura y en parte porque, incluso si solo hay una textura, debe usar unidades de textura.

Ejercicio: Modifique las coordenadas de textura para cambiar los efectos de mapeo de texturas

Para familiarizarnos más con el mapeo de texturas, modifiquemos las coordenadas de textura en el programa de ejemplo. Por ejemplo, modifique las coordenadas de textura en este ejemplo de la siguiente manera:

El efecto de ejecución del código del programa modificado se muestra en la siguiente figura (izquierda). La imagen de la derecha muestra las coordenadas de textura de los cuatro vértices del rectángulo y las posiciones de las cuatro esquinas de la imagen de textura en el rectángulo. Esta imagen puede ayudarlo a comprender mejor el sistema de coordenadas de textura. 

Dado que la imagen de la textura no es lo suficientemente grande como para cubrir todo el rectángulo, puede ver que la textura se repite en áreas que deberían estar vacías. La razón de esto es que en el programa de muestra, configuramos los parámetros gl.TEXTURE_WRAP_S y gl.TEXTURE_WRAP_T en gl.REPEAT. 

Ahora, modifiquemos los parámetros de textura de la siguiente manera para ver qué otros efectos podemos obtener. El programa modificado se llama TexturedQuad_Clamp_Mirror y la siguiente imagen muestra cómo se ejecuta en el navegador.

Se puede ver que en el eje s (eje horizontal), la textura se rellena con el color de la mayoría de los texels de borde, y en el eje t (eje vertical), la textura se rellena repetidamente en una imagen especular. 

Supongo que te gusta

Origin blog.csdn.net/dabaooooq/article/details/132724182
Recomendado
Clasificación