登峰造极境

  • WIN
    • CSharp
    • JAVA
    • OAM
    • DirectX
    • Emgucv
  • UNIX
    • FFmpeg
    • QT
    • Python
    • Opencv
    • Openwrt
    • Twisted
    • Design Patterns
    • Mysql
    • Mycat
    • MariaDB
    • Make
    • OAM
    • Supervisor
    • Nginx
    • KVM
    • Docker
    • OpenStack
  • WEB
    • ASP
    • Node.js
    • PHP
    • Directadmin
    • Openssl
    • Regex
  • APP
    • Android
  • AI
    • Algorithm
    • Deep Learning
    • Machine Learning
  • IOT
    • Device
    • MSP430
  • DIY
    • Algorithm
    • Design Patterns
    • MATH
    • X98 AIR 3G
    • Tucao
    • fun
  • LIFE
    • 美食
    • 关于我
  • LINKS
  • ME
Claves
长风破浪会有时,直挂云帆济沧海
  1. 首页
  2. Platforms
  3. WEB
  4. WebGL
  5. 正文

WebGL的WebGLRenderingContext浅析

2024-10-08

WebGL上下文是从canvas标签中获取到的,通过canvas对象的getContext()函数可以获取WebGLRenderingContext。

跟据参数的不同,getContext()函数可以获取不同种类的渲染上下文。

当你调用 canvas.getContext('webgl') 时,返回的是一个 WebGLRenderingContext 对象。这个对象是 WebGL API 的核心接口,它提供了用于与 WebGL 进行交互的方法和属性。

一、基本使用

WebGLRenderingContext 对象的方法和属性主要用于以下几类操作:

  1. 绘制操作:
    • clear(): 清除指定的缓冲区。
    • drawArrays(): 使用顶点数组绘制图元。
    • drawElements(): 使用索引数组绘制图元。
  2. 缓冲区操作:
    • createBuffer(): 创建新的缓冲区对象。
    • bindBuffer(): 绑定缓冲区对象。
    • bufferData(): 创建并初始化缓冲区对象的数据存储。
  3. 着色器操作:
    • createShader(): 创建新的着色器对象。
    • shaderSource(): 设置着色器源代码。
    • compileShader(): 编译着色器代码。
    • createProgram(): 创建新的着色器程序。
    • attachShader(): 将着色器附加到程序上。
    • linkProgram(): 链接着色器程序。
    • useProgram(): 使用指定的着色器程序。
  4. 纹理操作:
    • createTexture(): 创建新的纹理对象。
    • bindTexture(): 绑定纹理对象。
    • texImage2D(): 指定二维纹理图像。
  5. 属性和视图设置:
    • viewport(): 设置视口。
    • enable(): 启用特定的 WebGL 功能。
    • disable(): 禁用特定的 WebGL 功能。
  6. 获取信息:
    • getParameter(): 返回特定参数的值。
    • getProgramInfoLog(): 获取着色器程序的错误信息。
    • getShaderInfoLog(): 获取着色器的错误信息。
// 获取 WebGL 上下文
var canvas = document.getElementById('myCanvas');
var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');

if (!gl) {
    console.log('WebGL not supported, falling back on experimental-webgl');
    gl = canvas.getContext('experimental-webgl');
}

if (!gl) {
    alert('Your browser does not support WebGL');
}

// 设置视口
gl.viewport(0, 0, canvas.width, canvas.height);

// 清除颜色缓冲区
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

// 创建和编译顶点着色器
var vertexShaderSource = `
    attribute vec4 a_Position;
    void main() {
        gl_Position = a_Position;
    }
`;
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);

// 创建和编译片段着色器
var fragmentShaderSource = `
    void main() {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Red color
    }
`;
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);

// 链接着色器程序
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);

// 创建缓冲区并传递顶点数据
var vertices = new Float32Array([
    0.0,  0.5,
   -0.5, -0.5,
    0.5, -0.5
]);
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

// 获取顶点着色器中的位置变量并启用它
var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position);

// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3);

二、webgl坐标系

WebGL 的默认坐标系是一个右手坐标系,范围在 [-1, 1] 之间。具体来说:

  • X 轴:从左到右,范围是 -1 到 1。
  • Y 轴:从下到上,范围是 -1 到 1。
  • Z 轴:从屏幕外到屏幕内,范围是 -1 到 1。

在 WebGL 中,顶点坐标通常使用归一化设备坐标(NDC),这些坐标经过投影和视口变换后映射到屏幕坐标。

归一化设备坐标(NDC, Normalized Device Coordinates)中的 -1 并不表示无穷远。NDC 是一种线性坐标系,用于表示顶点在裁剪空间中的位置,范围是从 -1 到 1。这个坐标系是线性的,而不是对数的。

详细说明:

  1. NDC 范围:
    • X 轴:从 -1 到 1,表示从屏幕的左边缘到右边缘。
    • Y 轴:从 -1 到 1,表示从屏幕的下边缘到上边缘。
    • Z 轴:从 -1 到 1,表示从近裁剪面(near plane)到远裁剪面(far plane)。
  2. 线性坐标:
    • NDC 是线性的,这意味着在 NDC 范围内的每个单位长度是等距的。例如,从 -1 到 0 的距离与从 0 到 1 的距离是相同的。
    • 在 WebGL 中,通过投影矩阵将视图空间(摄像机空间)坐标转换为裁剪空间坐标,然后进行透视除法(perspective divide)得到 NDC 坐标。
  3. 透视投影与深度缓冲:
    • 透视投影矩阵将视图空间中的坐标转换为裁剪空间坐标。这一过程中,深度值(Z 值)会被非线性地压缩,以便在近裁剪面附近有更高的精度。
    • 然后,通过透视除法,将裁剪空间坐标转换为 NDC 坐标。此时,NDC 坐标中的 Z 值仍然是线性的,范围在 -1 到 1 之间。
    • 最后,NDC 坐标会被映射到屏幕空间坐标,并存储在深度缓冲区中。深度缓冲区中的值通常是非线性的,以便更好地处理透视投影的深度精度问题。

Three.js 坐标系

Three.js 使用右手坐标系,默认情况下:

  • X 轴:从左到右。
  • Y 轴:从下到上。
  • Z 轴:从屏幕外到屏幕内(正 Z 轴指向屏幕外,负 Z 轴指向屏幕内)。

Three.js 的世界坐标系和 WebGL 的 NDC 坐标系不同。Three.js 提供了相机和投影矩阵来将三维世界坐标转换为 WebGL 的 NDC 坐标。

CesiumJS 坐标系

CesiumJS 是用于地理空间应用的 3D 引擎,它使用右手坐标系,但与其他引擎有所不同:

  • X 轴:指向本初子午线(0度经线)方向。
  • Y 轴:指向东经90度方向。
  • Z 轴:指向北极方向。

CesiumJS 主要使用地理坐标(经度、纬度、高度)和地心坐标(ECEF,Earth-Centered, Earth-Fixed),并提供转换函数将它们转换为 WebGL 的 NDC 坐标。

Babylon.js 坐标系

Babylon.js 也是一个使用右手坐标系的 3D 引擎,默认情况下:

  • X 轴:从左到右。
  • Y 轴:从下到上。
  • Z 轴:从屏幕外到屏幕内(正 Z 轴指向屏幕外,负 Z 轴指向屏幕内)。

与 Three.js 类似,Babylon.js 使用相机和投影矩阵将三维世界坐标转换为 WebGL 的 NDC 坐标。

总结

  • WebGL:右手坐标系,NDC 范围为 [-1, 1]。
  • Three.js:右手坐标系,默认相机方向与 WebGL 一致。
  • CesiumJS:右手坐标系,地理空间坐标系与地心坐标系。
  • Babylon.js:右手坐标系,默认相机方向与 WebGL 一致。
标签: 暂无
最后更新:2024-10-08

代号山岳

知之为知之 不知为不知

点赞
< 上一篇
下一篇 >

COPYRIGHT © 2099 登峰造极境. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蜀ICP备14031139号-5

川公网安备51012202000587号