在Per Vertex shader中处理着色计算的状况计算出的是每一个顶点上shading的结果,一般模型都是由三角面来构成,面上的颜色如何处理,就是今天要探讨的。经常使用的三种方法是Flat Shading, Gouraud Shading, Phong Shading,对于渲染一个小球,结果对好比下,从左到右依次是Flat Shading, Gouraud Shading, Phong Shading。html
这个最简单,整个面片的颜色都是一致的,没有平滑,只有很硬的边缘,面的颜色由面片的第一顶点或者最后一个顶点的颜色决定。OpenGL中相关的语句是性能
glShadeModel(GL_FLAT); glProvokingVertex(GL_FIRST_VERTEX_CONVENTION); glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
Gouraud Shading 中,首先要计算的是每一个顶点的法线,这里的法线求法是经过包含该顶点的面的法线取平局求得,求得法线以后,就能够经过局部光照模型求得该顶点的颜色。
优化
对于一个四边形面片,顶点颜色信息已经求出,当一条扫描线要对这个面片进行着色的时候,首先能够求出的是扫描线和四面体边的交点a,b的颜色。动画
那么s点的根据重心坐标插值,能够得出3d
因为是线性插值,因此能够经过上一个像素点的值求得,简化了计算code
则整个计算的伪代码以下htm
deltaI = (i2 - i1) / (x2 - x1); for (xx = x1; xx < x2; xx++) { int offset = row * CScene.screenW + xx; if (z < CScene.zBuf[offset]) { CScene.zBuf[offset] = z; CScene.frameBuf[offset] = i1; } z += deltaZ; i1 += deltaI; }
在Phong Shading中,首先要计算的也是多边形顶点的法线,可是在扫描线对颜色进行填充的时候,不是对颜色插值,而是对法线进行了插值。blog
已知多边形顶点的法线N1,N2,N4,扫描线与多边形交于a,b点,则a,b的法线为ip
因为是线性插值,一样能够用增量计算来进行优化it
到这一步,只计算出了法线,已经比Gouraud Shading复杂了三倍了。
计算出法线以后,还须要对每个像素进行光照计算,好比Phong光照模型,Blinn-Phong等,这个性能相比于直接插值可就不是一个数量级了。
仍是给出伪代码
for (xx = x1; xx < x2; xx++) { int offset = row * CScene.screenW + xx; if (z < CScene.zBuf[offset]) { CScene.zBuf[offset] = z; pt = face.findPtInWC(u,v); float Ival = face.ptIntensity; CScene.frameBuf[offset] = Ival;< BR> } u += deltaU; z += deltaZ; p1.add(deltaPt); n1.add(deltaN); }
相对于Flat shading, Gouraud shading已经有了长足的进步。一般,物体的表面都是光滑的,当用mesh网格来表示,全部的物体都变成了有棱有角的东西,固然网格越密,棱角感就越小,渲染的代价也就越大。Gouraud shading就解决了mesh渲染中的棱角感。相比于Phong shading,因为不用计算每一个ppixel的值。它的代价也很是的小,但问题也是存在的,就是specular表现并不尽如人意,特别是当specular很是小的时候,假如真实状况中,specular是处于一个多边形的中间,因为这个specular很小,因此多边形的顶点是没有specular的,那么按照Gouraud shading的插值方法,specular就不存在了。同时,若是真实状况中specular出如今多边形的顶点上,那么按照Gouraud shading的插值方法,包含顶点的多边形上会有线性分布的specular。
解决这两个问题的方法是适当增长顶点的密度。另外一个解决方案就是Phong shading了。Phong shading 最大的缺点应该就是性能上的代价了(固然是相对Gouraud shading),由于每一个像素都要计算光照,对应于OpenGL 的 Fragment shader.
Gouraud shading wiki - http://en.wikipedia.org/wiki/Gouraud_shading
Phong shading wiki - http://en.wikipedia.org/wiki/Phong_shading
Phong Shading and Gouraud Shading - http://www.nbb.cornell.edu/neurobio/land/OldStudentProjects/cs490-95to96/guo/report.html