当前位置: 首页 > article >正文

前端 -- 计算机图形学基础:光与三角形面(Mesh)求交

全文目录:

    • 开篇语
    • 🌈 前言
    • 📖 目录
    • 🎨 基本概念
      • 💡 光线是什么?
      • 🛠️ Mesh(三角形面)是什么?
      • 🎯 为什么需要光与 Mesh 求交?
    • 📐 数学基础
      • 1️⃣ 光线的表示方式
      • 2️⃣ 三角形面的数学表达
      • 3️⃣ 光线与三角形求交的算法
        • 基本步骤:
    • 🛠️ 实践案例:光与三角形求交的实现
      • 🌟 基本代码实现
      • 💡 优化思路与扩展
    • 🎁 拓展知识:光追与 Mesh 求交的高级应用
    • 🎉 总结与感悟
    • 文末

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

🌈 前言

Hello,小伙伴们!👋 有没有想过,为什么 3D 游戏里的光线可以那么炫酷地穿梭、反射,甚至投影?光的路径和三角形面的交点计算,构成了计算机图形学的核心基础。听起来高深莫测?别担心,我今天就用最简单的语言,带你走进 光与三角形面(Mesh)求交 的世界!

什么是光与 Mesh 求交?简单来说,就是 “光射到物体上,它和物体的形状(Mesh)在什么位置相遇”。这个问题的答案,广泛应用于 3D 渲染、游戏开发和物理引擎中,可以说是让画面看起来“真实”的关键所在。

让我们开始探索吧!✨


📖 目录

  1. 🎨 基本概念
    • 光线是什么?
    • Mesh(三角形面)是什么?
    • 为什么需要光与 Mesh 求交?
  2. 📐 数学基础
    • 光线的表示方式
    • 三角形面的数学表达
    • 光线与三角形求交的算法
  3. 🛠️ 实践案例:光与三角形求交的实现
    • 基本代码实现
    • 优化思路与扩展
  4. 🎁 拓展知识:光追与 Mesh 求交的高级应用
  5. 🎉 总结与感悟

🎨 基本概念

💡 光线是什么?

在图形学中,光线可以简单地表示为:

P(t) = O + t * D  
  • O 是光线的起点,也叫 光源
  • D 是光线的方向
  • t 是光线在该方向上的距离

比如说,我们站在路灯下,路灯发出的光是一束束的光线,而 O 就是路灯的位置,D 是每束光的方向。


🛠️ Mesh(三角形面)是什么?

Mesh 是 3D 模型的基本单位,它由大量三角形面拼接而成。每个三角形都由三个顶点 V1, V2, V3 和它们之间的边组成。

在计算机里,三角形通常用如下数学形式表示:

P(u, v) = (1 - u - v) * V1 + u * V2 + v * V3  
  • uv 是两组局部坐标,定义了三角形上的点;
  • V1, V2, V3 是三角形的顶点坐标;
  • 只要 u >= 0, v >= 0, u + v <= 1,点 P 就在三角形内部。

🎯 为什么需要光与 Mesh 求交?

光与 Mesh 求交在图形学中意义重大,比如:

  1. 光影计算:光线射到物体表面时,判断哪个三角形被光照到。
  2. 反射与折射:光线穿过物体时,计算折射方向。
  3. 碰撞检测:判断光线是否与物体发生碰撞,比如激光射击命中目标。

一句话,没有光与 Mesh 求交,3D 世界就没有真实感! 🌍


📐 数学基础

1️⃣ 光线的表示方式

如前所述,光线公式是:

P(t) = O + t * D  

这里:

  • O 是光线的起点,D 是方向向量;
  • t 决定了光线的延伸程度:当 t > 0 时,表示光线在 D 方向延伸。

2️⃣ 三角形面的数学表达

三角形的点 P(u, v) 用如下公式计算:

P(u, v) = (1 - u - v) * V1 + u * V2 + v * V3  

其中,uv重心坐标。当 u >= 0, v >= 0, u + v <= 1,点 P 才位于三角形内部。


3️⃣ 光线与三角形求交的算法

问题:光线 P(t) 是否与三角形 P(u, v) 相交?如果相交,在哪里?

基本步骤:
  1. 求平面方程:三角形所在平面的法向量 N 通过顶点计算:

    N = normalize((V2 - V1) × (V3 - V1))
    
  2. 计算交点 t
    光线与平面相交时:

    t = ((V1 - O) · N) / (D · N)  
    

    如果 t < 0,说明光线与平面没有交点。

  3. 判断交点是否在三角形内
    将交点带入三角形的重心坐标公式,验证是否满足 u >= 0, v >= 0, u + v <= 1


🛠️ 实践案例:光与三角形求交的实现

🌟 基本代码实现

以下是 JavaScript 中计算光与三角形求交的代码实现:

function rayTriangleIntersect(O, D, V1, V2, V3) {
    const EPSILON = 1e-6;

    // 计算平面法向量
    const edge1 = subtract(V2, V1);
    const edge2 = subtract(V3, V1);
    const h = cross(D, edge2);
    const a = dot(edge1, h);

    // 检查光线是否平行于三角形
    if (a > -EPSILON && a < EPSILON) return null;

    const f = 1.0 / a;
    const s = subtract(O, V1);
    const u = f * dot(s, h);

    // 检查交点是否在三角形外部
    if (u < 0.0 || u > 1.0) return null;

    const q = cross(s, edge1);
    const v = f * dot(D, q);

    if (v < 0.0 || u + v > 1.0) return null;

    // 计算 t,获得交点
    const t = f * dot(edge2, q);
    if (t > EPSILON) {
        return add(O, scale(D, t)); // 返回交点坐标
    }

    return null; // 没有交点
}

// 工具函数
function subtract(a, b) { return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]; }
function add(a, b) { return [a[0] + b[0], a[1] + b[1], a[2] + b[2]]; }
function scale(a, t) { return [a[0] * t, a[1] * t, a[2] * t]; }
function dot(a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; }
function cross(a, b) { return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]; }

💡 优化思路与扩展

  • 使用加速结构(如 BVH 树)提高求交效率;
  • 在复杂场景中结合 GPU 并行计算进行大规模光追求交。

🎁 拓展知识:光追与 Mesh 求交的高级应用

  1. 光线追踪(Ray Tracing):通过光与 Mesh 求交实现高质量的全局光影效果。
  2. 实时渲染:在游戏开发中,光与 Mesh 求交被优化到毫秒级,为玩家提供流畅体验。
  3. 物理仿真:模拟光的反射、折射以及其他物理特性。

🎉 总结与感悟

从数学公式到代码实现,光与 Mesh 求交的过程不仅展现了图形学的魅力,还让人感受到数学的力量。虽然概念复杂,但只要一步步拆解,你就会发现,它其实并不难!

希望这篇文章能为你打开计算机图形学的大门,点亮你的 3D 世界开发之旅!有任何疑问或灵感,欢迎留言交流哦!👋


版权声明:本文由作者原创,转载请注明出处,谢谢支持!

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。


版权声明:本文由作者原创,转载请注明出处,谢谢支持!


http://www.kler.cn/a/597995.html

相关文章:

  • gonet开源游戏服务器环境配置
  • MySQL颠覆版系列————MySQL新特性(开启数据库的新纪元)上篇
  • 1. 页面级一多开发:
  • Unity摄像机基本操作详解:移动、旋转与缩放
  • Java处理Markdown格式内容转换为Word文档
  • JavaScript 性能优化实战
  • 计算机网络的分类及其性能指标
  • Redis简单介绍和安装
  • Centos7搭建Zabbix4.x监控HCL模拟网络设备:zabbix-server搭建及监控基础02
  • 系统转换、系统维护、净室软件工程、构件软件工程(高软51)
  • c++有n个范围是-1e9~1e9的数,去统计每个数的个数?
  • 位示图大小的计算
  • 【递归、搜索和回溯算法】专题三 :穷举VS暴搜VS深搜VS回溯VS剪枝
  • 【ROS实战】02-ROS架构介绍
  • 如何使用SystemVerilog SVA检查跨时钟域信号?
  • [c语言日寄]数据输入
  • GEO与AISEO的关系解析:核心差异与协同逻辑
  • Qt-Q_ENUM宏和QMetaEnum类
  • java江湖系列——集合世家争霸(下)
  • MySQL 5.7升级8.0报异常:处理新增关键字