Cesium 用到的webgl扩展
Cesium 用到的webgl扩展
1 OES_standard_derivatives
OES_standard_derivatives 是 OpenGL ES 2.0 和 WebGL 1.0 的扩展,定义在 OpenGL ES 扩展规范中。
它引入了三个 GLSL 内置函数,用于在片段着色器中计算导数
- dFdx§:计算参数 p 在屏幕空间 x 方向上的偏导数。
- dFdy§:计算参数 p 在屏幕空间 y 方向上的偏导数。
- fwidth§:计算 |dFdx§| + |dFdy§|,表示参数 p 的总变化率(宽度)
这些函数返回片段在屏幕空间中的导数,反映了变量(如纹理坐标或颜色)在相邻像素之间的变化。
2 EXT_blend_minmax
EXT_blend_minmax 是由 Khronos Group 开发的图形 API 扩展,主要用于 OpenGL 和 OpenGL ES,可增强光栅化期间的混合作。它引入了新的混合方程,允许计算源颜色和目标颜色组件的最小值或最大值,这对于游戏和可视化中的叠加混合、阴影映射或后期处理等效果非常有用。该扩展于 1995 年首次指定,并已被广泛采用。
新的混合方程
- MIN_EXT:计算源颜色和目标颜色的最小值。
- MAX_EXT:计算源颜色和目标颜色的最大值。
- GL_FUNC_ADD_EXT:标准的加法混合方程, source + dest
3 OES_element_index_uint
OES_element_index_uint 是一个 WebGL 扩展,允许使用 32 位无符号整数索引 (gl.UNSIGNED_INT) 用于 WebGL 1.0 中的元素数组缓冲区。这允许渲染具有多达 4,294,967,296 (2³²) 个顶点的网格,这对于超过 16 位索引 (gl.UNSIGNED_SHORT,最多 65,535 个顶点)。如果没有此扩展,WebGL 1.0 仅限于 gl。UNSIGNED_BYTE(最大 255)或 gl。UNSIGNED_SHORT。
if (Geometry.computeNumberOfVertices(geometry) >=CesiumMath.SIXTY_FOUR_KILOBYTES &&context.elementIndexUint
) {indexBuffer = Buffer.createIndexBuffer({context: context,typedArray: new Uint32Array(indices),usage: bufferUsage,indexDatatype: IndexDatatype.UNSIGNED_INT,});
} else {indexBuffer = Buffer.createIndexBuffer({context: context,typedArray: new Uint16Array(indices),usage: bufferUsage,indexDatatype: IndexDatatype.UNSIGNED_SHORT,});
}
4 WEBGL_depth_texture
在 WebGL 2.0 中,深度纹理是核心规范的一部分,因此不需要扩展。
// gl.DEPTH_COMPONENT (16/24-bit depth) or gl.DEPTH_STENCIL (24-bit depth + 8-bit stencil).
this._depthTexture = new Texture({context: context,width: width,height: height,pixelFormat: PixelFormat.DEPTH_COMPONENT,pixelDatatype: PixelDatatype.UNSIGNED_INT,sampler: Sampler.NEAREST,
});
5 EXT_frag_depth
WebGL 中的 EXT_frag_depth 扩展允许片段着色器通过写入 gl_FragDepth 输出变量来显式设置片段的深度值。这对于自定义深度计算非常有用,例如在阴影贴图、体积渲染或需要修改默认深度缓冲区值的高级效果中。
6 WEBGL_debug_shaders
在着色器被编译成底层图形驱动程序的本机着色语言(例如,DirectX 的 HLSL、OpenGL 的 GLSL)后检索着色器的翻译源代码。这主要用于调试目的,允许开发人员检查如何针对 GPU 转换高级 GLSL 代码。
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2'); // Or 'webgl2' for WebGL 2// Create and compile a sample shader
const shader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(shader, `void main() {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Red color}
`);
gl.compileShader(shader);// Request the extension
const debugExt = gl.getExtension('WEBGL_debug_shaders');
if (debugExt) {const translatedSource = debugExt.getTranslatedShaderSource(shader);console.log('Translated Shader Source:\n', translatedSource);// Example output might look like: "void main(){ gl_FragColor=vec4(1.0,0.0,0.0,1.0); }"
} else {console.warn('WEBGL_debug_shaders not supported');
}
7 OES_texture_float
OES_texture_float 是 OpenGL ES(和 WebGL)的扩展,支持对纹理使用 32 位浮点像素格式 。这允许开发人员存储和作高动态范围 (HDR) 数据,例如精确的照明或科学可视化,而不会因标准 8 位整数格式而造成精度损失。它于 2005 年获得 Khronos 集团的批准,并在现代浏览器和设备中得到广泛支持。
支持的格式:
- RGBA32F
- RGB32F
- LUMINANCE_ALPHA32F
- LUMINANCE32F/ALPHA32F
创建浮点纹理 :
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);// Upload data (e.g., from a Float32Array or image)
const width = 256, height = 256;
const data = new Float32Array(width * height * 4); // RGBA floats
// Fill data array...
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.FLOAT, data);
常见用例:
- HDR 渲染和色调映射
- 计算着色器或 GPGPU 模拟(例如粒子系统)
8 OES_texture_half_float
OES_texture_half_float 扩展允许对 OpenGL ES 和 WebGL 中的纹理使用 16 位半精度浮点像素格式。它专为需要比 8 位整数纹理更高的精度但内存开销低于 32 位完整浮点数(由 OES_texture_float 提供)的方案而设计。此扩展对于高动态范围 (HDR) 渲染、计算任务和数据可视化特别有用,同时优化资源受限设备上的性能。
支持的格式:
- RGBA16F
- RGB16F
- LUMINANCE_ALPHA16F
- LUMINANCE16F/ALPHA16F
创建半浮点纹理:
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);// Upload data (e.g., from a Float32Array, converted to half-float)
const width = 256, height = 256;
const data = new Float32Array(width * height * 4); // RGBA data
// Fill data array (note: WebGL may require specific half-float encoding on some platforms)
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, ext.HALF_FLOAT_OES, data);
9 OES_texture_float_linear 和 OES_texture_half_float_linear
为具有浮点像素格式的纹理启用线性过滤(双线性或三线性),特别是由 OES_texture_float(32 位浮点)和 OES_texture_half_float 定义的纹理(16 位半浮点数)在 OpenGL ES 和 WebGL 中。如果没有此扩展,浮点纹理将仅限于 NEAREST 或 NEAREST_MIPMAP_NEAREST 过滤,这可能会产生块状结果。此扩展对于高动态范围 (HDR) 渲染、科学可视化或计算任务等应用程序中的平滑插值至关重要。
10 EXT_shader_texture_lod
EXT_shader_texture_lod 扩展支持对 OpenGL ES 和 WebGL 片段着色器中的纹理细节级别 (LOD) 进行显式控制 。通常,片段着色器中的纹理采样使用基于纹理缩放的自动 LOD 选择,但此扩展允许开发人员使用诸如 .这对于着色器中的自定义 mipmapping、模糊或细节控制等效果特别有用。
仅在 OpenGL ES 2.0 (WebGL 1.0) 中的片段着色器中可用 。在 WebGL 2.0(基于 OpenGL ES 3.0)中,顶点着色器中可以通过 textureLod 获得等效功能 ,而无需扩展。
依赖项: 需要具有 mipmap(通过 gl.generateMipmap 生成)的纹理才能有意义地运行,因为 LOD 控制对不同 mipmap 级别的访问。
用例 :实现对纹理细节的精确控制,对于景深、自定义抗锯齿或风格化渲染等效果非常有用。
使用:
// 设置 mipmapped 纹理
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);// Upload texture data
const width = 256, height = 256;
const data = new Uint8Array(width * height * 4); // RGBA data
// Fill data array...
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
gl.generateMipmap(gl.TEXTURE_2D); // Generate mipmaps// 在片段着色器中使用
#extension GL_EXT_shader_texture_lod : enable
precision mediump float;
uniform sampler2D u_texture;
varying vec2 v_texCoord;void main() {// Sample texture with explicit LOD (e.g., level 2)vec4 color = texture2DLodEXT(u_texture, v_texCoord, 2.0);gl_FragColor = color;
}
常见用例:
- 用于艺术效果(例如,模糊或锐化)的自定义 mipmap 选择
- 实现高级后处理(例如,泛光、景深)
- 根据距离或其他参数实时控制纹理细节
11 EXT_color_buffer_float 和 EXT_color_buffer_half_float
渲染到 32 位浮点和 16 位半浮点颜色附件的帧缓冲区对象 (FBO)。这些扩展允许高精度渲染,这对于高动态范围 (HDR) 渲染、延迟着色或需要未钳制颜色值的计算任务至关重要。
- EXT_color_buffer_float: 允许将 32-bit 浮点纹理(由 OES_texture_float 创建)用作帧缓冲区的 颜色附件,支持向这些纹理渲染。
- EXT_color_buffer_half_float: 允许将 16-bit 半浮点纹理(由 OES_texture_half_float 创建)用作帧缓冲区的 颜色附件
常见用例:
- HDR 渲染 :存储色调映射、泛光或光散射的未钳制颜色值
- 延迟渲染 :对 G 缓冲区纹理(例如法线、反照率、深度)使用浮点缓冲区
- GPGPU: 在渲染到纹理管道中对高精度数据进行计算
12 EXT_float_blend
可对 32 位浮点颜色缓冲区进行混合作。它建立在 EXT_color_buffer_float 扩展之上 ,该扩展允许渲染到浮点帧缓冲区,但由于当时的硬件限制,最初不允许混合。
13 WEBGL_compressed_texture_s3tc
WEBGL_compressed_texture_s3tc 是一个 WebGL 扩展,它向 WebGL API 公开了四种 S3TC (DXT) 压缩纹理格式。
S3TC 最初由 S3 Graphics 开发,是一系列有损纹理压缩算法,在桌面和移动 GPU 上得到广泛支持,特别是在基于 Windows 和 DirectX 的硬件上。此扩展允许开发人员上传预压缩纹理,从而减少内存使用和带宽,而不会产生运行时压缩开销。
该扩展为压缩的内部格式添加了四个常量:
- COMPRESSED_RGB_S3TC_DXT1_EXT
- COMPRESSED_RGBA_S3TC_DXT1_EXT
- COMPRESSED_RGBA_S3TC_DXT3_EXT
- COMPRESSED_RGBA_S3TC_DXT5_EXT
示例 (JavaScript)
const canvas = document.getElementById('webgl-canvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');// Enable extension with fallbacks
const ext = gl.getExtension('WEBGL_compressed_texture_s3tc') ||gl.getExtension('MOZ_WEBGL_compressed_texture_s3tc') ||gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc');if (!ext) {console.error('S3TC compressed textures not supported');return;
}// Assume textureData is a Uint8Array from a pre-compressed DDS file (e.g., DXT5)
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.compressedTexImage2D(gl.TEXTURE_2D,0, // mip levelext.COMPRESSED_RGBA_S3TC_DXT5_EXT,512, // width512, // height0, // bordertextureData // compressed data
);// Set filters (note: mipmapping requires full mip chain)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);// Generate mipmaps if chain is complete
gl.generateMipmap(gl.TEXTURE_2D);
14 EXT_texture_filter_anisotropic
可实现各向异性纹理过滤,从而提高从斜角观察的纹理表面的视觉质量。如果没有各向异性滤波,浅角度的道路或墙壁等表面上的纹理会显得模糊;此扩展通过沿最大拉伸方向采样更多纹素来缓解这种情况。
各向异性过滤可增强以陡峭角度观察的表面的纹理清晰度,这在 3D 游戏和可视化中很常见。它比双线性或三线性滤波的计算量更大,但通过根据视角自适应地采样纹理来提供卓越的图像质量。该扩展允许开发人员指定各向异性级别(例如,2x、4x、16x),最高可达硬件定义的最大值。
示例(WebGL JavaScript)
const canvas = document.getElementById('webgl-canvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');const ext = gl.getExtension('EXT_texture_filter_anisotropic') ||gl.getExtension('MOZ_EXT_texture_filter_anisotropic') ||gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic');if (!ext) {console.warn('Anisotropic filtering not supported');
} else {// Query max anisotropy level (e.g., 16.0)const maxAnisotropy = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT);console.log(`Max anisotropy: ${maxAnisotropy}`);// Create and bind textureconst texture = gl.createTexture();gl.bindTexture(gl.TEXTURE_2D, texture);// Upload texture data (example: 256x256 RGBA)gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, imageData);// Enable mipmaps for minificationgl.generateMipmap(gl.TEXTURE_2D);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);// Set anisotropic filtering level (e.g., clamp to max supported)gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(16, maxAnisotropy));
}
15 OES_vertex_array_object
提供对顶点数组对象 (VAO) 的支持。VAO 封装顶点属性状态(例如,缓冲区绑定、属性指针)以减少冗余设置调用,提高性能并简化渲染管道中的状态管理。
VAO 存储顶点属性数组的状态 (例如,glVertexAttribPointer、glEnableVertexAttribArray、缓冲区绑定) 。如果没有 VAO,开发人员必须为每次绘制调用重新指定属性设置,这是低效的。VAO 允许绑定单个对象以恢复所有顶点属性状态,从而优化渲染,特别是对于具有多个网格体的复杂场景。
16 ANGLE_instanced_arrays
它支持实例化渲染,允许通过单个绘制调用绘制同一几何体的多个实例。这对于通过共享顶点数据和改变每个实例的属性来有效地渲染重复对象(例如树、粒子)特别有用。它基于 OpenGL ES 扩展 ANGLE_instanced_arrays,与 OpenGL ARB_instanced_arrays 紧密结合。
WebGL 1.0 的独立扩展。内置于 WebGL 2.0 核心(基于 OpenGL ES 3.0)
17 WEBGL_draw_buffers
可以在单个绘制调用中同时渲染到多个颜色缓冲区,这是多渲染目标 (MRT) 功能的一部分。它允许片段着色器输出到附加到帧缓冲区的多个纹理或渲染缓冲区,这对于延迟渲染、后处理或阴影映射等技术非常有用。此扩展基于 OpenGL ES 的 EXT_draw_buffers,是 WebGL 2.0 的核心(与 OpenGL ES 3.0 保持一致)。
完整代码
Context.js
使用
gl.getExtension();
// Query and initialize extensionsthis._standardDerivatives = !!getExtension(gl, ["OES_standard_derivatives"]);this._blendMinmax = !!getExtension(gl, ["EXT_blend_minmax"]);this._elementIndexUint = !!getExtension(gl, ["OES_element_index_uint"]);this._depthTexture = !!getExtension(gl, ["WEBGL_depth_texture","WEBKIT_WEBGL_depth_texture",]);this._fragDepth = !!getExtension(gl, ["EXT_frag_depth"]);this._debugShaders = getExtension(gl, ["WEBGL_debug_shaders"]);this._textureFloat = !!getExtension(gl, ["OES_texture_float"]);this._textureHalfFloat = !!getExtension(gl, ["OES_texture_half_float"]);this._textureFloatLinear = !!getExtension(gl, ["OES_texture_float_linear"]);this._textureHalfFloatLinear = !!getExtension(gl, ["OES_texture_half_float_linear",]);this._supportsTextureLod = !!getExtension(gl, ["EXT_shader_texture_lod"]);this._colorBufferFloat = !!getExtension(gl, ["EXT_color_buffer_float","WEBGL_color_buffer_float",]);this._floatBlend = !!getExtension(gl, ["EXT_float_blend"]);this._colorBufferHalfFloat = !!getExtension(gl, ["EXT_color_buffer_half_float",]);this._s3tc = !!getExtension(gl, ["WEBGL_compressed_texture_s3tc","MOZ_WEBGL_compressed_texture_s3tc","WEBKIT_WEBGL_compressed_texture_s3tc",]);this._pvrtc = !!getExtension(gl, ["WEBGL_compressed_texture_pvrtc","WEBKIT_WEBGL_compressed_texture_pvrtc",]);this._astc = !!getExtension(gl, ["WEBGL_compressed_texture_astc"]);this._etc = !!getExtension(gl, ["WEBG_compressed_texture_etc"]);this._etc1 = !!getExtension(gl, ["WEBGL_compressed_texture_etc1"]);this._bc7 = !!getExtension(gl, ["EXT_texture_compression_bptc"]);const textureFilterAnisotropic = getExtension(gl, ["EXT_texture_filter_anisotropic","WEBKIT_EXT_texture_filter_anisotropic",])vertexArrayObject = getExtension(gl, ["OES_vertex_array_object"]);instancedArrays = getExtension(gl, ["ANGLE_instanced_arrays"]);drawBuffers = getExtension(gl, ["WEBGL_draw_buffers"]);