法线矩阵推导
法线矩阵推导
https://zhuanlan.zhihu.com/p/72734738
https://juejin.cn/post/7113952418613690382
https://blog.csdn.net/wangjianxin97?type=blog
1、为什么需要法线矩阵
vec3 normalEyeSpace = modelViewMatrix * normal;
如果模型矩阵执行了非等比缩放, 顶点的改变会导致法向量不再保持垂直关系。

缩放后 n n n不在与线段垂直了, 真正垂直的是 n ′ n' n′。
three.js 代码:
const geometry = new THREE.BufferGeometry()
const position = [];
const normals = [];
position.push(-1, 0, 0)
position.push(1, 0, 0)
position.push(0, 1, 0)normals.push(0.5, 0.5, 0)
normals.push(0.5, 0.5, 0)
normals.push(0.5, 0.5, 0)geometry.setAttribute('position', new THREE.Float32BufferAttribute(position, 3))
geometry.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3))const material = new THREE.ShaderMaterial({vertexShader: `varying vec3 vNormal;void main() {vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );gl_Position = projectionMatrix * mvPosition;vNormal = normal;}`,fragmentShader: `varying vec3 vNormal;uniform mat3 normalMatrix;void main() {gl_FragColor = vec4( vNormal, 1.0 );}`,
});const mesh = new THREE.Mesh(geometry, material);
mesh.scale.set(0.5, 1, 1)
2 法向量矩阵推导
约定:
- 向量用小写字母的表示
- 转换矩阵用大写字母表示

假设矩阵 G G G 转换法向量, 矩阵 M M M转换切线。
如果转换到视图空间,那么 M M M就是modelViewMatrix, 如果转换到世界空间, M M M就是modelMatrix。
根据假设有:
n ′ = G n t ′ = M t n' = G n \\ t' = M t \\ n′=Gnt′=Mt
根据几何关系有:
n ⋅ t = n ′ ⋅ t ′ = 0 n \cdot t = n' \cdot t' = 0 n⋅t=n′⋅t′=0
带入有:
n ′ ⋅ t ′ = ( G n ) ⋅ ( M t ) = ( G n ) T ( M t ) = n T G T M t \begin{aligned} n' \cdot t' &= (G n) \cdot (M t) \\ &= (G n)^{T} (M t) \\ &= n^{T} G^{T} M t \\ \end{aligned} n′⋅t′=(Gn)⋅(Mt)=(Gn)T(Mt)=nTGTMt
因为(向量点积用矩阵表示):
n ⋅ t = n T t = n ′ ⋅ t ′ n \cdot t = n^{T} t = n' \cdot t' n⋅t=nTt=n′⋅t′
所以,满足上式, 只需:
G T M = I G^{T} M = I GTM=I
因此:
G T = M − 1 ( G T ) T = ( M − 1 ) T G = ( M − 1 ) T \begin{aligned} G^{T} &= M^{-1} \\ (G^{T})^{T} &= (M^{-1})^{T} \\ G &= (M^{-1})^{T} \end{aligned} GT(GT)TG=M−1=(M−1)T=(M−1)T
相关文章:
法线矩阵推导
法线矩阵推导 https://zhuanlan.zhihu.com/p/72734738 https://juejin.cn/post/7113952418613690382 https://blog.csdn.net/wangjianxin97?typeblog 1、为什么需要法线矩阵 vec3 normalEyeSpace modelViewMatrix * normal;如果模型矩阵执行了非等比缩放, 顶点的改变会导致法…...
对容器、虚拟机和 Docker 的初学者友好介绍
一、说明 如果你是一个程序员或技术人员,你可能至少听说过Docker:一个有用的工具,用于在“容器”中打包,运输和运行应用程序。很难不这样做,这些天它得到了所有的关注 - 来自开发人员和系统管理员。即使是像谷歌、VMwa…...
linux部署clickhouse(单机)
一、下载安装 1.1、下载地址 阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区阿里巴巴开源镜像站,免费提供Linux镜像下载服务,拥有Ubuntu、CentOS、Deepin、MongoDB、Apache、Maven、Composer等多种开源软件镜像源,此外还提供域名解析DNS、…...
vue组件注册
组件注册分为全局注册和局部注册 全局注册 在 main.js 或者入口文件中 import { createApp } from vue; import MyComponent from ./components/MyComponent.vue;const app createApp();app.component(my-component, MyComponent);app.mount(#app); 我们首先通过createApp…...
day20 飞机大战射击游戏
有飞行物类 飞行 爆炸 的连环画, 飞行的背景图 , 子弹图, 还有游戏开始 暂停 结束 的画面图。 设计一个飞机大战的小游戏, 玩家用鼠标操作hero飞行机, 射出子弹杀死敌机,小蜜蜂。 敌机可以获得分数&…...
iOS设计规范是什么?都有哪些具体规范
iOS设计规范是苹果为移动设备操作系统iOS制定的设计指南。iOS设计规范的制定保证了苹果应用在外观和操作上的一致性和可用性,从而提高了苹果界面设计的用户体验和应用程序的成功性。本文将从七个方面全面分析iOS设计规范。 1.iOS设计规范完整版分享 由「即时设计」…...
动手学深度学习-pytorch版本(二):线性神经网络
参考引用 动手学深度学习 1. 线性神经网络 神经网络的整个训练过程,包括: 定义简单的神经网络架构、数据处理、指定损失函数和如何训练模型。经典统计学习技术中的线性回归和 softmax 回归可以视为线性神经网络 1.1 线性回归 回归 (regression) 是能为一个或多个…...
Spark 图计算ONEID 进阶版
0、环境信息 本文采用阿里云maxcompute的spark环境为基础进行的,搭建本地spark环境参考搭建Windows开发环境_云原生大数据计算服务 MaxCompute-阿里云帮助中心 版本spark 2.4.5,maven版本大于3.8.4 ①配置pom依赖 详见2-1 ②添加运行jar包 ③添加配置信…...
Comparable和Comparator区别
Comparable和Comparator接口都是实现集合中元素的比较、排序的,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较逻辑。总体来讲&#x…...
JAVA知识点梳理
我的博客:lcatake_flume,spark,zookeeper-CSDN博客 看不懂的话进去看看 1.Java的三个版本 JAVASE 基本 JAVAME 微缩 JAVAEE 标准 3.java的特点 面向对象 跨平台:jvm将java文件转变为字节码文件(.class)在多个系统中运 行字…...
[SWPUCTF 2022 新生赛]ez_ez_php
这段代码是一个简单的PHP文件处理脚本。让我们逐行进行分析: error_reporting(0); - 这行代码设置了错误报告的级别为0,意味着不显示任何错误。 if (isset($_GET[file])) { - 这行代码检查是否存在一个名为"file"的GET参数。 if ( substr($_…...
GraphQL strawberry的使用回顾和体会
GraphQL vs RESTful 简单来说GraphQL 比起 RESTful 集成额外一些功能 出入参校验、序列化 (简化后端编程)自由可选的返回数据字段 (简化一些多余接口开发和沟通联调成本) 这些都是优点了。 开发效率在项目初期是很重要的,需要快速原型化。 但是后期稳定后&#…...
08无监督学习——聚类
1.什么是聚类任务? 类别:无监督学习 目的:通过对无标记训练样本的学习来揭示数据的内在性质及规律,为进一步的数据分析提供基础。 1.1K均值聚类 步骤: 随机选取样本作为初始均值向量(初始值:k的值【即几个簇】)分别…...
Python使用OpenCV库对彩色图像进行通道分离
目录 1、解释说明: 2、使用示例: 3、注意事项: 1、解释说明: 在Python中,我们可以使用OpenCV库对彩色图像进行通道分离。通道分离是将彩色图像的每个像素分解为三个通道(红、绿、蓝)的过程。…...
前端面试:【CSS】盒模型、选择器、布局、响应式设计、Flexbox 与 Grid
CSS(层叠样式表)是用于控制网页外观和布局的重要语言。在这篇文章中,我们将深入探讨CSS的基础知识,包括盒模型、选择器、布局、响应式设计,以及弹性盒子(Flexbox)和网格布局(Grid&am…...
深入浅出通过PHP封装根据商品ID获取抖音商品详情数据方法
抖音商城商品详情数据是指商品在抖音商城中的展示信息,包括商品的标题、描述、价格、图片等。商家可以通过商品详情数据了解用户对商品的兴趣和需求,从而进行优化和调整。 商品详情数据还可以帮助商家评估商品的销售情况和市场竞争力,为制定…...
排序(七种排序)
1.插入排序 2.希尔排序 3.选择排序 4.堆排序 5.冒泡排序 6.快速排序 7.归并排序 1.插入排序 1.1思路 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为 止,得到一个新的有序序列 1.2实现 //插入排…...
【工程优化问题】基于鲸鱼、萤火虫、灰狼优化算法的张力、压缩弹簧设计问题研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
sap ui5刷新页面的方式
1.第一种 window.location.reload();2.第二种 如果你想在UI5应用程序中使用MVC模式来处理页面刷新,可以通过重新加载当前路由来实现刷新。首先,确保你有一个Router对象实例: var oRouter = sap.ui.core.UIComponent.getRouterFor(this);然后&...
Java课题笔记~ Fastjson 概述
3.3 JSON串和Java对象的相互转换 学习完 json 后,接下来聊聊 json 的作用。 以后我们会以 json 格式的数据进行前后端交互。前端发送请求时,如果是复杂的数据就会以 json 提交给后端;而后端如果需要响应一些复杂的数据时,也需要…...
Thorium浏览器:从源码到高性能Chromium分叉的实战指南
Thorium浏览器:从源码到高性能Chromium分叉的实战指南 【免费下载链接】thorium Chromium fork named after radioactive element No. 90. Source code and Linux releases. Windows/MacOS/ARM builds served in different repos, links are towards the top of the…...
Dell G15终极散热控制指南:开源温度管理软件全面解析
Dell G15终极散热控制指南:开源温度管理软件全面解析 【免费下载链接】tcc-g15 Thermal Control Center for Dell G15 - open source alternative to AWCC 项目地址: https://gitcode.com/gh_mirrors/tc/tcc-g15 还在为Dell G15笔记本过热问题而烦恼吗&#…...
Bonsai工具库:函数式编程与代码设计模式实战解析
1. 项目概述:当代码遇见禅意最近在GitHub上闲逛,发现一个挺有意思的项目,叫sauravpanda/bonsai。光看名字,你可能以为这是个园艺或者艺术相关的仓库,但实际上,它是一个非常精巧的编程工具库。这个项目名“B…...
GitAhead本地化配置详解:打造最适合你的中文Git环境
GitAhead本地化配置详解:打造最适合你的中文Git环境 【免费下载链接】gitahead Understand your Git history! 项目地址: https://gitcode.com/gh_mirrors/gi/gitahead GitAhead是一款功能强大的Git客户端工具,旨在帮助开发者更直观地理解和管理G…...
终极CFP管理指南:developers.events如何帮助您提交演讲申请
终极CFP管理指南:developers.events如何帮助您提交演讲申请 【免费下载链接】developers-conferences-agenda developers.events is a community-driven platform listing developer/tech conferences and Calls for Papers (CFPs) worldwide with a list, a calend…...
代码所有权的悖论:集体智慧与个人责任的边界
代码世界的身份迷局在软件测试的日常工作中,我们时常会陷入这样的困惑:当面对一行引发系统崩溃的代码时,究竟该追溯到最初编写它的开发者,还是问责于后续不断迭代维护的团队?当一个历经数十人之手、跨越数年周期的模块…...
Herc.ai:一站式AI API网关,统一调用GPT-4、Gemini等主流模型
1. 项目概述:Herc.ai,一个面向开发者的全能AI API网关如果你正在寻找一个能让你在项目中轻松集成GPT-4、Gemini、DALL-E、Flux等主流AI模型,同时又不想被单一供应商绑定、不想处理复杂的多API密钥管理、并且希望有一个统一的、开发者友好的接…...
3分钟掌握B站缓存视频转换:m4s-converter终极使用指南
3分钟掌握B站缓存视频转换:m4s-converter终极使用指南 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 你是否曾经遇到过这样的困扰&a…...
Linux调试利器:用addr2line精准定位程序崩溃现场
1. 当程序崩溃时,我们该如何快速定位问题? 作为一名长期奋战在Linux开发一线的程序员,我最头疼的就是遇到程序突然崩溃的情况。那种看着终端输出"Segmentation fault (core dumped)"却无从下手的无力感,相信很多开发者都…...
STM32CUBEMX实战指南:串口DMA高效收发与自定义打印函数优化
1. 串口DMA基础与STM32CubeMX配置 第一次用STM32CubeMX配置串口DMA时,我对着密密麻麻的选项差点崩溃。后来发现只要掌握几个关键点,5分钟就能搞定稳定可靠的DMA通信。先解释下为什么需要DMA:当你用传统方式通过串口发送"Hello World&quo…...
