Unity Shader 顶点程序 实现漫反射与法向量的非等比转换
2015-12-15 12:54
513 查看
Shader "Custom/MyShader_Diffuse" { SubShader { Pass { CGPROGRAM #include "lighting.cginc" //引入_WorldSpaceLightPos0 #pragma vertex vert #pragma fragment frag #pragma target 3.0 struct output{ //顶点输出 float4 Pos:POSITION; float4 Col:COLOR; }; output vert(in float4 ver:POSITION,in float3 verNormal:NORMAL) //输入顶点位置和 法向量 { output op; op.Pos = mul(UNITY_MATRIX_MVP,ver); //MVP变换 float3 N = normalize(verNormal); //规范化法向量 变为单位向量 float3 L = normalize(_WorldSpaceLightPos0); //规范化光照向量 //① L = mul(_World2Object,float4(L,0)).xyz; //重要:由于输入的顶点法向量为模型坐标不变,而光照向量为世界坐标也不变 //② N=mul(_Object2World,float4(N,0)).xyz; //故旋转时会光照异常,顶点坐标固定颜色不随光照变化 //解决方案: ①:将光照向量由世界坐标转换到模型坐标 // ②:将顶点法向量由模型坐标变换到世界坐标 N = mul(float4(N,0),_World2Object).xyz; //以上两种方案解决了顶点随光照位置变化的问题 //但是还有一个问题待解决 "若将模型非等比缩放,法向量转换到世界坐标会异常,变化后的法向量将不再垂直于对应的表面" //解决方案: 将模型法向量 * (((模型到世界变换矩阵)的逆矩阵)的转置矩阵) // (模型到世界变换矩阵)的逆矩阵 ==> 世界到模型 //(世界到模型)的 转置矩阵 ==> 将CG中 mul()方法的2个参数换位置 //最终得到左边的N float dot_NL = saturate(dot(N,L)); op.Col = _LightColor0 * dot_NL; return op; } float4 frag(output ipt):COLOR { return ipt.Col + UNITY_LIGHTMODEL_AMBIENT; } ENDCG } } }
相关文章推荐
- Unity 获取指定资源目录下的所有文件
- Unity3D AI角色移动和自动跟随
- Unity Sprite切割导出
- Unity3D 巡逻敌兵探测玩家逻辑实现
- Unity3D 摄像机平滑跟随角色
- Unity3D角色换装实现原理及步骤
- unity3d爬坑手记3
- 【Unity Shaders】Lighting Models —— 灯型号Lit Sphere
- 在Unity3D中使用ScriptableObject进行序列化
- unity发布程序的选项
- 使用vs调试unity脚本的方法
- Unity日志工具——封装,跳转
- Unity的Vsync Count垂直同步原理剖析
- UNITY 5.2 Quaternion 类
- unity5.x的bug
- Unity3d 配置OpenCV(EmguCV) 周围环境
- [Unity3D]脚本中Start()和Awake()的区别
- Unity3D Socket流数据大小端读写封装
- Unity3D 使用异步socket通讯
- unity, TRANSFORM_TEX