10、webgl 基本概念 + 坐标系统 + 立方体

基本概念

模型坐标

也常被称为局部空间或物体空间,是指一个三维模型在其自身坐标系下定义的顶点位置。
关键特性 :
独立性: 模型坐标完全不知道它将来会被放在场景的哪个位置,也不知道它会有多大,会如何旋转。

方便性: 对于建模者来说,这是最自然、最方便的坐标系统。他们只需关心物体本身的形状,无需考虑复杂的场景。

本质 :
模型: 指的是这个坐标系是专门为某个特定的模型(物体) 所定义的。

坐标: 指的是模型上各个顶点在这个专属坐标系下的位置信息。

所以,"模型坐标"直译就是"属于模型本身的坐标"。它强调的是坐标的"所有权"和"局部性"。

备注:在webgl 中,我们要先将模型坐标和 世界坐标系进行处理,让他们重合,这样可以减少计算量

世界坐标系

画布的坐标系统

观察坐标系(视图坐标系)

类似相机拍照时的可视范围,原点位置就是相机的位置。

对于相机位置的话,往前是 Z 轴,上面是 Y 轴,右边是 X 轴。

可视范围有两种情况(会影响展现的形状):

正摄投影:(理想的状态)展现的形状是不变的,还是物体本身的形状

透视投影:会根据相机的距离改变物体的局部大小。会有远小近大的感觉

视点与视线

视点:观察者所处的位置

视线:从视点触发沿着观察方向的射线

观察者默认状态

1、视点位于 webgl 坐标系统原点

2、视线为 z 轴负方向(向里)

可视空间

分类:

1、长方体可视空间,也称为盒状空间,由正射投影产生

2、四棱锥金字塔可视空间,由透视投影产生

例如正常眼睛的可视范围是一个扇形的区域

裁剪坐标系

没有在可视范围的点就会被裁剪,剩余的点就是裁剪坐标

立方体


html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <canvas width="500" height="500" id="myCanvas"></canvas>

    <script src="./cuon-matrix.js"></script>
    <script type="vertex" id="vertex">
        attribute vec3 a_position;
        attribute vec4 a_color;
        varying vec4 v_color;
        uniform mat4 u_Matrix;
        void main() {
            gl_Position = u_Matrix * vec4(a_position, 1);
            v_color = a_color;
        }
    </script>
    <script type="fragment" id="fragment">
        precision mediump float;
        varying vec4 v_color;
        void main() {
            gl_FragColor = v_color;
        }
    </script>
    <script>
        let myCanvas = document.getElementById("myCanvas");
        let gl = myCanvas.getContext("webgl");// IE8 之前的浏览器不兼容
        if(!gl) {
            alert("浏览器不支持 webgl!")
        }
        // 创建着色器
        function createShader(gl, type, source) {
            const shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);
            let isSuccess = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
            return isSuccess ? shader : console.log(gl.getShaderInfoLog(shader))
        }
        // 获取着色器中的文本内容字符串
        function getInnerText(id) {
            return document.getElementById(id).innerText;
        }
        const vertexStr = getInnerText("vertex");
        const fragmentStr = getInnerText("fragment");
        const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexStr)
        const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentStr);
        // 创建程序
        function createProgram(gl, vertexShader, fragmentShader) {
            let program = gl.createProgram();
            gl.attachShader(program, vertexShader);
            gl.attachShader(program, fragmentShader);
            gl.linkProgram(program);
            let isSuccess = gl.getProgramParameter(program, gl.LINK_STATUS);
            return isSuccess ? program : console.log(gl.getProgramInfoLog(program));
        }

        let program = createProgram(gl, vertexShader, fragmentShader);
        gl.useProgram(program);
        
        // 获取顶点着色器中变量
        let a_position = gl.getAttribLocation(program, 'a_position');
        let a_color = gl.getAttribLocation(program, 'a_color');
        let u_Matrix = gl.getUniformLocation(program, 'u_Matrix');
        
        let positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        let indexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
        gl.enable(gl.DEPTH_TEST); //深度检测
        // gl.enable(gl.CULL_FACE); // 隐藏背面

        let deg = 10
        function rotate() {
            let viewMatrix = new Matrix4();
            viewMatrix.setOrtho(-3, 3, -3, 3, -100, 100);
            let projectMatrix = new Matrix4();
            projectMatrix.setRotate(deg, 1, 1, 0);

            let matrix = viewMatrix.multiply(projectMatrix);
            gl.uniformMatrix4fv(u_Matrix, false, matrix.elements);
            draw()
        }
        // setInterval(() => {
        //     deg++
        //     rotate(deg)
        // },30)
        rotate()
        draw()
       
       function draw() {
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
        // 前
           
            -0.5, -0.5, -0.5, 1, 0, 0,
            0.5, -0.5, -0.5, 1, 0, 0,
            0.5, 0.5, -0.5, 1, 0, 0,
             -0.5, 0.5, -0.5, 1, 0, 0,

            // 后
             -0.5, -0.5, 0.5, 1, 0, 1,
            -0.5, 0.5, 0.5, 1, 0, 1,
            0.5, 0.5, 0.5, 1, 0, 1,
            0.5, -0.5, 0.5, 1, 0, 1,
           

            // 左
            -0.5, -0.5, 0.5, 1, 1, 0,
            -0.5, -0.5, -0.5, 1, 1, 0,
            -0.5, 0.5, -0.5, 1, 1, 0,
            -0.5, 0.5, 0.5, 1, 1, 0,
            

            // 右
            0.5, 0.5, -0.5, 0, 1, 0,
            0.5, -0.5, -0.5, 0, 1, 0,
            0.5, 0.5, 0.5, 0, 1, 0,
            0.5, -0.5, 0.5, 0, 1, 0,
            

            // 上面
            -0.5, 0.5, -0.5, 1, 0, 1,
            0.5, 0.5, -0.5, 1, 0, 1,
            0.5, 0.5, 0.5, 1, 0, 1,
            -0.5, 0.5, 0,5, 1, 0, 1,

            -0.5, -0.5, -0.5, 1, 0, 1,
            -0.5, -0.5, 0,5, 1, 0, 1,
            0.5, -0.5, 0.5, 1, 0, 1,
            0.5, -0.5, -0.5, 1, 0, 1,
        ]), gl.STATIC_DRAW);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([
            0, 1, 2,
            2, 3, 0,

            4, 5, 6,
            6, 7, 4,

            8, 9, 10,
            10, 11, 8,

            12, 13, 14,
            14, 15, 12,

            16, 17, 18,
            18, 19, 16,

            20, 21, 22,
            22, 23, 20,
        ]), gl.STATIC_DRAW);
        gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, 4 * 6, 0);
        gl.vertexAttribPointer(a_color, 3, gl.FLOAT, false, 4* 6, 4 * 3);
        // 启用这个位置数据
        gl.enableVertexAttribArray(a_position);
        gl.enableVertexAttribArray(a_color);
        // 绘制三角形
        gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
       }
    </script>
</body>
</html
相关推荐
溪语流沙15 分钟前
【每天一个CSS | Day08】整排按钮被鼠标吸走的磁吸导航
前端·css·计算机外设
wuyk55520 分钟前
Python实战项目05:JSON数据解析与数据可视化小案例|全套实战闭环
python·信息可视化·json
就叫年华吧丶25 分钟前
长文档点目录定位总是不准?一个 content-visibility + 平滑滚动引发的连环坑(Vue3 实战)
前端·javascript·算法·vue
茶栀(*´I`*)29 分钟前
【Python数据可视化】Matplotlib从零到精通:图表核心解剖、多子图布局与三大经典图表实战
python·信息可视化·matplotlib
JudithHuang32 分钟前
React 路由:React Router
前端·react.js·前端框架
赵得C33 分钟前
创建 SVG 图标预览页面:从零实现到解决 CORS 问题
前端·javascript·html
IT_陈寒39 分钟前
Java的HashMap线程安全问题让我深夜掉光了头发
前端·人工智能·后端
三掌柜66643 分钟前
ArkWeb 手记 04|Web 返回键别再一刀切
前端·harmonyos
光影少年1 小时前
RN与Flutter架构区别
前端·flutter·react native·react.js·架构·node.js
IT研究室1 小时前
最新大数据毕业设计选题推荐-基于大数据的生活指数分析与可视化-大数据-Spark-Hadoop-Bigdata
大数据·信息可视化·数据分析·spark·课程设计