Unity shader中的法线详解
2015-11-27 13:51
435 查看
一次写shader的时候,根据法线调整视觉效果,却发现坐标不同的情况下,会有颜色突变的情况。不解。故寻找计算法线部分的知识。
首先看一下大神文章了解下大概:http://blog.csdn.net/candycat1992/article/details/41605257
1.
is the transformation from object coordinates to world coordinates.
is the transformation from world coordinates to object coordinates.
Unity sometimes (for non-uniform scale factors) scales the vertex coordinates before handing them to the shader. (Supposedly such that _Object2World is an orthogonal matrix.) For uniform scale factors, however, it doesn't do this vertex scaling but integrates
the scaling into _Object2World (making it a scaled orthogonal matrix). However, for some strange reason (and this is probably an inconsistency that just never got fixed and now too much code relies on it) this scaling was never included in _World2Object. Thus,
you have to scale _World2Object with unity_Scale.w (if scale is important) but _Object2World is already scaled with the reciprocal factor.
No the space is the same, but in a general case (not unity) a non
orthogonal matrix doesn't transform normals correctly.
If you want to perform a correct normal transformation in the general case you need to use theinverse transpose matrix. (In unity shaders this is equivalent to
_Object2World works like a charm :(mul(_Object2World, normal)). both rotation and scaling (uniformly) gave the expected matrix through color checking elements in rows and columns
This is a bit tricky to explain (I hope to remember it correctly).You can assumescale is always uniform because
Following uniforms are provided to shaders:
In order to correctly transform the normal from object to world space, you have 3 possibility:
transform the scaled normal :
you can avoid to use the scaled normal if you normalize the normal after the transform (probably this is your case otherwise AFAIK the transformation shouldn't be 100% correct)
use the inverse transpose :
这个算是一个小知识点,虽然和法线本身无关,但却对写shader有所帮助。
2.o.normal本身是模型坐标系的,通过转化成世界坐标系,可以进行正确的插值。
首先看一下大神文章了解下大概:http://blog.csdn.net/candycat1992/article/details/41605257
1.
_Object2World
is the transformation from object coordinates to world coordinates.
_World2Object * unity_Scale.w
is the transformation from world coordinates to object coordinates.
Unity sometimes (for non-uniform scale factors) scales the vertex coordinates before handing them to the shader. (Supposedly such that _Object2World is an orthogonal matrix.) For uniform scale factors, however, it doesn't do this vertex scaling but integrates
the scaling into _Object2World (making it a scaled orthogonal matrix). However, for some strange reason (and this is probably an inconsistency that just never got fixed and now too much code relies on it) this scaling was never included in _World2Object. Thus,
you have to scale _World2Object with unity_Scale.w (if scale is important) but _Object2World is already scaled with the reciprocal factor.
No the space is the same, but in a general case (not unity) a non
orthogonal matrix doesn't transform normals correctly.
If you want to perform a correct normal transformation in the general case you need to use theinverse transpose matrix. (In unity shaders this is equivalent to
mul(normal,_World2Object).
_Object2World works like a charm :(mul(_Object2World, normal)). both rotation and scaling (uniformly) gave the expected matrix through color checking elements in rows and columns
This is a bit tricky to explain (I hope to remember it correctly).You can assumescale is always uniform because
Unity(at least until 4.x version. I think it will change in 5.x) doesn't apply non-uniform scale in the vertex shader but pre-transform the mesh CPU side.
Following uniforms are provided to shaders:
_Object2World: contains the world matrix including the scale
unity_Scale: the w component contains the inverse of the uniform scale factor (
w = 1/scale)
_World2Object: contains the inverse world matrix without scale
In order to correctly transform the normal from object to world space, you have 3 possibility:
transform the scaled normal :
float3 worldN = mul((float3x3)_Object2World, SCALED_NORMAL);
you can avoid to use the scaled normal if you normalize the normal after the transform (probably this is your case otherwise AFAIK the transformation shouldn't be 100% correct)
use the inverse transpose :
mul(normal,_World2Object)
SCALED_NORMALis defined this way:
[code]#define SCALED_NORMAL (v.normal * unity_Scale.w)
这个算是一个小知识点,虽然和法线本身无关,但却对写shader有所帮助。
2.o.normal本身是模型坐标系的,通过转化成世界坐标系,可以进行正确的插值。
相关文章推荐
- 解决unity中Animation Event无法正确保存的问题
- Unity中Update和FixedUpdate的区别
- Unity中T4M插件的使用,以及针对5.0的修改
- MAC下用unity进行开发书写中文-Visual Studio Code
- Unity uGui RawImage 渲染小地图
- Unity3D-粒子系统
- 混音器(AudioMixer):用Unity 5.0混合出美妙节拍
- Unity中的分层射线检测
- Unity3D模型制作规范[转]
- Unity3D 扩展 Scene
- [Unity框架]PureMVC基础
- 【小松教你手游开发】【unity实用技能】NGUI Scrollview的Reposition的几个总结
- unity万能的提示窗口
- Unity5中的光照简介
- Unity 5 全局光照GI与新的烘焙系统初探
- [3D理论] 关于unity中的update、Lateupdate和FixedUpdate。
- Unity3D中Update和Lateupdate的区别
- Unity3D Update() 和 FixedUpdate()区别
- unity脚本执行顺序详解
- Android 与 Unity3D 项目的整合的Bug