《Unity Shader入门精要》笔记(二) 光照初体验
2018-01-18 22:43
155 查看
第五章 开始Unity Shader学习之旅
Shader的属性是用来干嘛的?如何定义?Pass中如何使用这个属性?属性主要是在Unity的编辑器面板显示、修改用的。定义参考UntiyShader官方文档
pass中想要使用这个属性,需要定义一个同名变量。shader中属性变量一般以下划线开始,例如
fixed4 _Color;
指定顶点、片元着色器函数
着色器代码在CGPROGRAM 和 ENDCG之间,使用CG/HLSL语言书写。 MSDN HLSL参考
CGPROGRAM #pragma vertex vert #pragma fragment frag ... ENDCG
UNITY_MATRIX_MVP用来干嘛? mul函数?SV_POSITION又是什么东西? SV_Target呢?
UNITY_MATRIX_MVP是内建矩阵,是从模型空间到投影空间的转换矩阵。对于每个模型来说Unity会自动计算好几个常用的矩阵,以便使用,也减少重复计算。
mul函数就是操作矩阵跟向量、矩阵的函数。MV 操作就是就由mul完成。所以
mul(UNITY_MATRIX_MVP, v)就是坐标转换了。
SV_POSITION 是标明目标值是顶点投影到屏幕的最终位置,一个Pass里面应该只能指定一个
SV_Target也是一个语义(semantics),这个是用来标识最终屏幕颜色的。
关于语义,参考UnityShader语义介绍 以及 MSDN语义介绍文档
DX10以后SV开头的系统数值语义,通常有特殊含义 ,如SV_POSITION标识目标值包含了可用于光栅化的变换后的坐标。
着色器为什么能做到顶点参数自定义?自定义结构体内容是如何被填充的?
Unity根据结构体中字段的语义标识来填充,能够接受的数据都是预定义好的。
顶点着色器能接受那些参数?自定义结构体如何定义?
参考UnityShader顶点着色器能输入哪些数据
POSITION顶点坐标, typically a
float3or
float4.
NORMAL法线, typically a
float3.
TEXCOORD0第一个uv坐标, typically
float2,
float3or
float4.
TEXCOORD1,
TEXCOORD2and
TEXCOORD3are the 2nd, 3rd and 4th UV coordinates, respectively.
TANGENT切线 (used for normal mapping), typically a
float4.
COLORis the per-vertex color, typically a
float4.
// POSITION将被填充模型顶点坐标; NORMAL指定的字段将被填充法线 struct a2v { float4 pos : POSITION; float3 normal : NORMAL; };
顶点着色器与片元着色器之间如何通信?
顶点着色器函数返回值若不是单独SV_POSITION则可以被传递给片元着色器。
TEXCOORD1很多时候用来存储的值不是uv坐标,而是一些计算需要的值,用来传递给片元着色器。 数据的传递和存储不拘一格,包括后面的法线、切线、高度贴图
要熟悉Unity提供的内置文件和变量,使用时
#include "UnityCG.cginc"来包含目标文件中的函数变量。 参考UnityShader内建文件 以及 UnityShader中的内建函数。熟悉使用,不要重复造轮子。
如何调试Shader结果?
使用假色彩输出图像,同前面说的那样, 纹理,或者说颜色空间是着色器最好的数据存储方式,一切都是颜色。所以把要调试的数值转换成颜色输出来,就是最简单的调试方法了。
Windows上 VS2012的Graphics Debugger 参考UnityShader使用Windows上的VS2012调试
Unity自带的FrameDebug,只能简单看每一步pass的结果。
小心平台引起的语法差异
float half fixed类型的区别?
简单来说颜色类型的都使用fixed3 fixed4就没错了,half跟float现在基本没啥区别了。
参考UnityShader数据类型 以及 MSDN HLSL数据类型
小心使用分支与循环语句
分支判断语句中使用的条件变量最好是常数。
每个分支中包含的操作指令数尽可能少
分支的嵌套层数尽可能少
扩展阅读《GPU精粹2》
第六章 Unity中的基础光照
什么是光照模型?BRDF是什么东西?环境光?自发光?漫反射,高光都是个啥?所谓光照模型就是对真实世界光照的一个数学建模。计算的比较细比较真的就叫BPS,常见的都是一些简化的数学模型,为了减少计算量。常见的Phong及Lambert以及Blinn-Phong模型。
现实世界中,我们能看到一个物体,受到的各种光线的反射、折射影响太复杂,标准光照模型把光线分为4个部分:
自发光 2. 高光反射 3. 漫反射 4. 环境光
那高光反射跟漫反射有什么区别呢?简单理解就是高光反射才是反射,漫反射应该叫散射,漫反射会把光线反射到各个方向。参考下金属的反光,就是高光了。
环境光、自发光没啥好解释的,望文知义。
漫反射、高光如何计算?
漫反射采用Lambert定律:反射光线的强度与表面法线和光源方向之间夹角的余弦值成正比。 好,之前的数学知识开始排上用场了。n⃗ ⋅l⃗ =|n⃗ ||l⃗ |cosθ,只要N和L都是单位向量,就妥了。正式的公式如下: Clight为光线颜色,Mdiffuse为材质反射颜色
Cdiffuse=(Clight⋅Mdiffuse)max(0,n⃗ ⋅l⃗ );
高光的计算就稍微复杂一点了,主要是跟观察方向有关。如下图:
而r⃗ =2(n⃗ ⋅I⃗ )n⃗ −I⃗ 计算得出。那么这个公式到底几个意思?怎么理解呢?r⃗ +I⃗ 的结果肯定是在n⃗ 方向上,而大小为I⃗ 在n⃗ 上的投影的2倍。根据前面向量点积的公式,2(n⃗ ⋅I⃗ )就是投影的2倍了。注意计算点积是r跟v。公式如下:
cspecular=(clight⋅mspecular)max(0,v̂ ⋅r)Mgloss
另一种简化计算方法(实际是PBS中的微表面反射的简化版本),就是计算光线向量跟视线向量的中值,再与法向量点乘得到ĥ =normalize(v+I)。公式也变成了下面这样,点积部分为法向量跟ĥ :
cspecular=(clight⋅mspecular)max(0,n̂ ⋅ĥ )Mgloss
其中使用的Mgloss,是光泽度,max(0,n̂ ⋅ĥ )Mgloss这部分的取值图像大概就是这样:
可以理解Mgloss越大,图像越陡峭,高亮范围就越小。
(顺便发现一个在线画数学图的网站)
逐顶点光照跟逐像素光照的区别?如何选择?
针对每个顶点计算一次光照,当然比每个像素都计算一遍光照要节省的多。由于逐像素光照的消耗,所以使用要谨慎了。
逐像素的效果要优于逐顶点。一般来说,最多四个光源可以使用逐像素光照,其他光源就得只使用顶点光照了。
Unity光照实践要点
Pass中设置
Tags{ "LightMode" = "ForwardBase"}
引用光照的相应头文件
#include "Lighting.cginc"
属性要使用,需要定义对应的变量,变量命名以下划线开头,如_DiffuseColor;
内建变量熟悉 UNITY_MATRIX_MVP UNITY_LIGHTMODEL_AMBIENT _WorldSpaceLightPos0
使用Fallback “Diffuse”
对于平行光,_WorldSpaceLightPos0就是向量,计算光照方向时,不用再减顶点或像素位置
光照在世界空间和模型空间计算有没有区别?没有。 如果嫌法线转世界空间不方便,可以简单的把光照向量转到模型空间来计算。
集中一下上面的链接:
UntiyShader官方文档
MSDN HLSL参考
HLSL内建函数列表
UnityShader语义介绍
MSDN语义介绍文档
UnityShader顶点着色器能输入哪些数据
UnityShader内建文件
UnityShader中的内建函数
UnityShader使用Windows上的VS2012调试
UnityShader数据类型
MSDN HLSL数据类型
《GPU精粹2》
相关文章推荐
- WPF学习笔记之一: 初体验 和 XAML
- Direct 3D学习笔记(三)——光照与材质
- OpenGLES入门笔记 :OpenGLES光照基础总结1
- Spark笔记(1)-Spark初体验
- 《Unity Shader入门精要》笔记(四) 光照and阴影的理解
- 《unityshader 入门精要》漫反射光照与高光反射光照模型学习笔记
- java初体验学习笔记
- openGL之光照2(材料、颜色追踪、光源)---openGL学习笔记(十)
- jQuery 学习笔记 一 初体验《三》
- [学习笔记]markdown初体验
- OpenGL学习笔记(三):颜色与光照
- Cocos 3D功能初探学习笔记(3)---光照
- Android笔记(十七)光照传感器
- 【Visual C++】游戏开发笔记四十 浅墨DirectX教程之八 绘制真实质感的三维世界:光照与材质专场
- 【Visual C++】游戏开发笔记四十 浅墨DirectX教程之八 绘制真实质感的三维世界:光照与材质专场
- Shader自学笔记 2.1.1 逐顶点漫反射光照模型实现
- 【慕课笔记】第一章 JAVA初体验 第1节 JAVA平台应用
- 【慕课笔记】第一章 JAVA初体验 第4节 使用Eclipse开发java程序
- JQuery笔记1: JQuery初体验之 ready
- ExtJs 学习笔记 一 初体验