zoukankan      html  css  js  c++  java
  • Depth Of Field

    

        有这样一个物理现象,镜头对准被摄物体对焦,在底片上有清晰的成像,然而,在焦点前后一段短距离内的物体,在底片上仍然能得到较清晰的成像,离焦点更远的地方,光线开始扩散,影象变成模糊的,形成一个扩大的圆。这个圆叫做弥散圆。在焦点前后短距离内仍能得到较清晰的成像,是因为在这段距离内,弥散圆的直径比较小,在底片上人眼识别不出来。人眼不能识别的最大弥散圆直径称为允许弥散圆直径。在焦点前后,允许弥散圆直径之间的距离叫做焦深,前焦深和后焦深对应的物距之差就是景深,即Depth of Field(DOF)。如下图:

    1 景深(Depth of field),弥散圆(Circle of confusion)

        景深与镜头焦距、光圈及物距有密切的关系。如果摄影师为了突出主题,都会选择大光圈,中焦距摄影,这时,只有对焦主体有清晰成像。

        知道景深的由来之后,我们就可以在实时渲染领域模拟景深效果。景深是一个PostProcess,一般是一下几步骤:

    1.按普通方法渲染场景,但不是渲染到backbuffer,而是渲染到texture,供景深PostProcess使用。

    2.把场景的深度渲染到texture,供景深PostProcess使用。当然了,如果API直接提供sample depth buffer的能力,这个步骤就可以省去。

    3.根据场景每个像素的深度,调整像素的模糊程度,模拟景深效果。

        以下是实现及细节。

           步骤1及步骤2使用MRT方法同时进行,场景的texture使用X8R8G8B8格式,depth texture我建议使用浮点格式,例如R32F,这样做可以保证足够的精度,缺点是需要硬件支持;也可以使用RGB格式,不过要进行数据压缩,增加运算量。以下是示例程序的场景texturedepth texture(R32F):

    图2 场景texture,茶煲使用Instancing在一次DrawIndexedPrimitive内完成所有渲染

      

    图3 Depth texture 格式R32F

        需要注意的是,这里的Depth Texture记录的是normalized device coordinate(NDC)下的depth。我在步骤3通过NDCDepth恢复view position,计算离view point的距离,决定像素的模糊程度。另一个需要注意的地方是,渲染场景texture时,可以使用硬件特性生成mipmap chain,用mipmap chain模拟弥散圆。步骤3根据view point距离,使用tex2Dlod拾取这个mipmap chain,实现像素模糊。这个方法是最简便的方法,效率最高,但也是效果最差的方法,本文后面将有效果对比。

        步骤3,从depth texture恢复view position(具体方法见我的随笔《Deferred Shading》),计算view point的距离,再根据外部参数(对焦距离、模糊系数、景深深度)决定像素的模糊程度。如果在渲染场景texture时已生成mipmap chain,这里就可以使用tex2Dlod得到模糊的像素。如果没有生成mipmap chain,就要对场景texture进行模糊处理得到模糊texture。使用经过模糊处理的texture与原有的场景texture,根据之前计算出来的模糊程度进行线性插值,得到像素最终的颜色。注意,模糊处理所使用的filter直接影响景深效果,下面是mipmap chain和8次3x3 box filter的效果对比:

    图4 Mipmap chain 模糊,锯齿较严重

    图5 3x3 box filter 模糊,效果很自然(示例程序没有对采样texture边缘做特殊处理)

     

        这个是程序最终截图:

      

    图6 最终截图

    其中Focal distance是对焦距离,对焦距离不是焦距,对焦距离是指对焦物体到焦平面的距离。调整对焦距离,可以使近景或远景得到清晰成像。调整对焦距离其实就是相机里“对焦”这一过程,对焦并没有改变镜头的焦距。相机通过细微调整镜头与底片之间的距离,使被摄物体在底片上有清晰成像,以完成对焦动作。Blur factor是模糊系数,决定场景的最大模糊程度,这个由mipmap chain最顶层(如果使用mipmap chain实现模糊)或模糊处理过的场景texture决定。Depth of field调整景深大小。通过调整Blur factor及Depth of field可模拟镜头光圈效果,当然了,如果配合HDR就更逼真了。

        不足之处:1.这种景深实现手段始终无法逼真模拟弥散圆效果(见下图)

     

    弥散圆并不是简单的模糊,而且弥散圆的形状与光圈形状有关。2. 实际上,前后景深并不是对称的,通常前景深较浅,也就是说前景模糊程度比背景要厉害些。

        最后,示例程序使用DXUT、DirectX9接口,硬件要求SM3.0、MRT(RT>= 2)、D3DFMT_R32F,纹理取自DirectX SDK。示例程序源代码在这里
  • 相关阅读:
    How to Create a site at the specified URL and new database (CommandLine Operation)
    Using Wppackager to Package and Deploy Web Parts for Microsoft SharePoint Products and Technologies
    SQL Server Monitor v0.5 [Free tool]
    How to build Web Part
    Deploy web part in a virtual server by developing a Web Part Package file(.cab)
    How to recreate "sites" link if you delete it accidentally
    SharePoint Portal Server管理匿名访问设置
    Monitor sql connection from .Net SqlClient Data Provider
    Brief installation instruction of Sharepoint Portal Server
    How to Use SharePoint Alternate URL Access
  • 原文地址:https://www.cnblogs.com/rickerliang/p/2068706.html
Copyright © 2011-2022 走看看