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
相关推荐
byzh_rc7 分钟前
[微机原理与系统设计-从入门到入土] 微型计算机基础
开发语言·javascript·ecmascript
m0_471199637 分钟前
【小程序】订单数据缓存 以及针对海量库存数据的 懒加载+数据分片 的具体实现方式
前端·vue.js·小程序
编程大师哥8 分钟前
Java web
java·开发语言·前端
A小码哥10 分钟前
Vibe Coding 提示词优化的四个实战策略
前端
Murrays10 分钟前
【React】01 初识 React
前端·javascript·react.js
大喜xi13 分钟前
ReactNative 使用百分比宽度时,aspectRatio 在某些情况下无法正确推断出高度,导致图片高度为 0,从而无法显示
前端
helloCat14 分钟前
你的前端代码应该怎么写
前端·javascript·架构
电商API_1800790524714 分钟前
大麦网API实战指南:关键字搜索与详情数据获取全解析
java·大数据·前端·人工智能·spring·网络爬虫
康一夏15 分钟前
CSS盒模型(Box Model) 原理
前端·css
web前端12316 分钟前
React Hooks 介绍与实践要点
前端·react.js