Shading中的插值技术

提要

在Per Vertex shader中处理着色计算的情况计算出的是每个顶点上shading的结果,通常模型都是由三角面来构成,面上的颜色如何处理,就是今天要探讨的。常用的三种方法是Flat Shading, Gouraud Shading, Phong Shading,对于渲染一个小球,结果对比如下,从左到右依次是Flat Shading, Gouraud Shading, Phong Shading。




Flat Shading

这个最简单,整个面片的颜色都是一致的,没有平滑,只有很硬的边缘,面的颜色由面片的第一顶点或者最后一个顶点的颜色决定。OpenGL中相关的语句是

glShadeModel(GL_FLAT);
glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
glProvokingVertex(GL_LAST_VERTEX_CONVENTION);

在一些为了节省时间的渲染,比如CG动画的草稿等,可能会用到这种Shading技术。


Gouraud Shading 

Gouraud Shading 中,首先要计算的是每个顶点的法线,这里的法线求法是通过包含该顶点的面的法线取平局求得,求得法线之后,就可以通过局部光照模型求得该顶点的颜色。



对于一个四边形面片,顶点颜色信息已经求出,当一条扫描线要对这个面片进行着色的时候,首先可以求出的是扫描线和四面体边的交点a,b的颜色。


那么s点的根据重心坐标插值,可以得出


由于是线性插值,所以可以通过上一个像素点的值求得,简化了计算


则整个计算的伪代码如下

  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 

在Phong Shading中,首先要计算的也是多边形顶点的法线,但是在扫描线对颜色进行填充的时候,不是对颜色插值,而是对法线进行了插值。



已知多边形顶点的法线N1,N2,N4,扫描线与多边形交于a,b点,则a,b的法线为



由于是线性插值,同样可以用增量计算来进行优化


到这一步,只计算出了法线,已经比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); 

             } 


Gouraud shading VS Phong shading 

相对于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

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值