对于法线变换,进行非统一缩放时,如果使用跟变换顶点相同的变换矩阵来变换法线,则会得到错误的结果,即变换后的法线方向与平面不再垂直。

如何求得变换法线的矩阵呢:

转载请注明出处:http://www.cnblogs.com/jietian331/p/7047370.html

假设空间a中的某点的切线Ta和法线Na,空间a转换到空间b的矩阵Ma->b,则Ta转换到空间b中后为:T= Ma->bTa,求将法线从空间a转换到空间b的矩阵?

设此矩阵为G,设Na转换到空间b后为Nb,则在空间b中满足:

Tb* Nb=0

由于:

T= Ma->bTa

Nb = GNa

所以可得:

(Ma->bTa)T(GNa) = 0

推导得:

TaTMa->bTGNa = 0

由于在空间a中满足:

(Ta)TN= 0

所以

Ma->bTG = I

可得出:

G = (Ma->bT)-1 = (Ma->b-1)T

如果变换不包含非统一缩放,则Ma->b是正交矩阵,满足 Ma->b-1=Ma->bT,若统一缩放系数为 k,则

G = Ma->b / k

否则,则必须求解逆矩阵来得到变换法线的矩阵。

如UnityCG.cginc中的法线变换函数如下:

// Transforms direction from object to world space
inline float3 UnityObjectToWorldDir( in float3 dir )
{
return normalize(mul((float3x3)unity_ObjectToWorld, dir));
} // Transforms normal from object to world space
inline float3 UnityObjectToWorldNormal( in float3 norm )
{
#ifdef UNITY_ASSUME_UNIFORM_SCALING
return UnityObjectToWorldDir(norm);
#else
// mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
return normalize(mul(norm, (float3x3)unity_WorldToObject));
#endif
}

shader之法线变换的更多相关文章

  1. [Unity Shader] 坐标变换与法线变换及Unity5新增加的内置函数

    学习第六章Unity内置函数时,由于之前使用mul矩阵乘法时的顺序与书中不一致,导致使用内置函数时出现光照效果不一样,因此引出以下两个问题: 1 什么时候使用3x3矩阵,什么时候使用4x4矩阵? 2 ...

  2. 详解OpenGL中的各种变换(投影变换,模型变换,视图变换)(完)——法线变换

    前面两节内容已经说完了所有的三种变换.也就是说我们现在程序里面既不需要glLookAt(),也不需要gluPerspective(),这些矩阵我们都可以自己写.然后,再用glMultMatrix()来 ...

  3. 【OpenGL】法线变换详解(Normal Transform)[转]

    http://blog.csdn.net/xiajun07061225/article/details/7762711 在图形学中,同样的一个模型视图变换矩阵可以用来变换点.线.多边形以及其它几何体, ...

  4. 一个有趣的模拟光照的shader(类似法线贴图)

    最近使用unity,碰到到一个很有趣的例子.场景无光线,却模拟出了光照,效果挺好.其思路与法线贴图原理异曲同工. 原作者提供的效果印象深刻. 模型除了使用原来的diffuse贴图外,还用到了一张模拟记 ...

  5. 描边shader(法线外拓)

    描边的思路是需要两个pass.第一个pass让顶点沿着法线方向延伸出去,使得模型变大一圈.第二个pass正常渲染,让正常渲染的模型挡在第一个pass之上,这样就会露出延伸出去的部分,延伸出去的就是我们 ...

  6. OpenGL超级宝典第5版&&GLSL法线变换

    在GLSL中,有一些情况需要把局部坐标系下的向量或点转换到视点坐标系下,如光照计算时,需要把法向转化到视点坐标系.如果是模型上一点p 转化到视点坐标系下,直接(model-view matrix )* ...

  7. 【我的书】Unity Shader的书 — 文件夹(2015.12.21更新)

    写在前面 感谢全部点进来看的朋友.没错.我眼下打算写一本关于Unity Shader的书. 出书的目的有以下几个: 总结我接触Unity Shader以来的历程,给其它人一个借鉴.我非常明确学Shad ...

  8. 【Unity Shader】Unity Chan的卡通材质

    写在前面 时隔两个月我终于来更新博客了,之前一直在学东西,做一些项目,感觉没什么可以分享的就一直没写.本来之前打算写云彩渲染或是Compute Shader的,觉得时间比较长所以打算先写个简单的. 今 ...

  9. 【我的书】Unity Shader的书 — 目录(2016.5.19最后一次更新)

    写在前面 感谢所有点进来看的朋友.没错,我目前打算写一本关于Unity Shader的书. 出书的目的有下面几个: 总结我接触Unity Shader以来的历程,给其他人一个借鉴.我非常明白学Shad ...

随机推荐

  1. 出于性能考虑,C语言自动地以传地址的方式将数组传递给被调函数 const 编译错误 最小权限原则

    #include <stdio.h> int main(void) { char array[5]; printf("array=%p,&array[0]=%p,& ...

  2. .net Core2建立MVC网站,部署

    1..net Core2使用sqlservver.EFCore,部署在linux上将出错,具体是错原因大概是:连接超时的意思.=>就想测试下linux到底能不能连接sqlserver.是两者技术 ...

  3. 中位数&贪心

    谁能想到基本算法就这么难呢?我想去冲省选,但是迟迟在这些地方 花时间 算是提升自己的思维算了. 这道题呢 答案其实很简单每个数在a的位置和在b的位置之差的累加/2即是答案为什么呢?考虑当前数字 要向后 ...

  4. DBCHART

    dbchart1.Series[0].DataSource := adoquery1; dbchart1.Series[0].XLabelsSource := 'aaaa'; dbchart1.Ser ...

  5. 转:环绕通知返回值 object 类型

    遇到 AOP 环绕通知报错  “return value from advice does not match primitive return type for: public boolean” 百 ...

  6. 内部排序->插入排序->直接插入排序

    文字描述: 将一个记录插入到已排好序的有序表中,从而得到一个新的.记录数增1的有序表 示意图: 算法分析: 时间复杂度为n*n,辅助存储为1,是稳定的排序方法. 代码实现: #include < ...

  7. ORACLE监听配置及测试实验

    实验一: 修改db_domain和service_name 我们将Db_name和Db_domain两个参数用'.'连接起来,表示一个数据库,并将该数据库的名称称为Global_name即等于serv ...

  8. java 抽象类 abstract

    package cn.sasa.com; //抽象类 被abstract修饰的类 public abstract class Animal { //抽象类的成员变量 的定义 与 一般类是一样的 pri ...

  9. 洛谷P3960 列队 NOIp2017 线段树/树状数组/splay

    正解:动态开点线段树 解题报告: 传送门! 因为最近学主席树的时候顺便get到了动态开点线段树?刚好想起来很久很久以前就想做结果一直麻油做的这题,,,所以就做下好了QAQ 然后说下,这题有很多种方法, ...

  10. mysql报错Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage

    mysql报错Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage 在执行cr ...