在U3D中实现镜头光晕

发表于2016-03-11
评论0 2.3k浏览
一、简介
  镜头光晕本身很简单。绘制一条通过光源和屏幕中心点的直线,然后沿这条直线布置一系列光晕斑,这些光晕斑再进行Blend,这就形成了镜头光晕。如下: 



二、淡入淡出 
  在晴朗的日子里摄像机,如果太阳刚刚偏移出视野边缘仍然会看到光晕,光晕不会在某处突然出现,它是淡入淡出的。所以我们就设计一个“光晕边界”---围绕屏幕边界的区域。如果太阳超出了“屏幕边界”就不会有光晕;如果太阳在边界范围内,就会出现光晕。如下: 


  那么如何计算太阳在“屏幕边界”上时光晕的强度呢?本文用一种简单快速的方法,如下: 


  通过包围圆来判断,算法上比较简单,也是比较快速的方法。以下都是在屏幕UV空间中计算的。 
  小圆的半径r = 0.5 * sqrt(2); 
  大圆的半径R = r + x;  x  > 0 
  Dist = Distance(SunUV,CenterUV);  其中SunUV是太阳在屏幕UV空间的位置,CenterUV是屏幕中心的位置,也就是(0.5,0.5). 
  Dist归一化:  Dist  = (Dist – r)/(R – r); 
  光晕强度 t = LinearInterpolate(1, 0,Dist ); LinearInterpolate是线性插值函数,在1到0之间进行插值。 



三、光斑的计算 
  光斑包括颜色、尺寸、在屏幕上的位置和纹理贴图。如下: 


  光斑就是沿着这条线(称为光斑分布线)分布的,我们要做的是沿着光斑分布线创建一系列光斑,在U3D里, 
  U3D提供了GL.Begin(GL.QUADS)这样的API,可以在屏幕空间渲染矩形。如下,创建了4个尺寸位置不一样的光斑: 


  那怎么计算光斑的位置(也就是A、B、C、D的位置)呢? 


四、遮挡 
   太阳可能被其它物体遮挡,比如远处的建筑物遮挡了太阳,这时候摄像机镜头是没有光晕的,那应该怎么计算这种遮挡关系呢?本文提出一种简单有效的方法: 
  另外创建一个Camera,我们需要这个Camera渲染场景中的遮挡物体(比如远处的建筑),注意我们是将遮挡物渲染成黑色, 
  Camera的Background 是白色,得到包含遮挡信息的RTT如下: 


  我们在太阳的的位置对这遮挡Texture进行采样, 
  fixed ocllusion = tex2D(_OcllusionTex,v2SunUV ).r; 
  显然if (ocllusion == 1.0f) 那么太阳没有被遮挡;if (ocllusion == 0.0f) 那么太阳被遮挡。 
  但是太阳不是一个点,太阳也是有面积的,当太阳被遮挡一部分怎么办? 
  所以我们对太阳周围的4个点也进行采样: 


  这种方法只适合类似太阳这样的,因为太阳到摄像机的距离比所有遮挡物到摄像机都远。 
  如果是场景内的光源,那么就不是渲染黑色的遮挡物了,而是渲染遮挡物的深度图了。
  加入GAD的核心用户QQ群:484290331,各类活动奖励任你拿,最新资讯任你读,众多教学任你免费学,如此好地方赶紧加入吧!另VR专属群:476511561,专业VR技术分享,专业导师指导为你答疑解惑,大型小型活动奖励等你拿,免费学习赚奖励的天地,欢迎你加入哟!

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引