找回密码
 注册帐号

扫一扫,访问微社区

墙角落泪

Unity Shader笔记

热度 1367 2019-3-9 19:54 |个人分类:笔记| Shader, Unity


漫反射
diffuse=直射光*max(0,cos(夹角(光和法线的夹角))
cosθ=光的方向*法线方向

直射光: _LightColor0.rgb, 表示场景中第一个光源的直射光
需要先包含文件
#include"Lighting.cginc"
然后添加标签正确定义LightMode
Tags{"LightMode=ForwardBase"}

光的反射方向:_WorldSpaceLightPos0.xyz
光的方向就是照在模型上的位置,是在世界空间中的
光的方向使用时通常需要归一化:
fixed3 LightDir=normalize(_WorldSpaceLightPos0.xyz);
----
因为我们需要求的是光的反射方向,不需要大小所以要使用normalize

法线:NORMAL
法线是模型空间下的
使用法线计算漫反射时候需要把法线转换到世界空间中
fixed3 normalDir= normalize(mul(normal,(float3×3_)World2Object));
----
注意下计算法线方向的时候需要归一化的,
因为我们只需要方向,不需要大小

normalize() 用来把一个向量,单位化(原来方向保持不变,长度变为1)
max() 用来取得函数中最大的一个
dot() 用来取得两个向量的点积
_WorldSpaceLightPos0 取得平行光的位置
_LightColor0 取得平行光的颜色
UNITY_MATRIX_MVP 这个矩阵用来把一个坐标从模型空间转换到剪裁空间

_World2Object 这个矩阵用来把一个方向从世界空间转换到模型空间

mul() 使用矩阵变换方向的函数
即一个矩阵和一个方向相乘,然后对这个方向进行空间的转换
------
一个小Tips:
---
正常使用mul()函数 把定点位置从模型空间转换到剪裁空间:
mul(UNITY_MATRIX_MVP,v);
---
现在反过来使用,
比如法线是模型空间的方向,
现在有一个从世界空间转换到模型空间的矩阵 _World3Object
我们要把模型空间的法线方向转换到世界空间就可以这样
mul(normal,_World2Object);
---
只需要把原来矩阵放的位置换到后面,就可以实现反过来使用
矩阵了。
-----
总结:
通常使用矩阵的时候都是 矩阵乘以一个方向,这样运算的结果
是和矩阵的定义相同的,
如果用一个方向去乘以矩阵的话,这样得到的是和矩阵定义相反
的一个结果。

矩阵的强制转换
例如:(float 3×3)_World2Object
前面加一个(float 3×3) 就可以把矩阵转成我们所需要的矩阵了
也有(float4×4)选择合适的使用就可以了,
-----
对了使用什么转换成什么样的矩阵要看和矩阵相乘的方向是几维的方向
三维就选3 四维就选4

环境光 ambient
系统有环境光的内置宏直接调用就可以取到
fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.rgb

Shader编码中使用 +* 的区别
-----
使用+
使用这个符号的时候通常是几种光相互叠加的情况
比如漫反射光加(+)环境光 加(+)高光 这样的
是几种光源的叠加,并且越加越亮。
-----
使用 *
使用这个符号的时候通常是几种颜色相互融合,
或者某种光和某个颜色或者贴图融合。
这样只会改变模型的颜色或者外表样子,并
不会影响到模型身上的光的亮度。
如 漫反射(乘 *)color.rgb


半兰伯特模型漫反射
diffuse =直射光*max(0,cos(光的方向*法线方向)*0.5+0.5);

高光反射 Specular
 Blinn光照模型 Specular = 直射光 * pow(max(cosθ,0),高光参数)
---
直射光: _LightColor0.rgb
---
θ:是反射光和视角方向的夹角,夹角越小高光点越亮
---
高光参数: Gloss 控制反射光圈大小,0-10即可 也可以更大
---
pow() 是指数函数,cosθ是底数,高光参数是系数
假如高光系数时2那么可以写成这样 cosθ²
-----
reflect(i,n) 计算反射方向的函数
---
i是入射方向
光反射方向可以由内置函数_WorldSpaceLightPos0.xyz得到
只需要在这个函数前面加一个负号然后归一化一下就可以
得到入射方向 i=normalize(-_WorldSpaceLightPos0.xyz)
---
n 是法线方向
把法线从模型空间转换到世界空间然后归一化就可以得到
 n= normalize(mul(normal,(float3×3)_World2Object));
--------------------
Blinn-Phong光照模型  Specular = 直射光 * pow(max(cosθ,0),高光参数)
---
θ:是法线方向和 x 方向的夹角。  x: 是平行光和视野方向的平分线
这里的平行光和视野的方向均是从模型到光源和相机的方向
光的方向:(模型到光源方向)
fixed lightDir=normalize(_WorldSpaceLightPos0.xyz);
相机的方向:(模型到相机方向)
fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz-worldVertex);
说明: worldVertex 是在顶点函数中转换到世界空间中的顶点
x 的方向:(halfDir
fixed3 halfDir=normalize(viewDir+lightDir);

使用UnityCG.cginc中一些常用的函数
摄像机方向(视角方向)
float3 WorldSpaceViewDir(float4 v)  参数是模型空间中的顶点坐标,返回值是世界空间中这个点到相机的观察方向
float3 UnityWorldSpaceViewDir(flaot4 v)   参数是世界空间中的顶点坐标 ,返回值是世界空间从这个点到相机的观察方向
float3 ObjSpaceViewDir(float4 v)     参数是模型空间中的顶点坐标, 返回值是从模型空间中这个点到相机的观察方向
光源方向
float3 WorldSpaceLightDir(float4 v)  参数是模型空间中顶点坐标, 返回值是世界空间中从这个点到光源的方向
float3 UnityWorldSpaceLightDir(flat4 v)  参数是世界空间中的顶点坐标, 返回值是世界空间中从这个点到光源的方向
float3 ObjSpaceLightDir(float4 v)  参数是模型空间中的顶点坐标,返回值是模型空间中从这个点到光源的方向、
方向转换
float3 UnityObjectToWorldNormal(flaot3 normal)  参数是模型空间中的法线方向,返回值是世界空间中的法线方向
float3 UnityObjectToWorldDir(float3 dir)  参数是模型空间中的任意一个方向,功能是把这个模型空间中的方向转换到世界空间中
float3 UnityWorldToObjectDir(float3 dir)  参数是世界空间中的任意一个方向,功能是把这个世界空间中的方向转换到模型空间中
































评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册帐号