Render Monkey的sample里的DOF的稍微有点复杂,不过效果很漂亮。我觉得只要知道了原理并实现了基本的效果就可以了
o(∩_∩)o...
一共分为4个pass
前两个pass效果一样 在两个不同的位置渲染两个teapot到BackBuffer这张纹理,并保存下相对聚焦区域的深度值
- //渲染物体的VS代码
- struct VS_OUTPUT
- {
- float4 Pos : POSITION;
- float2 Tex : TEXCOORD0;
- float3 View : TEXCOORD1;
- float depth : TEXCOORD2;
- };
- VS_OUTPUT vs_main (
- float4 inPos : POSITION,
- float2 inTex : TEXCOORD0 )
- {
- VS_OUTPUT Out = (VS_OUTPUT) 0;
- float4 offsetPos = inPos;
- offsetPos.xyz += 10.0 * teapotPos; //沿Z轴偏移一段距离
- // Output transformed position:
- Out.Pos = mul( view_proj_matrix, offsetPos );
- // Compute position in view space:
- float3 Pview = mul( view_matrix, offsetPos );
- // Compute the view direction in view space:
- Out.View = - normalize( Pview );
- // Propagate texture coordinate for the object:
- Out.Tex = inTex;
- Out.depth = Pview.z; //算出深度值
- return Out;
- }
- //渲染物体的PS代码
- float d_near;
- float d_focus; //聚焦区域
- float d_far;
- sampler2D Texture0;
- float ComputeDepthBlur (float depth)
- {
- float f;
- f = (depth - d_focus)/d_focus;//算出当前像素点相对于d_focus的深度值
- f = clamp (f, -1.0, 1.0); //控制在-1到1之间
- return f * 0.5f + 0.5f; //控制在0到1之间
- }
- float4 ps_main( float2 Tex : TEXCOORD0,
- float depth : TEXCOORD2) : COLOR
- {
- float4 FinalColor = tex2D(Texture0, Tex);
- FinalColor.a = ComputeDepthBlur (depth); //在纹理中保存深度值
- return FinalColor;
- }
第三个pass 模糊一下BackBuffer,并渲染到Blur这张纹理
第四个pass 混合BackBuffer和Blur这两张纹理,根据BackBuffer保存下的深度值,来确定当前像素点的模糊程度
- //关键的PS代码
- sampler2D TBlur; //模糊的纹理
- sampler2D TBack; //正常的纹理 , 保存有深度值
- float4 ps_main(float2 texCoord: TEXCOORD0) : COLOR {
- float4 sharp = tex2D(TBack, texCoord);
- float4 blur = tex2D(TBlur, texCoord);
- // 根据深度值来决定混合的程度,即模糊的程度
- return lerp(sharp, blur, sharp.w );
- }
以下是效果图和四个PASS分别的效果