返回

WebGL 2.0系列之采样器对象: 深度探索纹理采样之艺术

前端

前言

在WebGL 1.0中,纹理的图片数据和采样信息都存储在纹理对象中。这意味着如果我们希望从同一张图片中多次读取像素信息,但每次读取时使用的过滤方式不同,就需要创建两个不同的纹理对象。这既浪费内存,又降低了渲染效率。

WebGL 2.0中的采样器对象解决了这个问题。采样器对象是一个独立于纹理对象的对象,它存储了纹理的采样信息,如过滤方式、环绕方式和LOD偏置。这使得我们可以使用同一个纹理对象,但通过不同的采样器对象来读取不同的像素信息。

采样器对象的概念

采样器对象本质上是纹理采样状态的容器,主要用于定义纹理如何被采样,包括过滤、环绕方式和LOD偏置等。它可以应用于任何纹理对象,并提供了比WebGL 1.0中纹理对象更灵活的纹理采样控制。

创建采样器对象

为了创建采样器对象,我们需要使用WebGL的createSampler()函数。该函数返回一个采样器对象,我们可以使用它来设置各种采样参数。

const sampler = gl.createSampler();

设置采样器参数

创建采样器对象后,我们可以使用samplerParameteri()samplerParameterf()函数来设置采样器参数。这些参数控制着纹理的采样方式。

参数 说明
TEXTURE_MAG_FILTER 放大时的过滤方式
TEXTURE_MIN_FILTER 缩小时的过滤方式
TEXTURE_WRAP_S 水平环绕方式
TEXTURE_WRAP_T 垂直环绕方式
TEXTURE_MIN_LOD 最小LOD级别
TEXTURE_MAX_LOD 最大LOD级别
TEXTURE_LOD_BIAS LOD偏置

放大时的过滤方式

放大时的过滤方式控制着当纹素被放大时如何计算颜色值。有四种可供选择的过滤方式:

  • NEAREST:最近邻过滤。这是最简单的过滤方式,它只是选择离采样点最近的纹素的颜色值。
  • LINEAR:线性过滤。线性过滤在两个相邻的纹素之间进行插值,以获得更平滑的颜色过渡。
  • NEAREST_MIPMAP_NEAREST:最近邻Mipmap最近邻过滤。这种过滤方式使用Mipmap来提高纹理的质量。它先选择离采样点最近的Mipmap级别,然后在这个Mipmap级别上使用最近邻过滤。
  • LINEAR_MIPMAP_NEAREST:线性Mipmap最近邻过滤。这种过滤方式使用Mipmap来提高纹理的质量。它先选择离采样点最近的Mipmap级别,然后在这个Mipmap级别上使用线性过滤。
  • NEAREST_MIPMAP_LINEAR:最近邻Mipmap线性过滤。这种过滤方式使用Mipmap来提高纹理的质量。它先选择离采样点最近的两个Mipmap级别,然后在这两个Mipmap级别之间进行插值,以获得更平滑的颜色过渡。
  • LINEAR_MIPMAP_LINEAR:线性Mipmap线性过滤。这种过滤方式使用Mipmap来提高纹理的质量。它先选择离采样点最近的两个Mipmap级别,然后在这两个Mipmap级别之间进行插值,以获得更平滑的颜色过渡。

缩小时的过滤方式

缩小时的过滤方式控制着当纹素被缩小时如何计算颜色值。有四种可供选择的过滤方式:

  • NEAREST:最近邻过滤。这是最简单的过滤方式,它只是选择离采样点最近的纹素的颜色值。
  • LINEAR:线性过滤。线性过滤在两个相邻的纹素之间进行插值,以获得更平滑的颜色过渡。
  • NEAREST_MIPMAP_NEAREST:最近邻Mipmap最近邻过滤。这种过滤方式使用Mipmap来提高纹理的质量。它先选择离采样点最近的Mipmap级别,然后在这个Mipmap级别上使用最近邻过滤。
  • LINEAR_MIPMAP_NEAREST:线性Mipmap最近邻过滤。这种过滤方式使用Mipmap来提高纹理的质量。它先选择离采样点最近的Mipmap级别,然后在这个Mipmap级别上使用线性过滤。
  • NEAREST_MIPMAP_LINEAR:最近邻Mipmap线性过滤。这种过滤方式使用Mipmap来提高纹理的质量。它先选择离采样点最近的两个Mipmap级别,然后在这两个Mipmap级别之间进行插值,以获得更平滑的颜色过渡。
  • LINEAR_MIPMAP_LINEAR:线性Mipmap线性过滤。这种过滤方式使用Mipmap来提高纹理的质量。它先选择离采样点最近的两个Mipmap级别,然后在这两个Mipmap级别之间进行插值,以获得更平滑的颜色过渡。

水平环绕方式

水平环绕方式控制着当纹理坐标超出[0, 1]的范围时如何处理。有三种可供选择的环绕方式:

  • REPEAT:重复。这种环绕方式将纹理重复多次,直到覆盖整个表面。
  • MIRRORED_REPEAT:镜像重复。这种环绕方式将纹理镜像重复多次,直到覆盖整个表面。
  • CLAMP_TO_EDGE:边缘裁剪。这种环绕方式将纹理的颜色值钳制在[0, 1]的范围内。

垂直环绕方式

垂直环绕方式控制着当纹理坐标超出[0, 1]的范围时如何处理。有三种可供选择的环绕方式:

  • REPEAT:重复。这种环绕方式将纹理重复多次,直到覆盖整个表面。
  • MIRRORED_REPEAT:镜像重复。这种环绕方式将纹理镜像重复多次,直到覆盖整个表面。
  • CLAMP_TO_EDGE:边缘裁剪。这种环绕方式将纹理的颜色值钳制在[0, 1]的范围内。

最小LOD级别

最小LOD级别控制着纹理可以被缩小的最小程度。LOD级别越高,纹理的质量就越好,但渲染的成本也越高。

最大LOD级别

最大LOD级别控制着纹理可以被放大的最大程度。LOD级别越高,纹理的质量就越好,但渲染的成本也越高。

LOD偏置

LOD偏置可以用来手动调整纹理的LOD级别。正值会使纹理被缩小,负值会使纹理被放大。

使用采样器对象

设置完采样器参数后,就可以将其绑定到纹理单元。纹理单元是一个用来存储采样器对象的特殊变量。我们可以使用gl.bindSampler()函数来将采样器对象绑定到纹理单元。

gl.bindSampler(0, sampler);

一旦采样器对象被绑定到纹理单元,就可以在片段着色器中使用它来采样纹理。在片段着色器中,我们可以使用texture2D()函数来从纹理中读取像素信息。

vec4 color = texture2D(texture, uv);

采样器对象的优势

使用采样器对象有以下几个优势:

  • 提高性能:采样器对象可以减少纹理对象的数量,从而提高渲染性能。
  • 提高灵活性:采样器对象可以让我们使用同一个纹理对象,但通过不同的采样器对象来读取不同的像素信息。这提供了比WebGL 1.0中纹理对象更灵活的纹理采样控制。
  • 提高代码的可读性和可维护性:采样器对象可以使我们的代码更易于阅读和维护。

结语

采样器对象是WebGL 2.0中一个非常重要的特性。它可以提高性能、提高灵活性,并提高代码的可读性和可维护性。如果你正在使用WebGL 2.0,强烈建议你使用采样器对象。