WebGL 2.0系列之采样器对象: 深度探索纹理采样之艺术
2023-09-17 18:21:45
前言
在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,强烈建议你使用采样器对象。