法线矩阵推导

news2024/9/19 10:57:09

法线矩阵推导

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 nt=nt=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} nt=(Gn)(Mt)=(Gn)T(Mt)=nTGTMt

因为(向量点积用矩阵表示):
n ⋅ t = n T t = n ′ ⋅ t ′ n \cdot t = n^{T} t = n' \cdot t' nt=nTt=nt

所以,满足上式, 只需:
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=M1=(M1)T=(M1)T

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/910113.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于蝴蝶算法优化的BP神经网络(预测应用) - 附代码

基于蝴蝶算法优化的BP神经网络(预测应用) - 附代码 文章目录 基于蝴蝶算法优化的BP神经网络(预测应用) - 附代码1.数据介绍2.蝴蝶优化BP神经网络2.1 BP神经网络参数设置2.2 蝴蝶算法应用 4.测试结果:5.Matlab代码 摘要…

sNMFcross-entropyK

0.简单介绍 稀疏非负矩阵(sNMF)和最小二乘优化来产生祖先比例估计数的祖先推断算法,这个算法呢与admixture来说差别不是很大,但是优点就是快,运算速度可以快到10-30倍左右。 1.安装 这一步不必多说,下载…

tailscale使用教程(远程连接服务器)

tailscale:将多个设备放在同一局域网下,实现异地组网。 首先进入tailscale官网,根据系统需求进行下载 需要远程的设备和被远程的设备都需要下载。 然后两个设备均登录同一账号即可 注:这里重点讲一下linux操作系统上的操作&…

PID输出PWM温度控制(PID输出PWM的各种方法介绍)

这篇博客主要介绍PID的输出如何和PWM输出进行绑定,PID控制算法和源代码大家自行查看PID专栏,这里不再赘述。常用链接如下: 位置式PID(S7-200SMART 单自由度、双自由度梯形图源代码)_RXXW_Dor的博客-CSDN博客有关位置型PID和增量型PID的更多详细介绍请参看PID专栏的相关文章…

读SQL学习指南(第3版)笔记02_数据类型

1. 命令行工具 1.1. mysql -u root -p; 1.2. mysql> show databases; 1.3. mysql> use sakila; 1.4. mysql> SELECT now(); 1.4.1. now()是MySQL的内建函数 1.4.2. 返回当前日期和时间 1.5. mysql> SELECT now() FROM dual…

DFT计算入门新手坑:能带不连续

新手在学习DFT计算时,在熟悉了基本的操作和VASP输入文件后,首先就会学习到结构优化、自洽计算和能带的计算。 而笔者学习DFT计算这些年来看到太多新手学者踩到大大小小的坑,其中能带看起来不连续或者能带不连续则是几乎必踩的坑之一。 这些初…

【HCIP】04.VRRP与BFD

VRRP VRRP基本概念 VRRP路由器 运行VRRP协议的路由器,VRRP是配置在路由器的接口上的,而且也是基于接口来工作的。 VRID 一个VRRP组由多台协同工作的路由器(的接口)组成,使用相同的VRID(Virtual Router…

Spring统一功能处理

1. AOP存在的问题 获取参数复杂AOP的规则相对简单 2. 拦截器 2.1. 应用(以登录为例) 2.1.1. 自定义拦截器 新建interceptor文件夹 import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest; import javax.servlet.http…

Blend for Visual Studio:提升用户界面设计的专业工具

随着软件行业的迅速发展,用户界面设计变得越来越重要。一个好的用户界面能够吸引用户的注意力,提供良好的用户体验,并增加应用程序的成功率。在这个背景下,Blend for Visual Studio作为一款专业的用户界面设计工具,为开…

SpringCloud学习笔记(二)_Eureka注册中心

一、Eureka简介 Eureka是一项基于REST(代表性状态转移)的服务,主要在AWS云中用于定位服务,以实现负载均衡和中间层服务器的故障转移。我们称此服务为Eureka Server。Eureka还带有一个基于Java的客户端组件Eureka Client&#xff…

从电子表格到纸张:Excel转PDF的神奇变身之旅!

当你需要将Excel文件转换为PDF时,可以使用Python编程语言和一些流行的库来实现这个任务。在本篇博客中,我将介绍如何使用wxPython、pandas和PyMuPDF库创建一个简单易用的图形用户界面(GUI)工具来完成这项工作。 C:\pythoncode\new\excelexportpdf.py …

SCCB与IIC的异同及FPGA实现的注意事项

文章目录 前言一、信号线二、SCCB数据传输格式三、SCCB写(与IIC完全一致)四、SCCB读五、SCCB和IIC的区别 前言 IIC接口有比较广泛的应用,而SCCB(Serial Camera Control Bus,串行摄像头控制总线)是由OV&…

发现一款免费WEB在线使用的AI对话+绘画

这是一个优秀的golang开发作者 免费开放给大家使用的 简单上手 注册就能使用 多个AI角色多模型自由选择 下面是使用效果 链接地址在文末链接地址:目前免费体验

基于51单片机无线温度报警控制器 NRF24L01 多路温度报警系统设计

一、系统方案 1、本设计默认采用STC89C52单片机,如需更换单片机请联系客服。 2、接收板LCD1602液晶实时显示当前检测的2点温度值以及对应的上下限报警值。发射板由DS18B20采集温度值,通过无线模块NRF24L01传给接收板。 3、按键可以设置温度上下限值&…

硬编码基础三(变长指令的查询方式)

硬编码基础三(变长指令的查询方式) intel指令的格式可以看作如下形式: 前缀操作码modrmsib偏移立即数 其中操作码决定了是否存在moderm modrm中的rm位决定了是否存在sib 这边举个例子, 在intel白皮书中的A附录中的A.3章节有一…

HCIP---企业网三层架构实验

实验要求 实验拓扑及IP规划 实验步骤 1. Eth-Trunk通道(将多个接口逻辑的整合成一个接口,实现带宽叠加的作用) SW1和SW2起eth-trunk,并划入接口 [sw1]interface Eth-Trunk 0 [sw1-Eth-Trunk0]int g0/0/3 [sw1-GigabitEthernet0…

第5天----单词替换(C++replace()函数)

当一句话中出现错误的单词时&#xff0c;你是否想快速将它替换为你想要的&#xff0c;接下来的这篇文章&#xff0c;将带你了解什么是单词替换。 一、基本知识&#xff1a; 1. string::replace()函数 C <string>库中的replace()函数是用于替换字符串中的特定字符或子字…

微信小程序canvas type=2d生成海报保存到相册、文字换行溢出显示...、文字删除线、分享面板

做个简单的生成二维码海报分享&#xff0c;我做的时候也找简单的方法看能不能实现页面直接截图那种生成图片&#xff0c;原生小程序不支持&#xff0c;不多介绍下面有全部代码有注释、参数自行替换运行看看&#xff0c;有问题可以咨询我&#xff0c;我写的已经上线 效果如图&a…

CTFhub-sql-整数注入

判断存在 sqli 注入 1 1 and 11 1 and 12 因为 11 为真&#xff0c;12 为假&#xff0c;且 11 与 1 显示的数据一样&#xff0c;那么就存在 sqli 注入 查询该数据表的字段数量 一、 2 3 1,2成功带出数据&#xff0c;3没有数据&#xff0c;所以有两个字段 二、 1 order by …

数据结构---串(赋值,求子串,比较,定位)

目录 一.初始化 顺序表中串的存储 串的链式存储 二.赋值操作&#xff1a;将str赋值给S 链式表 顺序表 三.复制操作&#xff1a;将chars复制到str中 链式表 顺序表 四.判空操作 链式表 顺序表 五.清空操作 六.串联结 链式表 顺序表 七.求子串 链式表 顺序表…