【TA-霜狼_may-《百人计划》】图形4.5 Dof景深基础

  • @[TOC](【TA-霜狼_may-《百人计划》】图形4.5 Dof景深基础
  • 4.5.1 景深
    • 离散圈
  • 4.5.2 景深的作用
  • 4.5.3 移动端景深效果实现
    • 景深的实现时间点
    • 景深的制作思路
    • 景深mask制作
  • 4.5.4 高级景深效果思路拓展
  • 作业
    • DOF效果:
    • 代码部分

4.5.1 景深


照片中有清晰的部分,有模糊的部分。
景深:Depth of field, DOF,景深是指相机对焦点前后相对清晰的成像范围。景深是针对相机成像出现的概念。

离散圈

4.5.2 景深的作用

景深是拍摄图像中的一个重要特征,可以选择性的强调画面中的一个部分,景深也是用来强调所拍摄画面的深度,增加层次感,还能够营造各种氛围,表达镜头语言。

4.5.3 移动端景深效果实现


景深的实现时间点


所以景深效果在后处理阶段进行

景深的制作思路

模拟景深制作mask =》 模糊景深 =》 正常景深 =》 合并。

景深mask制作

  1. 在camera上打开深度图
  2. shader中获得景深值
    归一化之后乘以摄像机远平面距离得到的景深图:
  3. 计算近郊距离和远焦距离 (焦距±景深值)
  4. 将当前深度值与景深值作比较,使得景深范围外的深度值朝着远离景深范围的方向增大。
  5. 效果优化,添加一个平滑度效果
  6. 生成模糊图(利用高斯模糊)思路就是取单个像素周围横竖包括自己的10个像素点进行取值再加权平均。

    效果:

    初次模糊得到的模糊结果不太理想,需要利用降采样再上采样的方法完善效果(在csharp中)

4.5.4 高级景深效果思路拓展

  • 简单的模糊会导致色彩溢出,颜色泄露:

    利用扩散滤波,在景深部分使用更小的滤波核得到防止颜色溢出。

  • 模糊不连续缺陷

    做前景和背景的单独区分,分别模糊,最后进行融合。

  • 散景的模拟(在高光区域最为显著)

作业

DOF效果:


图片大小限制,还可以调整景深范围在这里没有展示出来。

代码部分

关键部分已经给出注释,较好理解。
shader代码:

Shader "Custom/Dof" {Properties {_MainTex ("Texture", 2D) = "white" { }_BlurOffset ("Blur Offset", vector) = (0, 0, 0, 0)_FocusRange ("Range Of Focus", float) = 10_FocusDistance ("Fcous Distance", range(0, 30)) = 10_DofSmoothRange ("Smooth Range", range(0, 1)) = 0.5_Step ("Step", range(0, 1)) = 0.5}SubShader {// Pass 0 对画面进行模糊处理Pass {CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"sampler2D _MainTex;float4 _BlurOffset;struct v2f {float4 vertex : SV_POSITION;float2 uv : TEXCOORD0;};v2f vert(appdata_img v) {v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.texcoord;return o;}half4 frag(v2f i) : SV_Target {// 高斯模糊half2 uv1 = i.uv + _BlurOffset.xy * half2(1, 0) * - 2;half2 uv2 = i.uv + _BlurOffset.xy * half2(1, 0) * - 1;half2 uv3 = i.uv;half2 uv4 = i.uv + _BlurOffset.xy * half2(1, 0) * 1;half2 uv5 = i.uv + _BlurOffset.xy * half2(1, 0) * 2;half2 uv6 = i.uv + _BlurOffset.xy * half2(0, 1) * - 2;half2 uv7 = i.uv + _BlurOffset.xy * half2(0, 1) * - 1;half2 uv8 = i.uv;half2 uv9 = i.uv + _BlurOffset.xy * half2(0, 1) * 1;half2 uv10 = i.uv + _BlurOffset.xy * half2(0, 1) * 2;half4 s = 0;s += tex2D(_MainTex, uv1) * 0.05;s += tex2D(_MainTex, uv2) * 0.25;s += tex2D(_MainTex, uv3) * 0.40;s += tex2D(_MainTex, uv4) * 0.25;s += tex2D(_MainTex, uv5) * 0.05;s += tex2D(_MainTex, uv6) * 0.05;s += tex2D(_MainTex, uv7) * 0.25;s += tex2D(_MainTex, uv8) * 0.40;s += tex2D(_MainTex, uv9) * 0.25;s += tex2D(_MainTex, uv10) * 0.05;s /= 2;return half4(s.rgb, 1);}ENDCG}// Pass 1 根据焦距进行模糊融合Pass {Cull OffZTest AlwaysZWrite OffCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"sampler2D _CameraDepthTexture;sampler2D _MainTex;float4 _MainTex_TS;sampler2D _DoFTex;float _FocusDistance;float _FocusRange;float _DofSmoothRange;float _Step;struct v2f {float4 vertex : SV_POSITION;float2 uv : TEXCOORD0;};v2f vert(appdata_img v) {v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.texcoord;return o;}fixed4 frag(v2f i) : SV_TARGET {// 原图fixed4 mainTex = tex2D(_MainTex, i.uv);// 模糊图fixed4 doFTex = tex2D(_DoFTex, i.uv);// 避免远裁面的值对景深效果的影响fixed depth = Linear01Depth(tex2D(_CameraDepthTexture, i.uv)).r * _ProjectionParams.z * _Step;// 近焦距离 和 远焦距离float focusNear = _FocusDistance - _FocusRange;float focusFar = _FocusDistance + _FocusRange;// 根据焦距重新进行赋值fixed final_depth = 0;if (depth < focusNear) {final_depth = saturate(abs(focusNear - depth) * _DofSmoothRange);} else if (depth > focusFar) {final_depth = saturate(abs(depth - focusFar) * _DofSmoothRange);}fixed4 finalColor = lerp(mainTex, doFTex, final_depth * 1.2);//return doFTex;return fixed4(finalColor.rgb, 1);}ENDCG}}
}

两个脚本,一个开启深度图,一个用于处理
深度图c#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DepthTexture : MonoBehaviour
{private Camera currentCamera = null;private void Awake(){currentCamera = GetComponent<Camera>();}private void OnEnable(){currentCamera.depthTextureMode |= DepthTextureMode.Depth;}private void OnDisable(){currentCamera.depthTextureMode &= ~DepthTextureMode.Depth;}
}

渲染脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DoFScript : MonoBehaviour
{public Material mat;// 迭代次数[Range(1, 4)]public int _Iteration = 2;// 模糊半径[Range(0, 15)]public float _BlurRadius = 5;// 下采样次数[Range(0, 10)]public float _DownSample = 2;// 景深范围[Range(0, 10)]public float _FocusRange = 1.0f;// 焦距[Range(0, 30)]public float _FocusDistance = 10.0f;// Start is called before the first frame updatevoid Start(){// 判断材质和shader是否为空,是否被支持,来决定是否启用if (mat == null || SystemInfo.supportsImageEffects == false || mat.shader == null || mat.shader.isSupported == false){enabled = false;return;}}private void OnRenderImage(RenderTexture source, RenderTexture destination){mat.SetFloat("_FocusRange", _FocusRange);mat.SetFloat("_FocusDistance", _FocusDistance);int width = (int)(source.width / _DownSample);int height = (int)(source.height / _DownSample);mat.SetVector("_BlurOffset", new Vector4(_BlurRadius / width, _BlurRadius / height, 0, 0));RenderTexture RT1 = RenderTexture.GetTemporary(width, height);RenderTexture RT2 = RenderTexture.GetTemporary(width, height);Graphics.Blit(source, RT1, mat, 0);// 下采样for (int i = 0; i < _Iteration; i++){RenderTexture.ReleaseTemporary(RT2);width /= 2;height /= 2;RT2 = RenderTexture.GetTemporary(width, height);Graphics.Blit(RT1, RT2, mat, 0);width /= 2;height /= 2;RenderTexture.ReleaseTemporary(RT1);RT1 = RenderTexture.GetTemporary(width, height);Graphics.Blit(RT2, RT1, mat, 0);}// 上采样for (int i = 0; i < _Iteration; i++){RenderTexture.ReleaseTemporary(RT2);width *= 2;height *= 2;RT2 = RenderTexture.GetTemporary(width, height);Graphics.Blit(RT1, RT2, mat, 0);width *= 2;height *= 2;RenderTexture.ReleaseTemporary(RT1);RT1 = RenderTexture.GetTemporary(width, height);Graphics.Blit(RT2, RT1, mat, 0);}// 调用第二个pass进行混合mat.SetTexture("_DoFTex", RT1);Graphics.Blit(source, destination, mat, 1);// 释放缓存RenderTexture.ReleaseTemporary(RT1);RenderTexture.ReleaseTemporary(RT2);}
}

【TA-霜狼_may-《百人计划》】图形4.5 DoF景深基础相关推荐

  1. 百人计划 图形2.1 色彩空间

    色彩发送器 色彩认知:光源是出生点,光源发出光线,光线通过直射反射折射等路径最终进入人眼.在接收到光线后,人眼产生了一系列化学反应.由此把产生的信号传入大脑,大脑对颜色产生了认知感知. 光的要素: 光 ...

  2. 百人计划 图形1.4 PC手机图形API介绍

    前言 电脑工作原理:电脑是有各种不同的硬件组成,由驱动软件驱使硬件进行工作.所有的如软件工程师都会直接或间接使用到驱动. 定义:是一个针对GPU的图形库,用于渲染2D.3D矢量图形的跨语言.跨平台的应 ...

  3. 百人计划 图形 2.5 BUMP图改进

    基础感念 凹凸贴图技术是对物体表面贴图进行变化然后再进行光照计算的一种技术.例如给法线分量添加噪音,或者在一个保存扰动值的纹理图中进行查找,这是一种提升物体真实感的有效办法,但却不需要额外的提升物体的 ...

  4. 【技美百人计划】图形 4.5 Dof景深基础

    笔记 景深原理 ● 指相机对焦点前后相对清晰的成像范围,是一段三维空间. ● 针对相机成像产生的概念,肉眼也有类似的效果 景深遇到的问题 因为是基于深度图的实现,如果是半透明物体,则没有深度,要如何解 ...

  5. 百人计划 图形2.2 模型与材质基础

    渲染流水线大致过程 1.顶点数据输入到顶点着色器中进行相关的顶点计算,然后进行图元装配,通过点与点之间的关系将点进行连接.2.再到几何着色器(可选着色器)进行图元的增加,再到光栅化通过遍历像素点将一个 ...

  6. 【技美百人计划】美术 2.2 模型基础

    笔记 基本建模流程 贴图 SP:偏向于机械.金属,常用于游戏领域 mary:适合于人物.幻想生物,比如龙.人物皮肤.龙鳞,适用于影视领域 离线渲染: ● 阿诺德:无偏渲染器,较适合人物 ● vary: ...

  7. 【TA-霜狼_may-《百人计划》】图形3.4 延迟渲染管线介绍

    [TA-霜狼_may-<百人计划>]图形3.4 延迟渲染管线介绍 @[TOC]([TA-霜狼_may-<百人计划>]图形3.4 延迟渲染管线介绍 3.4.1 渲染路径 3.4. ...

  8. 【TA-霜狼_may-《百人计划》】图形3.7.2 command buffer简

    [TA-霜狼_may-<百人计划>]图形3.72command buffer 及urp概述 @[TOC]([TA-霜狼_may-<百人计划>]图形3.72command buf ...

  9. 【TA-霜狼_may-《百人计划》】图形2.7.2 GPU硬件架构概述

    [TA-霜狼_may-<百人计划>]图形2.7.2 GPU硬件架构概述 @[TOC]([TA-霜狼_may-<百人计划>]图形2.7.2 GPU硬件架构概述 GPU是什么 GP ...

最新文章

  1. 电子界卡组构建2019_2018–2019年构建现代Android应用程序的路线图
  2. 数论概论(Joseph H.Silverman) 定理39.2 连分数相邻收敛项之差定理
  3. 【正一专栏】俄罗斯世界杯来了——抽签概述
  4. DCMTK:DcmItem类的测试程序
  5. 交换机与路由器主要功能的区别和联系
  6. 百词斩和扇贝打卡测试与评估
  7. linux显示内存状态,Linux显示内存状态
  8. GUI库:PyQt5
  9. js 控制 head 元素 隐藏与显示
  10. fdisk硬盘分区(1)——系统盘剩余空间创建分区
  11. Introduction to Computer Networking学习笔记(十一):flow control 滑动窗口详解
  12. 如何在微信公众号优雅地添加代码
  13. uk码对照表_36码(uk码和中国码对照表)
  14. android tif格式文件,后缀tif文件怎么打开(tif图片查看器安卓版)
  15. 老男孩之《生日快乐》
  16. 基于testNG的数据驱动测试的自动化测试实践(一)
  17. 百度编辑支持word内容和截图的复制黏贴
  18. C语言中long long的用法
  19. day26-多进程多线程
  20. 关于垃圾文件ant、贝壳等弹窗广告的卸载问题

热门文章

  1. 亚马逊独一份的有趣规则
  2. java支付宝rsa2签名_JAVA RSA签名 解签(利用支付宝封装的函数)
  3. Unknown Faceted Project Problem (Java Version Mismatch)
  4. 国外stripe支付,超简单几行代码搞定
  5. Spring Data Jpa使用QueryDsl接口出现的一些问题
  6. TI 毫米波雷达学习网站链接整理
  7. Try{}里有一个return语句,那么紧跟在这个try后面的finally{}里的code会不会执行,什么时候执行,在return之前还是之后?
  8. Win 10系统下,用stc-isp烧程序的时候,出现“串口已被其它程序打开或该串口不存在”的解决方法
  9. [转发]知识图谱 (Knowledge Graph) 专知 荟萃
  10. [lua] 用lua实现扑克游戏发牌的逻辑代码