Three.js中文网 Three.js中文网
首页
免费视频
系统课 (opens new window)
  • Three.js基础课程
  • Vue3+Threejs 3D可视化
  • Threejs进阶课程
  • 展厅3D预览漫游
  • Threejs Shader
  • Blender建模基础
  • 文章
WebGPU教程
  • WebGL教程
  • ES GLSL着色器语言
  • WebGL教程(旧版本)
3D案例
  • 本站部署(打开快) (opens new window)
  • 原官网文档 (opens new window)
首页
免费视频
系统课 (opens new window)
  • Three.js基础课程
  • Vue3+Threejs 3D可视化
  • Threejs进阶课程
  • 展厅3D预览漫游
  • Threejs Shader
  • Blender建模基础
  • 文章
WebGPU教程
  • WebGL教程
  • ES GLSL着色器语言
  • WebGL教程(旧版本)
3D案例
  • 本站部署(打开快) (opens new window)
  • 原官网文档 (opens new window)
Web3D系统课程视频
  • 1. WebGL绘制一个点(HTML框架文件)
    • 2. WebGL绘制一个矩形
    • 3. WebGL坐标系(投影)
    • 4. WebGL平移变换
    • 5. 绘制一个立方体(WebGL旋转变换)
    • 6. WebGL顶点索引绘制
    • 7. varying变量和颜色插值
    • 8. 立方体(每个面一种颜色)
    • 9. WebGL光照渲染立方体
    • 10 .立方体旋转动画
    • 11. WebGL绘制多个几何体
    • 12. 纹理贴图
    • 13. 彩色图转灰度图
    • 14. 切换着色器程序
    • 15. WebGL透明度与α融合
    • 16. 深度测试与α融合
    • WebGL教程-原旧版本
    郭隆邦
    2026-05-22
    目录

    1. WebGL绘制一个点(HTML框架文件)

    # WebGL绘制一个点

    通过WebGL可以渲染出来各种各样酷炫的3D效果,但是考虑到WebGL复杂性,为了大家降低初学难度,下面的代码仅仅在Canvas画布上绘制了一个点,对WebGL的整个绘图渲染流程进行了完整的演示,麻雀虽小,五脏俱全。

    # 学习建议

    本节课你不需要刻意去记忆具体知识,对于暂时不理解的小细节可以跳过,先有个整体印象即可,可以把全部代码复制到编辑器中,根据课程对相关知识模块的介绍,尝试更改几个参数,体验一下渲染效果。

    在后面的学习中,都可以在本节课源码的基础上进行增删代码即可,初学WebGL没必要每一行代码都要自己去敲出来。

    本课程风格和大多数课程风格不同,注意一定要结合案例代码学习,在案例代码的基础上调试体验总结,就像做化学实验一样,不要仅仅阅读文字。

    # 关键词

    • 超文本语言HTML
    • 脚本语言Javascript
    • Canvas画布
    • 着色器语言GLSL ES
    • WebGL API

    关于HTML/CSS/JavaScript不再进行过多的介绍,默认你有一定的前端基础,下面结合WebGL绘制点的代码,对Canvas画布、着色器语言GLSL ES和WebGL API相关知识进行简单介绍。

    # WebGL绘制一个点(.html文件完整源码)

    1    <!DOCTYPE html>
    2    <html lang="en">
    3    <head>
    4        <meta charset="UTF-8">
    5        <title>使用WebGL绘制一个点</title>
    6    </head>
    7    <body>
    8    <!--canvas标签创建一个宽高均为500像素,背景为蓝色的矩形画布-->
    9    <canvas id="webgl" width="500" height="500" style="background-color: blue"></canvas>
    10   
    11   
    12   <script>
    13       //通过getElementById()方法获取canvas画布
    14       var canvas=document.getElementById('webgl');
    15       //通过方法getContext()获取WebGL上下文
    16       var gl=canvas.getContext('webgl');
    17   
    18       //顶点着色器源码
    19       var vertexShaderSource = '' +
    20           'void main(){' +
    21           //给内置变量gl_PointSize赋值像素大小
    22           '   gl_PointSize=20.0;' +
    23           //顶点位置,位于坐标原点
    24           '   gl_Position =vec4(0.0,0.0,0.0,1.0);' +
    25           '}';
    26   
    27       //片元着色器源码
    28       var fragShaderSource = '' +
    29           'void main(){' +
    30           //定义片元颜色
    31           '   gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
    32           '}';
    33   
    34       //初始化着色器
    35       var program = initShader(gl,vertexShaderSource,fragShaderSource);
    36       //开始绘制,显示器显示结果
    37       gl.drawArrays(gl.POINTS,0,1);
    38   
    39       //声明初始化着色器函数
    40       function initShader(gl,vertexShaderSource,fragmentShaderSource){
    41           //创建顶点着色器对象
    42           var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    43           //创建片元着色器对象
    44           var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    45           //引入顶点、片元着色器源代码
    46           gl.shaderSource(vertexShader,vertexShaderSource);
    47           gl.shaderSource(fragmentShader,fragmentShaderSource);
    48           //编译顶点、片元着色器
    49           gl.compileShader(vertexShader);
    50           gl.compileShader(fragmentShader);
    51   
    52           //创建程序对象program
    53           var program = gl.createProgram();
    54           //附着顶点着色器和片元着色器到program
    55           gl.attachShader(program,vertexShader);
    56           gl.attachShader(program,fragmentShader);
    57           //链接program
    58           gl.linkProgram(program);
    59           //使用program
    60           gl.useProgram(program);
    61           //返回程序program对象
    62           return program;
    63       }
    64   </script>
    65   </body>
    66   </html>
    

    # 创建Canvas画布

    创建一个Canvas画布,用于显示WebGL的渲染结果,canvas元素和div等元素一样是HTML的一个元素,只是Canvas画布具有2D和3D绘图功能。

    <!--canvas标签创建一个宽高均为500像素,背景为蓝色的矩形画布-->
    <canvas id="webgl" width="500" height="500" style="background-color: blue"></canvas>
    

    通过JavaScript获取上面创建的Canvas元素返回一个Canvas对象。

    //通过getElementById()方法获取canvas画布对象
    var canvas= document.getElementById('webgl')
    

    canvas对象也可以不通过<canvas>标签创建,然后id方式获取,也可以通过DOM直接创建

    //通过getElementById()方法获取canvas画布对象
    var canvas = document.createElement('canvas');
    

    # Canvas对象方法.getContext()

    HTML的Canvas元素提供了2D和3D绘图两种功能,平时程序员之间交流所说的Canvas一词就是指Canvas的2D绘图功能,通过Canvas元素实现的3D绘图功能,也就是所谓的WebGL,或者说WebGL依赖于Canvas元素实现。

    执行canvas.getContext('2d')返回对象具有一系列绘制二维图形的方法,比如绘制直线、圆弧等API。关于canvas 2D绘图相关内容,本课程不介绍,可以百度关键词Canvas,

    //通过方法getContext()获取Canvas 2D绘图上下文
    var c =canvas.getContext('2d');
    c.moveTo(0,0);//直线起点坐标
    c.lineTo(50,50);//直线第2个点坐标
    c.lineTo(0,100);//直线第3个点坐标
    c.stroke();//把点连成直线绘制出来
    

    执行canvas.getContext('webgl');返回对象具有一系列绘制渲染三维场景的方法,也就是WebGL API。

    //通过方法getContext()获取WebGL上下文
    var gl=canvas.getContext('webgl');
    ...
    //调用WebGL API绘制渲染方法drawArrays
    gl.drawArrays(gl.POINTS,0,1);
    ...
    

    # 着色器语言GLSL ES

    下面代码中的两个字符串vertexShaderSource和fragShaderSource是WebGL的着色器代码,着色器代码通过着色器语言GLSL ES编写,对于前端工程来说学习WebGL,还需要学习一门新的语言着色器语言GLSL ES。关于着色器语言的学习,可以跟着课程一边写案例,一边去学习,这样更容易理解。

    着色器语言用于计算机图形编程,运行在GPU中,平时所说的大多数语言编写的程序都是运行在CPU中。 与OpenGL API相配合的是着色器语言GLSL,与OpenGL ES API、WebGL API相互配合的是着色器语言GLSL ES。OpenGL标准应用的是客户端 OpenGL ES应用的是移动端,WebGL标准应用的是浏览器平台。

    顶点着色器和片元着色器经过WebGL编译处理后,会在GPU的顶点着色器单元和片元着色器单元上执行。

    顶点着色器定义了顶点的渲染位置和点的渲染像素大小

    //顶点着色器源码
    var vertexShaderSource = '' +
        'void main(){' +
        //给内置变量gl_PointSize赋值像素大小
        '   gl_PointSize=20.0;' +
        //顶点位置,位于坐标原点
        '   gl_Position =vec4(0.0,0.0,0.0,1.0);' +
        '}';
    

    片元着色器定义了点的渲染结果像素的颜色值

    //片元着色器源码
    var fragShaderSource = '' +
        'void main(){' +
        //定义片元颜色
        '   gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
        '}';
    

    gl_PointSize、gl_Position、gl_FragColor都是内置变量,也就是说不需要声明,这一点与多数编程语言不同,这主要是由GPU的特殊性决定,感兴趣的话 可以研究显卡的硬件结构,渲染管线等概念。

    通过程序可以看出来顶点着色器源码vertexShaderSource、片元着色器源码fragShaderSource,都是只有一个主函数main,也就是入口函数。

    给内置变量gl_Position赋值vec4(0.0,0.0,0.0,1.0),也就是设置顶点位置坐标,vec4代表的是一种数据类型, 在这里可以理解为vec4()是一个可以构造出vec4类型数据的构造函数,前三个参数表示顶点坐标值xyz。

    给内置变量gl_FragColor赋值vec4(1.0,0.0,0.0,1.0),也就是设置会在屏幕上显示的像素的颜色,vec4()构造函数 前三个参数,表示颜色RGB值,最后一个参数是透明度A。在WebGL着色器中颜色值使用[0,1]区间表示。

    你可以通过改变WebGL着色器代码内置变量gl_PointSize、gl_Position、gl_FragColor测试WebGL渲染效果的变化。

    • gl_PointSize=20.0改为gl_PointSize=10.0,观察屏幕点的大小变化

    • gl_Position =vec4(0.5,0.5,0.0,1.0)改为gl_Position =vec4(0.5,0.5,0.0,1.0),观察屏幕点的位置变化

    gl_FragColor=vec4(0.0,0.0,1.0,1.0)更改为gl_FragColor = vec4(0.0,0.0,1.0,1.0),观察屏幕点的颜色变化

    # WebGL API

    一句话来描述,WebGL API指的就是gl=canvas.getContext('webgl')返回对象gl的一系列绘制渲染方法,通过WebGL API可以把一个三维场景绘制渲染出来。比如上面代码中gl.createShader()、gl.shaderSource()、gl.drawArrays()等方法就是WebGl API。

    WebGL API多数与GPU硬件相关,控制相关图形处理单元,比如说通过gl.createShader()、gl.shaderSource()等方法可以对着色器代码进行编译,然后在GPU的着色器单元上执行;比如说drawArrays不执行,GPU渲染管线的顶点、片元着色器是不会把顶点坐标转化为显示器上的像素显示出来。

    如果你有 数字电路的知识,可编程芯片不仅仅只有GPU,针对不同的应用情形,都有特定的可编程芯片,图形处理用到的是可编程GPU,也就是说可以运行程序。处理声音是声卡,处理图像是显卡,自然而然它们 都会以CPU为核心,接受CPU的调度。以上描述在有些地方可能不太严谨,大家也不必记忆,主要目的是让大家有基本的认识,可以更好的编写程序。GPU相比CPU最大的特点是并行计算,不过WebGL API都 进行了封装,如果你想学习并行计算可以关注CUDA或OpenCL。GPU硬件(渲染管线)、显卡驱动、操作系统、浏览器、WebGL API是逐层抽象的。每一层都会为上一层提供一个接口,这里可以看出WebGL API是 首先通过浏览器的的解析,才能够经过一系列层驱动GPU工作,生成像素缓存,显示器会按照一定的频率扫描像素缓存,最终显示出来。

    # 初始化着色器函数initShader()

    关于着色器函数initShader()中封装的WebGL API代码,案例代码中都进行了注释,可以先简单阅读一下,具体的细节可以先不去学习,当成一个黑箱处理,你只需要知道通过initShader()函数可以完成着色器代码的编译,然后在GPU上执行。

    初始化着色器函数initShader(),主要是把顶点着色器源代码vertexShaderSource, 片元着色器源代码fragShaderSource,进行编译处理,然后顶点着色器代码在GPU的顶点着色器单元执行,片元着色器代码在GPU的片元着色器单元执行。

    //声明初始化着色器函数
    function initShader(gl,vertexShaderSource,fragmentShaderSource){
        //创建顶点着色器对象
        var vertexShader = gl.createShader(gl.VERTEX_SHADER);
        //创建片元着色器对象
        var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
        //引入顶点、片元着色器源代码
        gl.shaderSource(vertexShader,vertexShaderSource);
        gl.shaderSource(fragmentShader,fragmentShaderSource);
        //编译顶点、片元着色器
        gl.compileShader(vertexShader);
        gl.compileShader(fragmentShader);
    
        //创建程序对象program
        var program = gl.createProgram();
        //附着顶点着色器和片元着色器到program
        gl.attachShader(program,vertexShader);
        gl.attachShader(program,fragmentShader);
        //链接program
        gl.linkProgram(program);
        //使用program
        gl.useProgram(program);
        //返回程序program对象
        return program;
    }
    

    # 绘制方法gl.drawArrays()

    gl.drawArrays()方法的作用就是通知GPU执行着色器代码,然后根据着色器代码在Canvas画布上进行渲染绘制。

    # 着色器代码放在script标签中

    WebGL着色器代码在JavaScript中以字符串的形式存在,编写代码比较麻烦,为了编写方便,可以把着色器代码写在script或者其他HTML元素标签中,然后通过元素.innerText属性获得元素中的字符串,也就是着色器的代码。

    在原来WebGL绘制一个点的代码基础上进行更改

    <!-- 顶点着色器源码 -->
    <script id="vertexShader" type="x-shader/x-vertex">
      void main() {
        //给内置变量gl_PointSize赋值像素大小
        gl_PointSize=20.0;
        //顶点位置,位于坐标原点
        gl_Position =vec4(0.0,0.0,0.0,1.0);
      }
    </script>
    <!-- 片元着色器源码 -->
    <script id="fragmentShader" type="x-shader/x-fragment">
      void main() {
        gl_FragColor = vec4(1.0,0.0,0.0,1.0);
      }
    </script>
    
    //顶点着色器源码
    var vertexShaderSource = document.getElementById('vertexShader').innerText;
    //片元着色器源码
    var fragShaderSource = document.getElementById('fragmentShader').innerText;
    //初始化着色器
    var program = initShader(gl,vertexShaderSource,fragShaderSource);
    
    2. WebGL绘制一个矩形

    2. WebGL绘制一个矩形→

    Theme by Vdoing | Copyright © 2016-2026 豫ICP备16004767号-2
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式