首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【愚公系列】2023年08月 WEBGL专题-正射投影

【愚公系列】2023年08月 WEBGL专题-正射投影

作者头像
愚公搬代码
发布2025-05-28 16:58:46
发布2025-05-28 16:58:46
1660
举报
文章被收录于专栏:历史专栏历史专栏

前言

投影是指将三维空间中的对象或图形映射到二维平面上的过程。在计算机图形学中,投影是一个重要的概念,因为屏幕上只有二维的显示空间,需要将三维场景投影到屏幕上才能呈现给用户。投影有两种常见的方式:透视投影和正交投影。透视投影模拟了真实世界的视觉效果,使远处的物体更小,近处的物体更大,增强了视觉感受。而正交投影则是在平面上进行垂直投影,可以保留物体的大小和比例,但会失去深度感。无论是哪种投影方式,都需要计算投影矩阵来进行投影。

一、正射投影

1.概念

正射投影是指将三维物体投影到一个平面上时,投影线垂直于平面的投影方式。这意味着在正射投影中,所有的投影线都是平行的,因此物体的形状和大小将被保留,但是深度感会被忽略。正射投影常用于工程和建筑设计等领域中,用来表现物体的几何形状和尺寸。在计算机图形学中,正射投影也是一种常用的投影方式,常用于生成二维图像或进行裁剪操作。

正射投影是所有的物体投影线都垂直于最终的绘图表面。

正射投影就是把可视空间内的坐标映射到 x [-1,1], y [-1,1], z [-1,1] 的区间内。

2.推导过程

2.1 xyz矩阵换算

1、左右区间

使用 l 代替 left, 使用 r 代替 right

2、上下区间

3、远近区间

2.1 计算正射投影矩阵

3.案例

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="../lib/index.js"></script>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    canvas{
      margin: 50px auto 0;
      display: block;
      background: yellow;
    }
  </style>
</head>
<body>
  <canvas id="canvas" width="400" height="400">
    此浏览器不支持canvas
  </canvas>
</body>
</html>
<script>
  // 获取正射投影矩阵
  function getOrtho(l, r, t, b, n, f) {
    return new Float32Array([
      2 / (r - l), 0,           0,           0,
      0,           2/(t-b),     0,           0,
      0,           0,           -2/(f-n),    0,
      -(r+l)/(r-l),-(t+b)/(t-b),-(f+n)/(f-n),1
    ])
  }
  const ctx = document.getElementById('canvas')

  const gl = ctx.getContext('webgl')

  // 创建着色器源码
  const VERTEX_SHADER_SOURCE = `
    attribute vec4 aPosition;
    uniform mat4 mat;
    void main() {
      gl_Position = mat * aPosition;
      gl_PointSize = 10.0;
    }
  `; // 顶点着色器

  const FRAGMENT_SHADER_SOURCE = `
    void main() {
      gl_FragColor = vec4(1.0,0.0,0.0,1.0);
    }
  `; // 片元着色器

  const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)

  const aPosition = gl.getAttribLocation(program, 'aPosition');
  const mat = gl.getUniformLocation(program, 'mat');

  const points = new Float32Array([
    -0.5, -0.5,
     0.5, -0.5,
     0.0,  0.5,
  ])

  const buffer = gl.createBuffer();

  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);

  gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);

  gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);

  gl.enableVertexAttribArray(aPosition)

  let eyey = -0.1;
  function animation() {
    eyey += 0.01;
    if (eyey > 1) {
      eyey = -0.1;
    }

    const vm = getViewMatrix(0.0,eyey,0.2,0.0,0.0,0.0,0.0,0.6,0.0);
    const ortho = getOrtho(-1,1,1,-1,0,20);
    // const matrix = getTranslateMatrix(x, x);
    // gl.vertexAttrib1f(aTranslate, x);
    gl.uniformMatrix4fv(mat, false, mixMatrix(vm, ortho));
    gl.drawArrays(gl.TRIANGLES, 0, 3);

    requestAnimationFrame(animation);
  }

  animation()

</script>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-08-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一、正射投影
    • 1.概念
    • 2.推导过程
      • 2.1 xyz矩阵换算
      • 2.1 计算正射投影矩阵
    • 3.案例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档