博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Introduction to my galaxy engine 2: Depth of field
阅读量:5057 次
发布时间:2019-06-12

本文共 6682 字,大约阅读时间需要 22 分钟。

参考shaderx2 中DOF via Simulation of Circle of Confusion 算法 or http://amdstaging.wpengine.com/wordpress/media/2012/10/Scheuermann_DepthOfField.pdf,引擎中增加了depth of field 功能模块。基本原理就是根据物体与聚焦平面的距离来设定模糊kernel的大小,对远离聚焦平面的物体做模糊处理。

视频地址:

1.首先将场景中物体的颜色渲染到一个render target上,颜色计算公式可以自己定,以下是我用的方法:

output.Color = saturate( dot(input.Norm, normalize(SunLightDir)) * vLightColor + diffuse + vAmbiantColor );

2.再将场景深度,模糊值blur分别存到另一个render target的R值和G值

深度模糊值计算方法如下:

float blur = saturate(abs(input.Depth - focalDist) / focalRange);

input.Depth为物体深度,focalDist为聚焦平面的值,focalRange为聚焦范围,blue这样计算的话就在0-1范围内。

output.Depth = float4(depth, blur, 0, 1);

 

下面的话就是按照以上两个信息做模糊处理

首先建立一个屏幕大小的平面,有四个顶点,作为画布传入vertex shader

从第一个贴图中获取物体颜色

float4 colorSum = g_SceneTexture.Sample( g_samClamp, input.Tex );

然后从另一张贴图去除深度值和模糊值

float2 centerDepthBlur = g_DepthTexture.Sample( g_samClamp,  input.Tex );

依据模糊值确定kernel大小

float sizeCoC = centerDepthBlur.y * g_MaxCoC;

下面是关键:

for (int i = 0; i < 12; i++)//kernel中原先有的12个采样点

{
// Compute tap coordinates
float2 tapCoord = input.Tex + g_FilterTaps[i] * sizeCoC;计算采样点的纹理坐标
// Fetch tap sample
float4 tapColor = g_SceneTexture.Sample(g_samClamp, tapCoord); 采样点所在位置的颜色值
float2 tapDepthBlur = g_DepthTexture.Sample(g_samClamp, tapCoord);采样点所在位置的深度和模糊因素

// Compute tap contribution

float tapContribution = (tapDepthBlur.x > centerDepthBlur.x) ? 1.0f : tapDepthBlur.y;防止聚焦平面后面的物体采样到聚焦平面的物体的颜色值

// Accumulate color and contribution

colorSum += tapColor * tapContribution;
totalContribution += tapContribution;
}

// Normalize to get proper luminance

finalColor = colorSum / totalContribution;

以下是截图,分别是没有DOF效果图,深度图,模糊因素图和有DOF的效果图

以下是所有shader代码

1 SamplerState g_samWrap  2 {  3     Filter = MIN_MAG_MIP_LINEAR;  4     AddressU = Wrap;  5     AddressV = Wrap;  6 };  7   8 SamplerState g_samClamp  9 { 10     Filter = MIN_MAG_MIP_LINEAR; 11     AddressU = Clamp; 12     AddressV = Clamp; 13 }; 14  15 BlendState NoBlending 16 { 17     AlphaToCoverageEnable = FALSE; 18     BlendEnable[0] = FALSE; 19 }; 20  21 BlendState AlphaBlendingOn 22 { 23     BlendEnable[0] = TRUE; 24     SrcBlend = SRC_ALPHA; 25     DestBlend = INV_SRC_ALPHA; 26 }; 27  28 matrix World; 29 matrix View; 30 matrix Projection; 31 matrix LightView; 32 float3  SunLightDir; 33  34 float4 vLightColor = float4(0.3f, 0.3f, 0.3f, 1.0f); 35 float4 vAmbiantColor = float4(0.1f, 0.1f, 0.1f, 1.0f); 36  37 float focalDist = 1.0; 38 float focalRange = 1.0; 39  40 Texture2D g_SceneTexture; 41 Texture2D g_DepthTexture; 42 Texture2D g_ModelTexture; 43  44 float2 g_FilterTaps[12]; 45  46 float g_MaxCoC = 3; 47  48 struct VS_MODEL_INPUT 49 { 50     float4 Pos            : POSITION;          51     float2 Tex            : TEXCOORD0;      52     float3 Norm        : NORMAL;        53 }; 54  55 struct PS_MODEL_INPUT 56 { 57     float4 Pos            :SV_POSITION;    58     float2 Tex            : TEXCOORD0;      59     float3 Norm        : TEXCOORD1;     60     float   Depth        : TEXCOORD2;    61 }; 62  63 struct PS_MODEL_OUTPUT 64 { 65     float4 Color    : SV_Target1; 66     float4 Depth    : SV_Target0; 67 }; 68  69 struct VS_DOF_INPUT 70 { 71     float4 Pos            : POSITION;          72     float2 Tex            : TEXCOORD0;        73 }; 74  75 struct PS_DOF_INPUT 76 { 77     float4 Pos            :SV_POSITION;    78     float2 Tex            : TEXCOORD0;      79 }; 80  81 PS_MODEL_INPUT VS_SCENE(VS_MODEL_INPUT input) 82 { 83     PS_MODEL_INPUT output = (PS_MODEL_INPUT)0; 84     output.Pos = input.Pos; 85     output.Pos.w = 1; 86  87     output.Pos = mul( output.Pos, World ); 88     output.Pos = mul( output.Pos, View ); 89     output.Pos = mul( output.Pos, Projection ); 90     output.Depth = output.Pos.z; 91     output.Pos = output.Pos / output.Pos.w; 92  93     output.Norm = mul( input.Norm, World ); 94     output.Norm = normalize( output.Norm ); 95  96     output.Tex = input.Tex; 97  98     return output; 99 }100 101 PS_MODEL_OUTPUT PS_SCENE( PS_MODEL_INPUT input ) : SV_Target102 {103     PS_MODEL_OUTPUT output = (PS_MODEL_OUTPUT)0;104 105     float4 diffuse = g_ModelTexture.Sample( g_samClamp, input.Tex );106     output.Color = saturate( dot(input.Norm, normalize(SunLightDir)) * vLightColor + diffuse + vAmbiantColor );107 108     float blur = saturate(abs(input.Depth - focalDist) / focalRange);109     float depth = input.Pos.z;110     output.Depth = float4(depth, blur, 0, 1);111 112     return output;113 }114 115 PS_DOF_INPUT VS_DOF(VS_DOF_INPUT input)116 {117     PS_DOF_INPUT output = (PS_DOF_INPUT)0;118     output.Pos = input.Pos;119 120     output.Tex = float2( input.Tex.x,  1 - input.Tex.y );121 122     return output;123 }124 125 float4 PS_DOF(PS_DOF_INPUT input) : SV_Target126 {127     float4 finalColor = 0;128 129      float4 colorSum = g_SceneTexture.Sample( g_samClamp, input.Tex );130 131     float2 centerDepthBlur = g_DepthTexture.Sample( g_samClamp,  input.Tex );132 133     //return centerDepthBlur.y;134 135     float sizeCoC = centerDepthBlur.y * g_MaxCoC;//blur * maxCoC136 137     //return sizeCoC;138     float totalContribution = 1.0f;139 140     for (int i = 0; i < 12; i++)141     {142         // Compute tap coordinates143         float2 tapCoord = input.Tex + g_FilterTaps[i] * sizeCoC;144         145         // Fetch tap sample146         float4 tapColor = g_SceneTexture.Sample(g_samClamp, tapCoord); 147         float2 tapDepthBlur = g_DepthTexture.Sample(g_samClamp, tapCoord);148 149         // Compute tap contribution150         //for obj in front, use tapDepthBlur.y, and if obj is in focus, tapDepthBlur.y is 0, so no leak of front obj color; for back obj, use 1.0f151         float tapContribution = (tapDepthBlur.x > centerDepthBlur.x) ? 1.0f : tapDepthBlur.y;152 153         // Accumulate color and contribution154         colorSum += tapColor * tapContribution;155         totalContribution += tapContribution;156     }157 158     // Normalize to get proper luminance159     finalColor = colorSum / totalContribution;160 161     return finalColor;162 }163 164 technique10 DoF165 {166     pass p0167     {168         SetVertexShader( CompileShader( vs_4_0, VS_SCENE() ) );169         SetGeometryShader( NULL );170         SetPixelShader( CompileShader( ps_4_0, PS_SCENE() ) );171 172         SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );173     }  174 175    pass p1176     {177         SetVertexShader( CompileShader( vs_4_0, VS_DOF() ) );178         SetGeometryShader( NULL );179         SetPixelShader( CompileShader( ps_4_0, PS_DOF() ) );180 181         SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );182     }  183 }

转载于:https://www.cnblogs.com/RobinG/archive/2012/05/23/2514465.html

你可能感兴趣的文章
win10家庭版启用远程桌面
查看>>
用于所有Windows驱动程序开发者的概念
查看>>
zabbix基本功能操作
查看>>
Bootstrap+JSP实例学习笔记一.简单的带登录功能的首页
查看>>
浅谈C#与数据结构中的哈希表(Hashtable)(上)(没法转载,只能贴在这里啦)
查看>>
Git 的使用
查看>>
原码 反码 补码 移码
查看>>
JS 二维数组 对象数组 对象中的数组
查看>>
转:前端工程与性能优化(下):静态资源管理与模板框架
查看>>
转:Hprose for php(二)——服务器
查看>>
extern static和函数
查看>>
HBase环境搭建
查看>>
拍照、本地图片工具类(兼容至Android7.0)
查看>>
NGUI-使用UILabel呈现图片和不同格式的文字
查看>>
AutoTransformHandler
查看>>
angular5引入sass
查看>>
Gridview 动态指定字段升序,降序排序
查看>>
解决idea maven 编译版本自动回复1.5
查看>>
【转载】基于CodeIgniter框架Restful风格API的Auth验证
查看>>
Java学习--使用 Date 和 SimpleDateFormat 类表示时间
查看>>