Unity Shader模板测试用法记录

之前经常忘记模板测试的用法,现在把这些用法记录在博客上免得以后忘记了。

在Shader的Pass开头写Stencil{ }结构体,如果每个Pass都用,则可以提到外面。

Stencil {  
                Ref 2                     //参考值为2,stencilBuffer值默认为0  
                Comp always               //stencil比较方式是永远通过  
                Pass replace              //pass的处理是替换,就是拿2替换buffer 的值  
                ZFail decrWrap            //ZFail的处理是溢出型减1  
            }  

Ref 2:设置参考值。除了2,还可以设置0-255的任意数。

Comp equal:表示通过模板测试的条件。这里只有等于2的像素才算通过测试。除了equal,还有Greater、Less、Always、Never等,类似ZTest。

Pass keep:表示通过模板测试和Z测试(注意是都通过)的像素,怎么处置它的模板值,这里我们保留它的模板值。除了keep,还有Replace,IncrWrap(循环自增1,超过255为0),IncrSat(自增1,超过255还是255),DecrWrap,DecrSat等。

Fail decrWrap:表示没通过模板测试的像素, 怎么处置它的模板值。这里为循环自减。

ZFail keep:表示通过了模板测试但没通过Z测试的像素,怎么处置它的模板值。这里为保持不变。

除此之外,还有ReadMask和WriteMask语法,用来提取Ref值或模板缓存的某几位,默认是255,全部提取。

Phong和Blinn-Phone光照模型的区别

Lambert光照模型虽然能模拟出粗糙物体表面的光照效果,但是在真实环境中很多光滑的物体它却不能很好的表现出来。

所以在1975年裴祥风提出了一种局部光照的经验模型——Phong光照模型

公式:Color = Ambient + Diffuse + Specular

其中, Specular 为镜面反射,C(specular) = C(light)*M(specular)saturate(v*r)^M(shininess)

v是视角方向,r是光线的反射方向, M(shininess) 为物体材质的光泽度。

后来在1977年 Jim Blinn对Phong光照模型算法进行了改进,提出了Blinn-Phong光照模型,和Phong光照模型相比 Blinn-Phong 只改进了镜面反射的算法。

镜面反射公式:C(specluar)= C(light)*M(specular)saturate(n*h)^M(shininess)

其中h=normalize(v+l),v是视角方向,l是光照方向,n是法线方向。

虽然这一个小小的改进并没有让表现效果在视觉上有很大的提升,但是在性能方面却有很大的提升,因为h是取决于视角方向以及灯光方向的,两者很远的时候h可以认为是常量,和位置及表面曲率没有关系,所以可以减少计算量。

而Phong要根据表面曲率去逐顶点或逐像素计算反射向量r,所以计算量比较大。