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 level
ext.COMPRESSED_RGBA_S3TC_DXT5_EXT,
512, // width
512, // height
0, // border
textureData // 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 texture
const 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 minification
gl.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 extensions
this._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"]);