第 3 篇:让图形动起来 - WebGL 2D 变换

webGL硬核知识:图形渲染管渲染流程,各个阶段对应的API调用方式 顶点处理(Vertex Processing)阶段该阶段主要处理传入的顶点数据,包括顶点坐标、顶点颜色、法线向量等顶点相关的属性信息。进行的操作有坐标变换(例如将顶点从模型坐标系转换到世界坐标系、再到视图坐标系、裁剪坐标系等)以及对顶点属性进行必要的设置和计算等。例如,将一个 3D 模型中各个顶点的初始坐标通过平移、旋转、缩放等矩阵变换,使其放置到正确的空间位置,并且根据光照等需求计算顶点的光照属性(如果在顶点着色器中处理光照部分)。图元装配(Primitive Assembly)阶段。 阅读详情

到目前为止,我们已经创造了一个有形状、有颜色的三角形。但要让它在画布上移动,我们现在唯一的办法就是……回去修改 JavaScript 里的顶点坐标数组。

// 如果想让三角形向右移动一点...
const positionsAndColors = [
     0.1,  0.5,    1.0, 0.0, 0.0, // 把 x 从 0.0 改成 0.1
    -0.4, -0.5,    0.0, 1.0, 0.0, // 把 x 从 -0.5 改成 -0.4
     0.6, -0.5,    0.0, 0.0, 1.0  // 把 x 从 0.5 改成 0.6
];
// 然后重新上传整个 buffer 的数据...
gl.bufferData(...);

这太笨拙了!如果要让它旋转呢?天哪,那我们得拿出三角函数来手算每个点的新坐标。这种方式不仅效率低下,而且完全违背了 GPU 的设计初衷。

GPU,这位图形处理专家,最擅长的工作就是——疯狂地进行数学运算,尤其是矩阵运算。而变换 (Transformation),无论是平移、旋转还是缩放,本质上都是数学运算。

魔法咒语:矩阵 (Matrix)

想象一下,你有一个点的坐标 (x, y)。现在,我给你一个神奇的“咒语”——矩阵,你用这个点的坐标去乘以这个咒语,就能得到一个新的坐标 (x', y')。

  • 如果这个咒语是“平移咒语”,新坐标就是点平移后的位置。
  • 如果这个咒语是“旋转咒语”,新坐标就是点围绕原点旋转后的位置。
  • 如果这个咒语是“缩放咒语”,新坐标就是点缩放后的位置。

更神奇的是,这些咒语可以叠加!你可以先旋转,再平移,只需要把两个咒语矩阵先乘起来,得到一个更复杂的“复合咒语”,然后用这个终极咒语去处理所有的点,一步到位。

这就是 2D 变换的核心思想:定义一个物体的形状一次(比如一个以原点为中心的三角形),然后通过向 GPU 发送不同的“变换咒语”(矩阵),来控制它在屏幕上的最终状态。

新伙伴登场:uniform 变量

我们如何把这个“咒语矩阵”发送给 GPU 呢?

回顾一下,attribute 是给每个顶点都不同的数据。但变换矩阵对于一个物体的所有顶点来说,都是一样的,是统一的。因此,我们需要 GLSL 变量家族的最后一位成员:uniform。

uniform 变量就像一个全局指令,从 JavaScript 发出,顶点着色器(有时片元着色器也会用)里的每一次执行都能接收到这份完全相同的数据。

开始施法:代码改造

1. 顶点着色器:接收并使用矩阵

我们的顶点着色器需要一个 uniform 变量来接收 2D 变换矩阵(它是一个 3x3 的矩阵,所以类型是 mat3)。然后,在计算 gl_Position 之前,用它来变换顶点的位置。

attribute vec2 a_position;
attribute vec4 a_color;

uniform mat3 u_transformMatrix; // 新增:接收变换矩阵

varying vec4 v_color;

void main() {
  // 核心改动:
  // 1. 把 a_position (vec2) 扩展成 vec3,因为 mat3 需要和 vec3 相乘。
  //    我们加一个 1.0,这在图形学中称为齐次坐标,是矩阵运算的要求。
  // 2. 将位置向量与变换矩阵相乘,得到变换后的新位置。
  // 3. 取新位置的 x, y 分量,构建最终的 gl_Position。
  vec2 transformedPosition = (u_transformMatrix * vec3(a_position, 1.0)).xy;
  
  gl_Position = vec4(transformedPosition, 0.0, 1.0);
  v_color = a_color;
}

2. 片元着色器:无需改动!

颜色逻辑和变换无关,所以我们的片元着色器保持原样。

3. JavaScript:动画循环与矩阵计算

JavaScript 的部分将是改动最大的。我们需要:

  • 恢复顶点数据:让三角形的坐标变回最原始、最简单的状态,比如以(0,0)为中心。所有变换都交给矩阵。
  • 添加矩阵数学函数:在现实项目中,你通常会使用一个成熟的库(如 gl-matrix)。但为了教学,我们手动实现几个简单的函数来创建平移、旋转和缩放矩阵。这样能让你更清楚地看到底层发生了什么。
  • 获取 uniform 的位置:就像 getAttribLocation 一样,我们需要用 getUniformLocation 来找到着色器中 uniform 变量的地址。
  • 创建动画循环:使用 requestAnimationFrame,这是一个浏览器提供的 API,能让我们以最优的帧率来重复执行绘制函数,从而形成流畅的动画。在每一帧中,我们都会更新变换(比如改变旋转角度),计算新的矩阵,并重新绘制。

下面是集成了所有改动的完整代码。这次,你会看到一个在原地不停旋转的彩色三角形!

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>WebGL 教程 3:动态变换</title>
    <style>
        body { background-color: #333; color: #eee; text-align: center; }
        canvas { background-color: #000; border: 1px solid #555; }
    </style>
</head>
<body onload="main()">
    <h1>让图形动起来 - WebGL 2D 变换</h1>
    <canvas id="webgl-canvas" width="500" height="500"></canvas>

    <!-- 顶点着色器代码 (已更新) -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec2 a_position;
        attribute vec4 a_color;

        // 新增:接收一个 3x3 的变换矩阵
        uniform mat3 u_transformMatrix;

        varying vec4 v_color;

        void main() {
            // 将 2D 位置乘以 3x3 矩阵
            // a_position 是 vec2,需要扩展成 vec3 (x, y, 1) 才能与 mat3 相乘
            vec2 transformedPosition = (u_transformMatrix * vec3(a_position, 1.0)).xy;

            gl_Position = vec4(transformedPosition, 0.0, 1.0);
            v_color = a_color;
        }
    </script>

    <!-- 片元着色器代码 (无变化) -->
    <script id="fragment-shader" type="x-shader/x-fragment">
        precision mediump float;
        varying vec4 v_color;
        void main() {
            gl_FragColor = v_color;
        }
    </script>

    <script>
        // --- 简单的矩阵数学帮助函数 ---
        // 在实际项目中,你会使用像 gl-matrix 这样的库
        const matrixUtils = {
            createIdentity: () => [
                1, 0, 0,
                0, 1, 0,
                0, 0, 1
            ],
            createTranslation: (tx, ty) => [
                1, 0, 0,
                0, 1, 0,
                tx, ty, 1
            ],
            createRotation: (angleInRadians) => {
                const c = Math.cos(angleInRadians);
                const s = Math.sin(angleInRadians);
                return [
                    c, -s, 0,
                    s,  c, 0,
                    0,  0, 1
                ];
            },
            createScale: (sx, sy) => [
                sx, 0,  0,
                0, sy,  0,
                0,  0,  1
            ],

            // 矩阵乘法 (matA * matB)
            multiply: (matA, matB) => {
                const a00 = matA, a01 = matA, a02 = matA;
                const a10 = matA, a11 = matA, a12 = matA;
                const a20 = matA, a21 = matA, a22 = matA;
                const b00 = matB, b01 = matB, b02 = matB;
                const b10 = matB, b11 = matB, b12 = matB;
                const b20 = matB, b21 = matB, b22 = matB;
                return [
                    b00 * a00 + b01 * a10 + b02 * a20,
                    b00 * a01 + b01 * a11 + b02 * a21,
                    b00 * a02 + b01 * a12 + b02 * a22,
                    b10 * a00 + b11 * a10 + b12 * a20,
                    b10 * a01 + b11 * a11 + b12 * a21,
                    b10 * a02 + b11 * a12 + b12 * a22,
                    b20 * a00 + b21 * a10 + b22 * a20,
                    b20 * a01 + b21 * a11 + b22 * a21,
                    b20 * a02 + b21 * a12 + b22 * a22
                ];
            }
        };

        function main() {
            const canvas = document.getElementById('webgl-canvas');
            const gl = canvas.getContext('webgl');
            if (!gl) { alert('WebGL not supported!'); return; }

            const vertexShaderSource = document.getElementById('vertex-shader').text;
            const fragmentShaderSource = document.getElementById('fragment-shader').text;
            const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
            const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
            const program = createProgram(gl, vertexShader, fragmentShader);

            const positionAttributeLocation = gl.getAttribLocation(program, "a_position");
            const colorAttributeLocation = gl.getAttribLocation(program, "a_color");
            // 新增: 获取 uniform 变量的位置
            const matrixUniformLocation = gl.getUniformLocation(program, "u_transformMatrix");

            const positionBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
            
            // 顶点数据恢复到以原点为中心的简单版本
            const positionsAndColors = [
                 0.0,  0.25,   1.0, 0.0, 0.0,
                -0.25,-0.25,   0.0, 1.0, 0.0,
                 0.25,-0.25,   0.0, 0.0, 1.0
            ];
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positionsAndColors), gl.STATIC_DRAW);

            gl.useProgram(program);

            gl.enableVertexAttribArray(positionAttributeLocation);
            gl.enableVertexAttribArray(colorAttributeLocation);
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

            const FSIZE = (new Float32Array()).BYTES_PER_ELEMENT;
            const STRIDE = 5 * FSIZE;
            gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, STRIDE, 0);
            gl.vertexAttribPointer(colorAttributeLocation, 3, gl.FLOAT, false, STRIDE, 2 * FSIZE);

            let currentAngle = 0;
            
            // 动画循环
            function animate() {
                // 1. 更新状态 (例如:角度)
                currentAngle += 0.02;

                // 2. 计算矩阵
                let matrix = matrixUtils.createIdentity();
                // 注意乘法顺序:先缩放,再旋转,最后平移
                // matrix = matrixUtils.multiply(matrix, matrixUtils.createScale(1.0, 1.0));
                matrix = matrixUtils.multiply(matrix, matrixUtils.createRotation(currentAngle));
                matrix = matrixUtils.multiply(matrix, matrixUtils.createTranslation(0.5, 0.0));

                // 3. 绘制
                gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
                gl.clearColor(0.1, 0.1, 0.1, 1.0);
                gl.clear(gl.COLOR_BUFFER_BIT);

                // 将计算好的矩阵发送给顶点着色器
                // gl.uniformMatrix3fv(location, transpose, value)
                // transpose 必须是 false
                gl.uniformMatrix3fv(matrixUniformLocation, false, matrix);

                gl.drawArrays(gl.TRIANGLES, 0, 3);
                
                // 4. 请求下一帧
                requestAnimationFrame(animate);
            }

            // 启动动画!
            animate();
        }

        // --- 辅助函数 (与之前相同) ---
        function createShader(gl, type, source) { /* ... */ }
        function createProgram(gl, vertexShader, fragmentShader) { /* ... */ }
        // For brevity, I'm hiding the unchanged helper functions here.
        // They are the same as in the previous article.
        function createShader(gl, type, source) {const shader = gl.createShader(type); gl.shaderSource(shader, source); gl.compileShader(shader); if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) return shader; console.error("Shader compile error:", gl.getShaderInfoLog(shader)); gl.deleteShader(shader);}
        function createProgram(gl, vertexShader, fragmentShader) {const program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); if (gl.getProgramParameter(program, gl.LINK_STATUS)) return program; console.error("Program link error:", gl.getProgramInfoLog(program)); gl.deleteProgram(program); }

    </script>
</body>
</html>
总结与展望

太棒了!我们成功地让三角形“活”了起来。它先是围绕自己的中心旋转,然后作为一个整体平移到了画布的右半边。

今天我们解锁了 WebGL 中极为强大的能力:

  • 理解了变换的意义:将形状定义与位置状态分离,让控制更灵活。
  • 认识了矩阵:它是实现平移、旋转、缩放的数学工具,是 GPU 的“母语”。
  • 掌握了 uniform 变量:学会了如何向着色器传递对所有顶点都一致的全局数据。
  • 创建了动画循环:使用 requestAnimationFrame 让我们的场景动了起来。

现在,我们的 2D 图形已经相当完备了。但 WebGL 的魅力远不止于此。在下一篇中,我们将为我们的图形穿上华丽的“外衣”——纹理贴图。我们将学习如何加载一张图片,并把它精准地“贴”到我们的三角形表面上,让它不再是简单的颜色渐变。

准备好进入更丰富多彩的视觉世界了吗?敬请期待 《第 4 篇:赋予表面生命 - WebGL 纹理贴图》!

WebGL概述 WebGL标准是由科纳斯组织(Khronos Group)开发和维护,该组织还管理着OpenGL、COLLADA等。WebGL的官方描述:WebGL是免授权费的,跨平台的应用程序接口API。它将OpenGL ES 2.0作为在HTML网页内的3D绘图环境,作为低级别文档对象模型接口开放。它使用OpenGL渲染语言GLSL ES,并可整洁地与其他3D内容上层或下层的网页内容捆绑。它是使用JavaScript编程开发语法开发,适合动态3D网页应用的理想工具,并已被主流互联网浏览器集成。 阅读详情

相关推荐

基于HTML5 Canvas和WebGL实现图片的交互式几何变换

基于HTML5 Canvas和WebGL实现图片的交互式几何变换

Enjolras' Studio 5235

JavaScript 2D 3D 图形库API webGL

目录 WebGL MDN API 指南和教程 指南 教程 示例 高级教程 资源 库 规范 浏览器兼容性 WebGL 1 Legend WebGL 2 Legend 兼容性说明 Gecko备忘 参见 WebGL 中文版 多端阅读《WebGL 中文版》: 中文学习目录 WebGL (Web图形库) 是一种JavaScript API,用于在任何兼容的We...

纸上得来终觉浅,绝知此事要躬行 2755

WebGL入门与实践:构建交互式3D图形体验

WebGL(Web Graphics Library)是一种JavaScript API,用于在不需要插件的情况下在任何兼容的Web浏览器中渲染2D和3D图形。它是OpenGL ES的一个Web版本,使得Web开发人员可以在网页中实现复杂的图形处理,而无需依赖特定平台或插件,如Flash或Java。WebGL的出现,极大地推动了Web平台上的图形应用开发。在确定浏览器支持WebGL之后,开发者可以使用HTML5的<canvas>元素来获取WebGL渲染上下文。getContext。

weixin_42393362的博客 3375

WebGL2 Fundamentals矩阵数学详解:从2D变换到3D投影

WebGL2 Fundamentals是学习WebGL 2基础的优质开源项目,通过矩阵数学实现从2D变换到3D投影的核心功能,帮助开发者轻松掌握3D图形编程的关键技术。 ## 为什么矩阵数学是WebGL的核心? 在WebGL中,矩阵是实现图形变换的数学基础。无论是简单的2D位移、旋转和缩放,还是复杂的3D投影,都离不开矩阵运算。矩阵能够将多个变换组合成单一操作,极大简化了图形渲染流程。 ##

gitblog_01195的博客 855

WebGL长方体动态变换项目:旋转与缩放

WebGL(Web Graphics Library)是一种JavaScript API,它提供了一个用于在任何兼容的Web浏览器中无需插件就可以进行3D和2D图形渲染的标准方式。它将OpenGL ES 2.0的标准应用到了网页中,使得开发者能够在网页上绘制出复杂的图形。在现实世界中,要观察一个物体,需要一个相机或眼睛作为观察的起点。在WebGL中,虚拟相机用于定义观察世界的方式,它包含位置、朝向和视野范围等属性。虚拟相机的重要性在于,它决定了用户的观察视角,影响了3D场景的视觉效果和用户的交互体验。

weixin_42590539的博客 1244

WSL2+Ubuntu20.04纯root环境搭建指南:告别权限烦恼的终极方案

本文提供了一份详细的WSL2+Ubuntu20.04纯root环境搭建指南,旨在为本地开发与学习打造一个免去权限干扰、极致流畅的Linux子系统环境。通过启用WSL2、安装Ubuntu 20.04,并执行核心的root用户设置,开发者可以彻底告别频繁的sudo操作,提升在文件操作、容器调试和系统配置等方面的效率。

time3的博客 470

webgl纹理,变换,光照介绍

注意:上述代码案例是简化的示例,它们省略了 WebGL 上下文的设置、着色器的编译和链接、顶点数据的加载和渲染等步骤。在 WebGL 中,光照通常通过着色器中的光照模型来计算。此外,对于光照的实现,你还可以添加更多的光照类型(如点光源、聚光灯等)、光照属性(如强度、颜色等)以及光照效果(如镜面反射、阴影等),以实现更复杂和逼真的光照效果。模型矩阵:用于将模型的顶点坐标转换到世界坐标系中。

猿脑2.0的博客 1330

VMware Workstation Pro 17 最新破解版安装教程(附永久激活密钥)

本文详细介绍了VMware Workstation Pro 17专业版的安装与配置指南,包括系统要求检查、官方版本安装流程、高级配置优化及常见问题排查。通过合规使用官方版本,开发者可以充分利用其强大的虚拟化能力,提升多平台开发与测试效率。

weixin_29327977的博客 3412

使用 WebGL 创建 2D 内容

一旦创建 WebGL 上下文创建成功,你就可以在这个上下文里渲染画图了。而对我们而言最简单的事,莫过于绘制一个没有纹理的 2D 图形了。那就让我们从画出一个正方形开始吧。

qq_25547755的博客 1188

SAP中贸易伙伴的应用原理简析

公司也称为贸易伙伴,是出具合并报表的组织单位,可以为客户和供应商分配公司(贸易伙伴),用于识别集团内关闻公司间的业务往来,在编制合并报表时进行往来账务的计算处理。 如下图某贸易伙伴公司(关联方名称G0059)在我方公司的SAP系统中有多重身份(即是供应商,又是客户)。那么在我方公司SAP系统中建立起公司(贸易伙伴),并关联到供应商和客户主数据中。之后,就可以通过G0059这个贸易伙伴名称来识别与该贸易伙伴间的往来业务。 相应的配置设定如下: 定义公司(贸易伙伴或关联方) 会计凭证中会

专注SAP应用技术文章写作,致力于拉近用户与系统间的距离; 9808

SAP_SD模块路径及运输功能后台配置简介

后台路径:SPRO—后勤执行—装运—基本发运功能—定义路线—定义传输模式根据实际运输过程运输地理的类型:海运、公路运输、空运后台路径:SPRO—后勤执行—装运—基本发运功能—定义路线—定义发运类型根据实际运输过程运输方式:汽车、卡车、火车、轮船、飞机后台路径:SPRO—后勤执行—装运—基本发运功能—路径—定义路线—定义运输连接点指在运输过程中需要中转的地区可以维护中转地区的停留的时间后台路径:SPRO—后勤执行—装运—基本发运功能—路径—定义路线—定义路径和阶段。

我小时候很黑的博客 1388

【WebGL实战】1. 全流程实现与拆解:WebGL绘制2D图形

WebGL绘制2D图形的实战,全流程实现与拆解

同学小张的博客 1139

基于MATLAB的最大重叠离散小波变换(MODWT)算法详解

最大重叠离散小波变换(Maximal Overlap Discrete Wavelet Transform, MODWT)是DWT的重要改进形式,由Percival和Walden等人在20世纪90年代系统提出并完善。MODWT通过消除下采样操作,采用样本平移不变的分解方式,解决了DWT的多个固有缺陷。MODWT的核心创新在于取消下采样环节。与DWT每级分解后对滤波输出进行二分下采样不同,MODWT在每一级都使用相同的滤波器,但通过插入零值的方式调整滤波器系数,保持每级系数数量与原始信号相同。

qq_42212808的博客 112

第 5 篇:WebGL 从 2D 到 3D - 坐标系、透视与相机

本文介绍了从2D平面到3D空间的转换,重点讲解了WebGL中实现3D效果的核心技术。主要内容包括:1)引入Z轴构建三维坐标系;2)通过透视投影解决2D屏幕显示3D世界的问题;3)详解MVP矩阵(模型矩阵、视图矩阵、投影矩阵)的作用及其组合运算;4)处理深度遮挡问题的深度测试技术;5)实际演示如何创建一个旋转的3D立方体场景。文章通过理论结合实践的方式,系统阐述了3D渲染的基本原理和实现方法。

waws520的博客 1014

YOLOv9改进策略【Neck】| GSConv+Slim Neck:混合深度可分离卷积和标准卷积的轻量化网络设计

实时检测器架构的轻量级设计GsConv。

Limiiiing的博客 1360

【RKNN】RKNN(Rockchip Neural Network)​​ 的详解

RKNN 为 Rockchip 硬件提供了高效的 AI 推理解决方案,适合需要低功耗、实时响应的边缘场景

浩瀚之水的专栏 1670

WebGL原来如此:搞懂三维坐标系变换

三维渲染,顾名思义,就是要将多角度可观测的三维物体绘制到一个固定的二维矩形屏幕上,那么三维到二维是如何映射的呢?就是前面我说的对图形渲染最基础的认知———坐标系转换。 一起来搞懂三维渲染需要的MVP变换、视口变换...

FloraCat_染小白 3832

信捷PLC XD5系列运动控制(10轴)编程应用篇

项目PLC采用XD5-60T10-E,36DI 24DO 晶体管输出,支持10路脉冲输出功能。TMR指令定时器时基可以自己设定,这点比其他品牌PLC方便。ZRN指令我们需要上升沿指令触发。 5、变址寻址 该说不说这个变址寻址是真的强,比西门子指针、三菱的变址寄存器Z 、V都要更加灵活。 7、特殊寄存器:时钟 8、如何建立PLC通讯...............

RXXW_Dor的博客 1万+

WebGL 之创建 2D 内容

它的职责是确定像素的颜色,通过指定应用到像素的纹理元素(也就是图形纹理中的像素),获取纹理元素的颜色,然后将适当的光照应用于颜色。在观察者视图空间中,观察者(通常是摄像机)位于坐标系的原点,观察方向是坐标系的负Z轴方向,摄像机的朝向和位置决定了观察者视图空间的坐标系。:在顶点着色器中,顶点数据经过模型变换、视图变换和投影变换后,得到的坐标被称为裁剪空间坐标。这个范围内的坐标表示的是相对于视锥体(View Frustum)的位置,超出这个范围的坐标将被裁剪掉,不会显示在最终的图像中。

qq_35094120的博客 1084

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

webgl——图形的基本变换:平移、旋转、缩放并实践类似 threeJS 放大、拖拽效果(五)

文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例可供参考 一、pandas是什么? 首先需要将世界坐标转换为 webgl 中的坐标 [-1, 1] 的范围内,这会用到缩放、然后在 webgl 中如何放置,放在哪里;我们需要用到平移、旋转等。 二、使用步骤 1.引入库

jiegiser博客 1675

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

ICG-WebGL项目深度解析:基于WebGL的自顶向下图形学教程

ICG-WebGL项目是交互式计算机图形学领域的实践指南,基于"自顶向下方法"第七版教材开发,提供了丰富的WebGL示例与练习题。本项目通过直观的代码实现和清晰的视觉演示,帮助开发者从基础到进阶掌握WebGL图形编程技术,是学习计算机图形学的理想实践资源。 ## 📚 项目核心架构与目录解析 ICG-WebGL采用章节式组织架构,每个章节对应图形学的核心知识点,从基础渲染到复杂3D场景构建逐步

gitblog_01009的博客 797

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

WebGL vs Canvas2D:Kaetram Open如何优化2D游戏性能的技术实践

Kaetram Open是一款基于HTML5的开源2D MMORPG游戏,它作为BrowserQuest的扩展版本,在Web环境中实现了复杂的游戏场景渲染。本文将深入剖析Kaetram Open如何通过WebGL和Canvas2D两种渲染技术的灵活应用,解决2D游戏性能优化难题,为开发者提供可复用的技术实践方案。 ## 🚀 渲染技术双选择:WebGL与Canvas2D的博弈 在2D游戏开发中

gitblog_00426的博客 806

如何学习前端图形编程(如Canvas、WebGL)?

前端图形编程,特别是利用Canvas 2D、WebGL和新兴的WebGPU技术,为开发者打开了一扇通往丰富视觉世界的大门。本报告旨在为不同经验水平的学习者提供一条从入门到精通的系统化、结构化的学习路径,分析核心技术、主流工具以及未来的发展趋势。元素上进行绘制的,但它提供的是一个基于OpenGL ES的3D渲染上下文。掌握了框架的基本使用后,深入理解WebGL的高级特性将使你的作品效果和性能都提升一个档次。在踏上图形编程的征程之前,坚实的基础和正确的学习心态是成功的关键。WebGL本质上是在。

破损的天堂鸟博客 954

掌握WebGL图形学:ICG-WebGL项目实战指南

ICG-WebGL是基于《交互式计算机图形学——基于WebGL的自顶向下方法(第七版)》教材的现代WebGL学习项目,为计算机图形学开发者和学习者提供了一套完整的WebGL编程实践体系。该项目重构了官方示例代码,采用现代前端开发工具链,包含12个章节的完整示例和练习题实现,帮助开发者从零构建WebGL图形渲染技能。 ## 项目概览:现代WebGL学习框架 ICG-WebGL项目不仅是一个代码库

gitblog_00079的博客 613

【Web2D/3D】CSS3的2D/3D转换transform、过渡transistion、关键帧动画animation(第一篇)

本篇开始介绍Web2D和3D相关基础知识,会从CSS3的2D/3D转换、过渡、动画,讲到Canvas 2D图形绘制,再到SVG,最后到WebGL。

weixin_45620943的博客 1668

WebGL,真正进入三维的世界

一、在此之前 在之前的文章中,我想大家已经对WebGL有了一个大体的了解,不过为了凑字数,我在这篇文章的开头再稍微回顾一下,如果我们需要使用WebGL来绘制图像需要走完以下这五步: 1、从canvas元素中获取webgl context 2、利用GLSL ES语言,编写顶点着色器和片元着色器,并成对应的着色器程序 3、准备好你想要绘制的图像的顶点数据,并写入缓冲区 4、把着色器中的变量与...

hsany330的专栏 5821
上一篇: 为世界添彩 - WebGL 中的颜色与着色器变量
下一篇: 第 4 篇:赋予表面生命 - WebGL 纹理贴图
Zuckjet_
博客等级 码龄10年 56粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值