webgl入门到成仙【入门-04wegbl的实际绘图思路】

本文介绍了webgl的绘图思路,包括webgl渲染引擎、程序对象、上下文对象的作用,以及绘图步骤。讲解了顶点着色器和片元着色器的功能,如描述顶点位置、颜色和进行逐片元处理。同时,阐述了不同绘制模式的使用,并以两点确定直线为例,解释了顶点与片元的关系。
摘要由CSDN通过智能技术生成

04webgl的实际绘图思路

知识点

webgl的绘图思路

  1. 找一台电脑
    • 浏览器里内置的webgl渲染引擎,负责渲染webgl图形,只认GLSL ES语言
  2. 找一块手绘板
    • 程序对象,承载GLSL ES语言,翻译GLSL ES语言和js语言,使两者相互童心
  3. 找一只触控笔
    • 通过canvas获取的webgl类型的上下文对象,可以向手绘板传递绘图命令,并接收手绘板的状态信息
  4. 开始画画
    • 通过webgl类型的上下文对象,用js画画

webgl的绘图步骤

  1. 在html中建立canvas画布

  1. 在js中获取画布

const canvas = document.querySelector("#canvas")

  1. 使用canvas获取webgl上下文

const gl = canvas.getContext(“webgl”)

  1. 在script中建立顶点着色器和片元着色器,用的是glsl es语言
    • 顶点着色器:描述顶点的特征,如位置、颜色等。
      • gl_Position = vec4(0.0, 0.0, 0.0, 1.0);表示点的位置,默认参数为0, 0, 0, 1
        • 第一个参数代表x轴,负数向左,正数向右,如果-1,代表点的中心在画布最左侧,如果1,代表点的中心在画布最右侧
        • 第二个参数代表y轴,负数向下,正数向上,如果-1,达标点的中心在画布最下方,如果1,代表点的中心在画布最上方
        • 第三个参数代表z轴,表示远近
          (后面会讲)
    • 片元着色器:进行逐片元处理,如光照。
    <!-- 顶点着色器 -->
    <script id="vertexShader" type="x-shader/x-vertex">
        void main() {
            // 点位,单词gl_Position是写死的,专门用于接收点位的,后面要写分号
            gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
            // 点的尺寸,单词gl_PointSize写死的,值一定是浮点,后面要写分号
            gl_PointSize = 100.0;
        }
    <\/script>
    <!-- 片元着色器 -->
    <script id="fragmentShader" type="x-shader/x-fragment">
        void main() {
            // 片元,单词gl_FragColor写死的,
            gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); // 黄色
        }
    <\/script>
  1. 在js中获取顶点着色器和片元着色器的文本
    - 目的:用于后面初始化着色器
    - 方法:获取顶点着色器和片元着色器的script的两个DOM元素,然后获取innerText
    - 返回值:顶点着色器和片元着色器的script中的两段viod main函数
    // 获取着色器的文本,获取着色器文本的目的是用于后面初始化着色器
    // 获取顶点着色器文本
    const vsSource = document.querySelector("#vertexShader").innerText;
    // 获取片元着色器文本
    const fsSource = document.querySelector("#fragmentShader").innerText;
    ```
6. 初始化着色器
    - 初始化着色器的功能:解析着色器文本,整合到程序对象,关联webgl上下文对象,实现两种语言的相互通信
```go
    initShaders(gl, vsSource, fsSource);
    // 注意:这个initShaders函数是要自己实现的,如下
    function initShaders(gl,vsSource,fsSource){
        //创建程序对象
        const program = gl.createProgram();
        //建立着色对象
        const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
        const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
        //把顶点着色对象装进程序对象中
        gl.attachShader(program, vertexShader);
        //把片元着色对象装进程序对象中
        gl.attachShader(program, fragmentShader);
        //连接webgl上下文对象和程序对象
        gl.linkProgram(program);
        //启动程序对象
        gl.useProgram(program);
        //将程序对象挂到上下文对象上
        gl.program = program;
        return true;
    }

    function loadShader(gl, type, source) {
        //根据着色类型,建立着色器对象
        const shader = gl.createShader(type);
        //将着色器源文件传入着色器对象中
        gl.shaderSource(shader, source);
        //编译着色器对象
        gl.compileShader(shader);
        //返回着色器对象
        return shader;
    }
  1. 指定将要用来清空绘图区的颜色
    gl.clearColor(0, 0, 0, 1)这里设置底色Wie黑色
  2. 使用之前设定的颜色,清空绘图区
    gl.clear(gl.COLOR_BUFFER_BIT)
  3. 绘制顶点
    • gl.drawArrays(mode, FIRST, COUNT)
      • mode代表绘制方式,具体方式如下:
        • gl.POINTS 绘制一系列点
        • gl.LINE_STRIP 绘制一个线条。即绘制一系列线段,上一点链接下一点
        • gl.LINE_LOOP 绘制一个线圈。即绘制一系列线段,上一个点链接下一个点,并且最后一点与第一个点相连
        • gl.LINES 绘制一系列单独线段。每两个点作为端点,线段之间不连接
        • gl.TRIANGLE_STRIP 绘制一个三角带
        • gl.TRIANGLE_FAN 绘制一个三角扇
        • gl.TRIANGLES 绘制一系列三角形。每三个点作为定点
      • FIRST
        • Glint类型,代表指定从哪个点开始绘制
      • COUNT
        • GLsizei类型,代表指定绘制需要使用到多少个点
          gl.drawArrays(gl.POINTS, 0, 1)

webgl绘图需要两种着色器:
- 顶点着色器(Vertex shader):描述定点的特征,比如位置。颜色等
- 片元着色器(Fragment shader):进行片元处理,如光照
- webgl中的片元就是像素的意思
举例说明:
两点决定一条直线,两个点就是顶点着色器的顶点,把直线画到画布上后,两个点之间构成的每个像素就是片元

代码

<!--
 * @Author: 俞华
 * @Date: 2021-02-28 23:06:22
 * @LastEditors: 俞华
 * @LastEditTime: 2021-03-01 22:06:42
 * @CSDN_BLOG: https://blog.csdn.net/qq_17175013
 * @wechat: 809742006
-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>01-刷底色</title>
    <style>
        body{
            margin: 0;
            overflow: hidden;
        }
        #canvas{
            background-color: red;
        }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertexShader" type="x-shader/x-vertex">
        void main() {
            // 设置点位,单词gl_Position是写死的,专门用于接收点位的,后面要写分号
            gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
            // 点的尺寸,单词gl_PointSize写死的,值一定是浮点,后面要写分号
            gl_PointSize = 50.0;
        }
    </script>
    <!-- 片元着色器 -->
    <script id="fragmentShader" type="x-shader/x-fragment">
        void main() {
            // 片元,单词gl_FragColor写死的,这句代码的意思是设置片元的颜色
            gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); // 黄色
        }
    </script>
    <script type="module">
        /*
            webgl的绘图思路
            1. 找一台电脑
                - 浏览器里内置的webgl渲染引擎,负责渲染webgl图形,只认GLSL ES语言
            2. 找一块手绘板
                - 程序对象,承载GLSL ES语言,翻译GLSL ES语言和js语言,使两者相互童心
            3. 找一只触控笔
                - 通过canvas获取的webgl类型的上下文对象,可以向手绘板传递绘图命令,并接收手绘板的状态信息
            4. 开始画画
                - 通过webgl类型的上下文对象,用js画画
            
            webgl的绘图步骤
            1. 在html中建立canvas画布
            > <canvas id="canvas"></canvas>
            2. 在js中获取画布
            > const canvas = document.querySelector("#canvas")
            3. 使用canvas获取webgl上下文
            > const gl = canvas.getContext("webgl")
            4. 在script中建立顶点着色器和片元着色器,用的是glsl es语言
                - 顶点着色器:描述顶点的特征,如位置、颜色等。
                    - gl_Position = vec4(0.0, 0.0, 0.0, 1.0);表示点的位置,默认参数为0, 0, 0, 1
                        - 第一个参数代表x轴,负数向左,正数向右,如果-1,代表点的中心在画布最左侧,如果1,代表点的中心在画布最右侧
                        - 第二个参数代表y轴,负数向下,正数向上,如果-1,达标点的中心在画布最下方,如果1,代表点的中心在画布最上方
                        - 第三个参数代表z轴,表示远近
                        (后面会讲)
                - 片元着色器:进行逐片元处理,如光照。
            ```html
                <!-- 顶点着色器 -->
                <script id="vertexShader" type="x-shader/x-vertex">
                    void main() {
                        // 点位,单词gl_Position是写死的,专门用于接收点位的,后面要写分号
                        gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
                        // 点的尺寸,单词gl_PointSize写死的,值一定是浮点,后面要写分号
                        gl_PointSize = 100.0;
                    }
                <\/script>
                <!-- 片元着色器 -->
                <script id="fragmentShader" type="x-shader/x-fragment">
                    void main() {
                        // 片元,单词gl_FragColor写死的,
                        gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); // 黄色
                    }
                <\/script>
            ```
            5. 在js中获取顶点着色器和片元着色器的文本
                    - 目的:用于后面初始化着色器
                    - 方法:获取顶点着色器和片元着色器的script的两个DOM元素,然后获取innerText
                    - 返回值:顶点着色器和片元着色器的script中的两段viod main函数
            ```go
                // 获取着色器的文本,获取着色器文本的目的是用于后面初始化着色器
                // 获取顶点着色器文本
                const vsSource = document.querySelector("#vertexShader").innerText;
                // 获取片元着色器文本
                const fsSource = document.querySelector("#fragmentShader").innerText;
                ```
            6. 初始化着色器
                - 初始化着色器的功能:解析着色器文本,整合到程序对象,关联webgl上下文对象,实现两种语言的相互通信
            ```go
                initShaders(gl, vsSource, fsSource);
                // 注意:这个initShaders函数是要自己实现的,如下
                function initShaders(gl,vsSource,fsSource){
                    //创建程序对象
                    const program = gl.createProgram();
                    //建立着色对象
                    const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
                    const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
                    //把顶点着色对象装进程序对象中
                    gl.attachShader(program, vertexShader);
                    //把片元着色对象装进程序对象中
                    gl.attachShader(program, fragmentShader);
                    //连接webgl上下文对象和程序对象
                    gl.linkProgram(program);
                    //启动程序对象
                    gl.useProgram(program);
                    //将程序对象挂到上下文对象上
                    gl.program = program;
                    return true;
                }

                function loadShader(gl, type, source) {
                    //根据着色类型,建立着色器对象
                    const shader = gl.createShader(type);
                    //将着色器源文件传入着色器对象中
                    gl.shaderSource(shader, source);
                    //编译着色器对象
                    gl.compileShader(shader);
                    //返回着色器对象
                    return shader;
                }
            ```
            7. 指定将要用来清空绘图区的颜色
            `gl.clearColor(0, 0, 0, 1)`这里设置底色Wie黑色
            8. 使用之前设定的颜色,清空绘图区
            `gl.clear(gl.COLOR_BUFFER_BIT)`
            9. 绘制顶点
                - gl.drawArrays(mode, FIRST, COUNT)
                    - mode代表绘制方式,具体方式如下:
                        - gl.POINTS 绘制一系列点
                        - gl.LINE_STRIP  绘制一个线条。即绘制一系列线段,上一点链接下一点
                        - gl.LINE_LOOP  绘制一个线圈。即绘制一系列线段,上一个点链接下一个点,并且最后一点与第一个点相连
                        - gl.LINES 绘制一系列单独线段。每两个点作为端点,线段之间不连接
                        - gl.TRIANGLE_STRIP  绘制一个三角带
                        - gl.TRIANGLE_FAN  绘制一个三角扇
                        - gl.TRIANGLES 绘制一系列三角形。每三个点作为定点
                    - FIRST
                        - Glint类型,代表指定从哪个点开始绘制
                    - COUNT
                        - GLsizei类型,代表指定绘制需要使用到多少个点
            `gl.drawArrays(gl.POINTS, 0, 1)`

            webgl绘图需要两种着色器:
                - 顶点着色器(Vertex shader):描述定点的特征,比如位置。颜色等
                - 片元着色器(Fragment shader):进行片元处理,如光照
                    - webgl中的片元就是像素的意思
            举例说明:
                两点决定一条直线,两个点就是顶点着色器的顶点,把直线画到画布上后,两个点之间构成的每个像素就是片元
        */
        import { initShaders } from "../jsm/Utils.js"
        const canvas = document.querySelector("#canvas");
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        // 获取着色器的文本,获取着色器文本的目的是用于后面初始化着色器
        // 获取顶点着色器文本
        const vsSource = document.querySelector("#vertexShader").innerText;
        // 获取片元着色器文本
        const fsSource = document.querySelector("#fragmentShader").innerText;
        console.log(vsSource, fsSource);

        // 三维画笔
        const gl = canvas.getContext("webgl");

        // 初始化着色器
        // 初始化着色器的功能:解析着色器文本,整合到程序对象,关联webgl上下文对象,实现两种语言的相互通信
        initShaders(gl, vsSource, fsSource);
        // 声明底色颜色
        gl.clearColor(0, 0, 0, 1);
        // 刷底色
        gl.clear(gl.COLOR_BUFFER_BIT);
        // 绘制顶点
        gl.drawArrays(gl.POINTS, 0, 1);// 第一个参数是绘制方式,可以用点、线或面来绘制,第二个参数是从哪里开始画,第三个参数表示画的个数
        
        
        
         
    </script>
</body>
</html>

jsm文件夹下的Utils.js代码

function initShaders(gl,vsSource,fsSource){
    //创建程序对象
    const program = gl.createProgram();
    //建立着色对象
    const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
    const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
    //把顶点着色对象装进程序对象中
    gl.attachShader(program, vertexShader);
    //把片元着色对象装进程序对象中
    gl.attachShader(program, fragmentShader);
    //连接webgl上下文对象和程序对象
    gl.linkProgram(program);
    //启动程序对象
    gl.useProgram(program);
    //将程序对象挂到上下文对象上
    gl.program = program;
    return true;
}

function loadShader(gl, type, source) {
    //根据着色类型,建立着色器对象
    const shader = gl.createShader(type);
    //将着色器源文件传入着色器对象中
    gl.shaderSource(shader, source);
    //编译着色器对象
    gl.compileShader(shader);
    //返回着色器对象
    return shader;
}

export {
    initShaders
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值